diff --git a/src/app/home/home.css b/src/app/home/home.css new file mode 100644 index 0000000..5664f0b --- /dev/null +++ b/src/app/home/home.css @@ -0,0 +1,36 @@ +:host { + display: block; +} + +.page-header h1 { + margin: 0; + font-size: 2rem; +} + +.page-header p { + margin: 0.5rem 0 1.5rem; + color: #4b5563; +} + +.cards { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); + gap: 1rem; +} + +.card { + border-radius: 0.75rem; + padding: 1rem; + background-color: #ffffff; + border: 1px solid #e5e7eb; +} + +.card h2 { + margin: 0 0 0.5rem; + font-size: 1rem; +} + +.card p { + margin: 0; + color: #4b5563; +} diff --git a/src/app/home/home.html b/src/app/home/home.html new file mode 100644 index 0000000..335ba2c --- /dev/null +++ b/src/app/home/home.html @@ -0,0 +1,21 @@ + + +
+
+

Statistiques

+

Resume rapide des activites recentes.

+
+ +
+

Notifications

+

Consultez les dernieres mises a jour de l'equipe.

+
+ +
+

Taches en cours

+

Suivi des priorites de la semaine.

+
+
diff --git a/src/app/home/home.spec.ts b/src/app/home/home.spec.ts new file mode 100644 index 0000000..61ab99d --- /dev/null +++ b/src/app/home/home.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { Home } from './home'; + +describe('Home', () => { + let component: Home; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [Home], + }).compileComponents(); + + fixture = TestBed.createComponent(Home); + component = fixture.componentInstance; + await fixture.whenStable(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/home/home.ts b/src/app/home/home.ts new file mode 100644 index 0000000..7c2e48d --- /dev/null +++ b/src/app/home/home.ts @@ -0,0 +1,9 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-home', + imports: [], + templateUrl: './home.html', + styleUrl: './home.css', +}) +export class Home {} diff --git a/src/app/menu/menu.css b/src/app/menu/menu.css new file mode 100644 index 0000000..174aa60 --- /dev/null +++ b/src/app/menu/menu.css @@ -0,0 +1,52 @@ +:host { + display: block; + height: 100%; +} + +.sidebar { + background-color: #111827; + color: #f9fafb; + padding: 1.5rem 1rem; + min-height: 100vh; +} + +.sidebar-title { + margin: 0 0 1rem; + font-size: 1.1rem; +} + +.menu-list { + list-style: none; + margin: 0; + padding: 0; + display: grid; + gap: 0.5rem; +} + +.menu-item { + display: block; + width: 100%; + border-radius: 0.5rem; + padding: 0.65rem 0.75rem; + text-align: left; + color: inherit; + background: transparent; + text-decoration: none; + transition: background-color 0.2s ease; +} + +.menu-item:hover { + background-color: #1f2937; +} + +.menu-item.active { + background-color: #2563eb; + font-weight: 600; +} + +@media (max-width: 768px) { + .sidebar { + padding: 1rem; + } +} + diff --git a/src/app/menu/menu.html b/src/app/menu/menu.html new file mode 100644 index 0000000..bd2687c --- /dev/null +++ b/src/app/menu/menu.html @@ -0,0 +1,20 @@ + diff --git a/src/app/menu/menu.spec.ts b/src/app/menu/menu.spec.ts new file mode 100644 index 0000000..acdf0d0 --- /dev/null +++ b/src/app/menu/menu.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { Menu } from './menu'; + +describe('Menu', () => { + let component: Menu; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [Menu], + }).compileComponents(); + + fixture = TestBed.createComponent(Menu); + component = fixture.componentInstance; + await fixture.whenStable(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/menu/menu.ts b/src/app/menu/menu.ts new file mode 100644 index 0000000..711b012 --- /dev/null +++ b/src/app/menu/menu.ts @@ -0,0 +1,15 @@ +import { Component } from '@angular/core'; +import { RouterLink, RouterLinkActive } from '@angular/router'; + +@Component({ + selector: 'app-menu', + imports: [RouterLink, RouterLinkActive], + templateUrl: './menu.html', + styleUrl: './menu.css', +}) +export class Menu { + protected readonly menuItems = [ + { label: 'Accueil', path: '/home' }, + { label: 'Projet', path: '/project' }, + ]; +} diff --git a/src/app/projects/projects.css b/src/app/projects/projects.css new file mode 100644 index 0000000..fe12c99 --- /dev/null +++ b/src/app/projects/projects.css @@ -0,0 +1,71 @@ +:host { + display: block; +} + +.page-header { + display: flex; + justify-content: space-between; + align-items: flex-start; + gap: 1rem; +} + +.page-header h1 { + margin: 0; + font-size: 2rem; +} + +.page-header p { + margin: 0.5rem 0 1.5rem; + color: #4b5563; +} + +.create-button { + border: none; + border-radius: 0.5rem; + background-color: #2563eb; + color: #ffffff; + padding: 0.65rem 1rem; + font-weight: 600; + cursor: pointer; +} + +.create-button:hover { + background-color: #1d4ed8; +} + +.table-wrapper { + background-color: #ffffff; + border: 1px solid #e5e7eb; + border-radius: 0.75rem; + overflow-x: auto; +} + +table { + width: 100%; + border-collapse: collapse; +} + +th, +td { + padding: 0.85rem 1rem; + text-align: left; + border-bottom: 1px solid #e5e7eb; +} + +th { + font-size: 0.85rem; + text-transform: uppercase; + letter-spacing: 0.03em; + color: #6b7280; + background-color: #f9fafb; +} + +tbody tr:last-child td { + border-bottom: none; +} + +@media (max-width: 768px) { + .page-header { + flex-direction: column; + } +} diff --git a/src/app/projects/projects.html b/src/app/projects/projects.html new file mode 100644 index 0000000..06aa8a0 --- /dev/null +++ b/src/app/projects/projects.html @@ -0,0 +1,32 @@ + + +
+ + + + + + + + + + + @for (project of projects(); track project.id) { + + + + + + + } + +
NomResponsableStatutProgression
{{ project.name }}{{ project.owner }}{{ project.status }}{{ project.progress }}%
+
diff --git a/src/app/projects/projects.spec.ts b/src/app/projects/projects.spec.ts new file mode 100644 index 0000000..c14c6a0 --- /dev/null +++ b/src/app/projects/projects.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { Projects } from './projects'; + +describe('Projects', () => { + let component: Projects; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [Projects], + }).compileComponents(); + + fixture = TestBed.createComponent(Projects); + component = fixture.componentInstance; + await fixture.whenStable(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/projects/projects.ts b/src/app/projects/projects.ts new file mode 100644 index 0000000..657725c --- /dev/null +++ b/src/app/projects/projects.ts @@ -0,0 +1,38 @@ +import { Component, signal } from '@angular/core'; + +type Project = { + id: number; + name: string; + owner: string; + status: 'Actif' | 'En attente' | 'Nouveau'; + progress: number; +}; + +@Component({ + selector: 'app-projects', + imports: [], + templateUrl: './projects.html', + styleUrl: './projects.css', +}) +export class Projects { + protected readonly projects = signal([ + { id: 1, name: 'Refonte Interface', owner: 'Marie', status: 'Actif', progress: 70 }, + { id: 2, name: 'API Inventaire', owner: 'Nabil', status: 'En attente', progress: 45 }, + { id: 3, name: 'Pipeline CI', owner: 'Sonia', status: 'Actif', progress: 90 }, + ]); + + private nextId = 4; + + protected createProject(): void { + const newProject: Project = { + id: this.nextId, + name: `Nouveau projet ${this.nextId}`, + owner: 'A definir', + status: 'Nouveau', + progress: 0, + }; + + this.projects.update((currentProjects) => [...currentProjects, newProject]); + this.nextId += 1; + } +}