mirror of
https://github.com/adam-benyekkou/my_portfolio.git
synced 2026-01-15 20:20:09 +00:00
DataService WIP, its working with project data for now, inc Skills, Education, Experience, Traits, Phrases
This commit is contained in:
0
assets/data/education.json
Normal file
0
assets/data/education.json
Normal file
0
assets/data/experiences.json
Normal file
0
assets/data/experiences.json
Normal file
69
assets/data/projects.json
Normal file
69
assets/data/projects.json
Normal file
@@ -0,0 +1,69 @@
|
||||
[
|
||||
{
|
||||
"id": "portfolio",
|
||||
"title": "PORTFOLIO_SYSTEM.EXE",
|
||||
"status": "[MISSION_ACTIVE]",
|
||||
"classification": "Personal Showcase Platform",
|
||||
"objective": "Professional presentation interface with NieR aesthetic",
|
||||
"statusDescription": "LIVE | CONTINUOUS_UPDATE",
|
||||
"techStack": ["ANGULAR", "TYPESCRIPT", "TAILWIND", "VERCEL"],
|
||||
"demoUrl": "https://adambenyekkoudev.vercel.app/",
|
||||
"codeUrl": "https://github.com/adam-benyekkou/angular_portfolio",
|
||||
"isRedacted": false,
|
||||
"caseStudy": {
|
||||
"title": "PORTFOLIO_SYSTEM.EXE",
|
||||
"sections": [
|
||||
{
|
||||
"title": "PROJECT_OVERVIEW",
|
||||
"content": "A NieR: Automata inspired personal portfolio showcasing development projects and skills. The design captures the game's distinctive UI aesthetic while maintaining modern web standards and accessibility. Built to stand out from typical developer portfolios while remaining professional and functional."
|
||||
},
|
||||
{
|
||||
"title": "DESIGN_PHILOSOPHY",
|
||||
"content": "Recreated the authentic NieR: Automata interface with parchment backgrounds, geometric layouts, and terminal-style typography. The design system uses CSS custom properties for theme consistency and implements dark/light mode switching that maintains the aesthetic in both contexts. Every element is carefully crafted to feel like it belongs in the game's world while serving a practical purpose."
|
||||
},
|
||||
{
|
||||
"title": "TECHNICAL_IMPLEMENTATION",
|
||||
"content": "Built with Angular 19 and Tailwind CSS using a custom design system. The architecture follows Angular best practices with standalone components, lazy loading, and optimized build processes. Implemented responsive grid layouts, smooth animations, and interactive elements that respond to user interactions while maintaining the game's UI feel. Special attention was paid to performance optimization and accessibility standards."
|
||||
},
|
||||
{
|
||||
"title": "CHALLENGES_SOLVED",
|
||||
"content": "<strong>Challenge 1:</strong> Balancing aesthetic authenticity with web accessibility<br><strong>Solution:</strong> Created high-contrast color schemes that pass WCAG guidelines<br><br><strong>Challenge 2:</strong> Making retro aesthetics work on modern devices<br><strong>Solution:</strong> Responsive design system with flexible typography and layouts<br><br><strong>Challenge 3:</strong> Performance with complex visual effects<br><strong>Solution:</strong> CSS-only animations and optimized asset loading"
|
||||
},
|
||||
{
|
||||
"title": "PERFORMANCE_METRICS",
|
||||
"content": "• Lighthouse score: <strong>95+</strong><br>• First contentful paint: <strong>< 1.2s</strong><br>• Accessibility score: <strong>98%</strong><br>• Mobile optimization: <strong>Perfect responsive design</strong><br>• Bundle size: <strong>< 500KB gzipped</strong><br>• SEO optimization: <strong>100%</strong>"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "redacted-1",
|
||||
"title": "REDACTED_PROJECT_1",
|
||||
"status": "[REDACTED]",
|
||||
"classification": "",
|
||||
"objective": "",
|
||||
"statusDescription": "",
|
||||
"techStack": [],
|
||||
"isRedacted": true
|
||||
},
|
||||
{
|
||||
"id": "redacted-2",
|
||||
"title": "REDACTED_PROJECT_2",
|
||||
"status": "[REDACTED]",
|
||||
"classification": "",
|
||||
"objective": "",
|
||||
"statusDescription": "",
|
||||
"techStack": [],
|
||||
"isRedacted": true
|
||||
},
|
||||
{
|
||||
"id": "redacted-3",
|
||||
"title": "REDACTED_PROJECT_3",
|
||||
"status": "[REDACTED]",
|
||||
"classification": "",
|
||||
"objective": "",
|
||||
"statusDescription": "",
|
||||
"techStack": [],
|
||||
"isRedacted": true
|
||||
}
|
||||
]
|
||||
0
assets/data/skills.json
Normal file
0
assets/data/skills.json
Normal file
0
assets/data/traits.json
Normal file
0
assets/data/traits.json
Normal file
@@ -2,7 +2,12 @@ import { ApplicationConfig } from '@angular/core';
|
||||
import { provideRouter } from '@angular/router';
|
||||
import { routes } from './app.routes';
|
||||
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
|
||||
import { provideHttpClient } from '@angular/common/http';
|
||||
|
||||
export const appConfig: ApplicationConfig = {
|
||||
providers: [provideRouter(routes), provideAnimationsAsync()],
|
||||
providers: [
|
||||
provideRouter(routes),
|
||||
provideAnimationsAsync(),
|
||||
provideHttpClient(),
|
||||
],
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// projects.component.ts
|
||||
import { Component, signal, OnInit } from '@angular/core';
|
||||
import { Component, signal, OnInit, inject, computed } from '@angular/core';
|
||||
import { SectionTitleComponent } from '../../components/section-title/section-title.component';
|
||||
import { type Project } from '../../shared/models/project.model';
|
||||
import { ProjectTreeComponent } from './project-tree/project-tree.component';
|
||||
@@ -7,6 +7,7 @@ import { ProjectModalComponent } from './project-modal/project-modal.component';
|
||||
import { ProjectFooterComponent } from './project-footer/project-footer.component';
|
||||
import { ProjectLoaderDecoratorComponent } from './project-loader-decorator/project-loader-decorator.component';
|
||||
import { ProjectListComponent } from './projects-list/projects-list.component';
|
||||
import { DataService } from '../../shared/services/data.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-projects',
|
||||
@@ -22,13 +23,16 @@ import { ProjectListComponent } from './projects-list/projects-list.component';
|
||||
styleUrl: './projects.component.css',
|
||||
})
|
||||
export class ProjectsComponent implements OnInit {
|
||||
// Signals
|
||||
projects = signal<Project[]>([]);
|
||||
private readonly dataService = inject(DataService);
|
||||
|
||||
// Use data service signals directly
|
||||
projects = this.dataService.projects;
|
||||
|
||||
// Component-specific signals
|
||||
selectedProject = signal<Project | null>(null);
|
||||
isLoading = signal(false);
|
||||
|
||||
ngOnInit(): void {
|
||||
this.loadProjects();
|
||||
this.startLoadingAnimation();
|
||||
}
|
||||
|
||||
@@ -40,105 +44,6 @@ export class ProjectsComponent implements OnInit {
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
private loadProjects(): void {
|
||||
const projectsData: Project[] = [
|
||||
{
|
||||
id: 'portfolio',
|
||||
title: 'PORTFOLIO_SYSTEM.EXE',
|
||||
status: '[MISSION_ACTIVE]',
|
||||
classification: 'Personal Showcase Platform',
|
||||
objective: 'Professional presentation interface with NieR aesthetic',
|
||||
statusDescription: 'LIVE | CONTINUOUS_UPDATE',
|
||||
techStack: ['ANGULAR', 'TYPESCRIPT', 'TAILWIND', 'VERCEL'],
|
||||
demoUrl: 'https://adambenyekkoudev.vercel.app/',
|
||||
codeUrl: 'https://github.com/adam-benyekkou/angular_portfolio',
|
||||
isRedacted: false,
|
||||
caseStudy: {
|
||||
title: 'PORTFOLIO_SYSTEM.EXE',
|
||||
sections: [
|
||||
{
|
||||
title: 'PROJECT_OVERVIEW',
|
||||
content: `A NieR: Automata inspired personal portfolio showcasing development projects and skills.
|
||||
The design captures the game's distinctive UI aesthetic while maintaining modern web standards
|
||||
and accessibility. Built to stand out from typical developer portfolios while remaining
|
||||
professional and functional.`,
|
||||
},
|
||||
{
|
||||
title: 'DESIGN_PHILOSOPHY',
|
||||
content: `Recreated the authentic NieR: Automata interface with parchment backgrounds,
|
||||
geometric layouts, and terminal-style typography. The design system uses CSS custom properties
|
||||
for theme consistency and implements dark/light mode switching that maintains
|
||||
the aesthetic in both contexts. Every element is carefully crafted to feel like
|
||||
it belongs in the game's world while serving a practical purpose.`,
|
||||
},
|
||||
{
|
||||
title: 'TECHNICAL_IMPLEMENTATION',
|
||||
content: `Built with Angular 19 and Tailwind CSS using a custom design system.
|
||||
The architecture follows Angular best practices with standalone components,
|
||||
lazy loading, and optimized build processes. Implemented responsive grid layouts,
|
||||
smooth animations, and interactive elements that respond to user interactions
|
||||
while maintaining the game's UI feel. Special attention was paid to performance
|
||||
optimization and accessibility standards.`,
|
||||
},
|
||||
{
|
||||
title: 'CHALLENGES_SOLVED',
|
||||
content: `<strong>Challenge 1:</strong> Balancing aesthetic authenticity with web accessibility<br>
|
||||
<strong>Solution:</strong> Created high-contrast color schemes that pass WCAG guidelines<br><br>
|
||||
|
||||
<strong>Challenge 2:</strong> Making retro aesthetics work on modern devices<br>
|
||||
<strong>Solution:</strong> Responsive design system with flexible typography and layouts<br><br>
|
||||
|
||||
<strong>Challenge 3:</strong> Performance with complex visual effects<br>
|
||||
<strong>Solution:</strong> CSS-only animations and optimized asset loading`,
|
||||
},
|
||||
{
|
||||
title: 'PERFORMANCE_METRICS',
|
||||
content: `• Lighthouse score: <strong>95+</strong><br>
|
||||
• First contentful paint: <strong>< 1.2s</strong><br>
|
||||
• Accessibility score: <strong>98%</strong><br>
|
||||
• Mobile optimization: <strong>Perfect responsive design</strong><br>
|
||||
• Bundle size: <strong>< 500KB gzipped</strong><br>
|
||||
• SEO optimization: <strong>100%</strong>`,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
// Redacted projects
|
||||
{
|
||||
id: 'redacted-1',
|
||||
title: 'REDACTED_PROJECT_1',
|
||||
status: '[REDACTED]',
|
||||
classification: '',
|
||||
objective: '',
|
||||
statusDescription: '',
|
||||
techStack: [],
|
||||
isRedacted: true,
|
||||
},
|
||||
{
|
||||
id: 'redacted-2',
|
||||
title: 'REDACTED_PROJECT_2',
|
||||
status: '[REDACTED]',
|
||||
classification: '',
|
||||
objective: '',
|
||||
statusDescription: '',
|
||||
techStack: [],
|
||||
isRedacted: true,
|
||||
},
|
||||
{
|
||||
id: 'redacted-3',
|
||||
title: 'REDACTED_PROJECT_3',
|
||||
status: '[REDACTED]',
|
||||
classification: '',
|
||||
objective: '',
|
||||
statusDescription: '',
|
||||
techStack: [],
|
||||
isRedacted: true,
|
||||
},
|
||||
];
|
||||
|
||||
this.projects.set(projectsData);
|
||||
}
|
||||
|
||||
openCaseStudy(project: Project): void {
|
||||
this.selectedProject.set(project);
|
||||
}
|
||||
|
||||
73
src/app/shared/services/data.service.ts
Normal file
73
src/app/shared/services/data.service.ts
Normal file
@@ -0,0 +1,73 @@
|
||||
import { Injectable, signal, inject } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { type Project } from '../models/project.model';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class DataService {
|
||||
private readonly http = inject(HttpClient);
|
||||
|
||||
// Private signals for state management
|
||||
private _projects = signal<Project[]>([]);
|
||||
|
||||
// Public readonly signals
|
||||
readonly projects = this._projects.asReadonly();
|
||||
|
||||
constructor() {
|
||||
console.log('DataService initialized');
|
||||
this.loadInitialData();
|
||||
}
|
||||
|
||||
private async loadInitialData(): Promise<void> {
|
||||
try {
|
||||
console.log('Starting to load projects...');
|
||||
const projects = await this.fetchProjects();
|
||||
console.log('Projects loaded successfully:', projects);
|
||||
console.log('Number of projects:', projects.length);
|
||||
this._projects.set(projects);
|
||||
console.log('Projects signal updated');
|
||||
} catch (error) {
|
||||
console.error('Error loading data:', error);
|
||||
|
||||
// Fallback to hardcoded data for debugging
|
||||
console.log('Loading fallback data...');
|
||||
const fallbackProjects: Project[] = [
|
||||
{
|
||||
id: 'portfolio',
|
||||
title: 'PORTFOLIO_SYSTEM.EXE',
|
||||
status: '[MISSION_ACTIVE]',
|
||||
classification: 'Personal Showcase Platform',
|
||||
objective: 'Professional presentation interface with NieR aesthetic',
|
||||
statusDescription: 'LIVE | CONTINUOUS_UPDATE',
|
||||
techStack: ['ANGULAR', 'TYPESCRIPT', 'TAILWIND', 'VERCEL'],
|
||||
demoUrl: 'https://adambenyekkoudev.vercel.app/',
|
||||
codeUrl: 'https://github.com/adam-benyekkou/angular_portfolio',
|
||||
isRedacted: false,
|
||||
},
|
||||
{
|
||||
id: 'redacted-1',
|
||||
title: 'REDACTED_PROJECT_1',
|
||||
status: '[REDACTED]',
|
||||
classification: '',
|
||||
objective: '',
|
||||
statusDescription: '',
|
||||
techStack: [],
|
||||
isRedacted: true,
|
||||
},
|
||||
];
|
||||
this._projects.set(fallbackProjects);
|
||||
console.log('Fallback data loaded');
|
||||
}
|
||||
}
|
||||
|
||||
private async fetchProjects(): Promise<Project[]> {
|
||||
console.log('Fetching projects from assets/data/projects.json');
|
||||
const result = await firstValueFrom(
|
||||
this.http.get<Project[]>('data/projects.json'),
|
||||
);
|
||||
console.log('HTTP request completed:', result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user