autocomit

This commit is contained in:
2026-02-08 16:44:04 +01:00
parent 1aeadb9c99
commit c6a514718c
8 changed files with 635 additions and 485 deletions
+18
View File
@@ -0,0 +1,18 @@
# Feature 1
Dans l'écran applications, je veux pouvoir ajouter des contacts à l'application.
# Feature 2
J'aimerais un écran me permettant de gérer les utilisateurs de l'application.
(ou de permettre d'utiliser un LDAP pour identifier les users)
A ce moment il faudra pouvoir assigner les users aux business units pour qu'ils puissent gérer les entités relatives à cette business unit la.
admin peut tout faire.
# Feature 3
J'aimerais que les badges "quick access" soient toujours disponible dans une bannière à gauche sur chaque écran.
Aujourd'hui les écrans de gestion (business units, applications, environments, personnes ...) sont des pages uniques et ce n'est pas pratique.
Je préfèrerais un dashboard cohérent qui me permette d'accéder à tous les éléments de l'application en gardant ce menu à gauche.
est-ce clair ? (n'implémente pas encore)
+7 -7
View File
@@ -12,13 +12,16 @@ export const routes: Routes = [
loadComponent: () => import('./core/auth/login/login.component').then(m => m.LoginComponent) loadComponent: () => import('./core/auth/login/login.component').then(m => m.LoginComponent)
}, },
{ {
path: 'dashboard', path: '',
canActivate: [authGuard], canActivate: [authGuard],
loadComponent: () => import('./core/layout/main-layout/main-layout.component').then(m => m.MainLayoutComponent),
children: [
{
path: 'dashboard',
loadComponent: () => import('./features/dashboard/dashboard.component').then(m => m.DashboardComponent) loadComponent: () => import('./features/dashboard/dashboard.component').then(m => m.DashboardComponent)
}, },
{ {
path: 'business-units', path: 'business-units',
canActivate: [authGuard],
children: [ children: [
{ {
path: '', path: '',
@@ -44,7 +47,6 @@ export const routes: Routes = [
}, },
{ {
path: 'applications', path: 'applications',
canActivate: [authGuard],
children: [ children: [
{ {
path: '', path: '',
@@ -70,7 +72,6 @@ export const routes: Routes = [
}, },
{ {
path: 'environments', path: 'environments',
canActivate: [authGuard],
children: [ children: [
{ {
path: '', path: '',
@@ -96,7 +97,6 @@ export const routes: Routes = [
}, },
{ {
path: 'persons', path: 'persons',
canActivate: [authGuard],
children: [ children: [
{ {
path: '', path: '',
@@ -122,7 +122,6 @@ export const routes: Routes = [
}, },
{ {
path: 'contacts', path: 'contacts',
canActivate: [authGuard],
children: [ children: [
{ {
path: '', path: '',
@@ -143,8 +142,9 @@ export const routes: Routes = [
}, },
{ {
path: 'contact-roles', path: 'contact-roles',
canActivate: [authGuard],
loadComponent: () => import('./features/contacts/contact-role-list/contact-role-list.component') loadComponent: () => import('./features/contacts/contact-role-list/contact-role-list.component')
.then(m => m.ContactRoleListComponent) .then(m => m.ContactRoleListComponent)
} }
]
}
]; ];
@@ -0,0 +1,37 @@
<div class="main-layout">
<!-- Sidebar Navigation -->
<aside class="sidebar">
<div class="sidebar-header">
<h1>LDPv2</h1>
<p class="subtitle">Lifecycle Data Platform</p>
</div>
<nav class="sidebar-nav">
<div
*ngFor="let item of navItems"
class="nav-item"
[class.active]="isActive(item.route)"
[style.border-left-color]="item.color"
(click)="navigate(item.route)">
<span class="nav-icon">{{ item.icon }}</span>
<span class="nav-title">{{ item.title }}</span>
</div>
</nav>
<div class="sidebar-footer">
<div class="user-info" *ngIf="currentUser">
<span class="user-icon">👤</span>
<div class="user-details">
<div class="username">{{ currentUser.username }}</div>
<div class="role-badge">{{ currentUser.role }}</div>
</div>
</div>
<button (click)="logout()" class="btn-logout">Logout</button>
</div>
</aside>
<!-- Main Content Area -->
<main class="main-content">
<router-outlet></router-outlet>
</main>
</div>
@@ -0,0 +1,164 @@
.main-layout {
display: flex;
height: 100vh;
overflow: hidden;
}
.sidebar {
width: 260px;
background: linear-gradient(180deg, #667eea 0%, #764ba2 100%);
color: white;
display: flex;
flex-direction: column;
box-shadow: 2px 0 10px rgba(0, 0, 0, 0.1);
z-index: 100;
}
.sidebar-header {
padding: 2rem 1.5rem;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
h1 {
margin: 0 0 0.25rem 0;
font-size: 1.75rem;
font-weight: 700;
}
.subtitle {
margin: 0;
font-size: 0.75rem;
opacity: 0.8;
}
}
.sidebar-nav {
flex: 1;
overflow-y: auto;
padding: 1rem 0;
&::-webkit-scrollbar {
width: 6px;
}
&::-webkit-scrollbar-track {
background: rgba(255, 255, 255, 0.1);
}
&::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.3);
border-radius: 3px;
&:hover {
background: rgba(255, 255, 255, 0.4);
}
}
}
.nav-item {
display: flex;
align-items: center;
padding: 1rem 1.5rem;
cursor: pointer;
transition: all 0.2s ease;
border-left: 4px solid transparent;
margin: 0.25rem 0;
&:hover {
background: rgba(255, 255, 255, 0.1);
}
&.active {
background: rgba(255, 255, 255, 0.2);
font-weight: 500;
}
.nav-icon {
font-size: 1.5rem;
margin-right: 1rem;
width: 30px;
text-align: center;
}
.nav-title {
font-size: 0.95rem;
}
}
.sidebar-footer {
padding: 1rem 1.5rem;
border-top: 1px solid rgba(255, 255, 255, 0.1);
.user-info {
display: flex;
align-items: center;
gap: 0.75rem;
margin-bottom: 1rem;
padding: 0.75rem;
background: rgba(255, 255, 255, 0.1);
border-radius: 8px;
.user-icon {
font-size: 1.5rem;
}
.user-details {
flex: 1;
min-width: 0;
.username {
font-weight: 500;
font-size: 0.9rem;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.role-badge {
font-size: 0.7rem;
opacity: 0.8;
text-transform: uppercase;
}
}
}
.btn-logout {
width: 100%;
background: rgba(255, 255, 255, 0.2);
color: white;
border: 1px solid rgba(255, 255, 255, 0.3);
padding: 0.75rem;
border-radius: 6px;
cursor: pointer;
font-weight: 500;
transition: all 0.3s ease;
&:hover {
background: rgba(255, 255, 255, 0.3);
transform: translateY(-2px);
}
}
}
.main-content {
flex: 1;
overflow-y: auto;
background: #f5f5f5;
}
// Responsive
@media (max-width: 768px) {
.sidebar {
position: fixed;
left: -260px;
height: 100vh;
transition: left 0.3s ease;
&.open {
left: 0;
}
}
.main-content {
width: 100%;
}
}
@@ -0,0 +1,102 @@
import { Component, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { Router, RouterModule, NavigationEnd } from '@angular/router';
import { AuthService } from '../../auth/auth.service';
import { User } from '../../../shared/models/user.model';
import { filter } from 'rxjs/operators';
interface NavItem {
title: string;
icon: string;
route: string;
color: string;
}
@Component({
selector: 'app-main-layout',
standalone: true,
imports: [CommonModule, RouterModule],
templateUrl: './main-layout.component.html',
styleUrls: ['./main-layout.component.scss']
})
export class MainLayoutComponent implements OnInit {
currentUser: User | null = null;
activeRoute: string = '';
navItems: NavItem[] = [
{
title: 'Dashboard',
icon: '📊',
route: '/dashboard',
color: '#2196f3'
},
{
title: 'Business Units',
icon: '🏢',
route: '/business-units',
color: '#3f51b5'
},
{
title: 'Applications',
icon: '📱',
route: '/applications',
color: '#009688'
},
{
title: 'Environments',
icon: '🌍',
route: '/environments',
color: '#ff9800'
},
{
title: 'Persons',
icon: '👤',
route: '/persons',
color: '#e91e63'
},
{
title: 'Contacts',
icon: '👥',
route: '/contacts',
color: '#9c27b0'
},
{
title: 'Contact Roles',
icon: '🎭',
route: '/contact-roles',
color: '#607d8b'
}
];
constructor(
private router: Router,
private authService: AuthService
) {}
ngOnInit(): void {
this.currentUser = this.authService.getCurrentUser();
this.activeRoute = this.router.url;
// Listen to route changes to update active route
this.router.events.pipe(
filter(event => event instanceof NavigationEnd)
).subscribe((event: any) => {
this.activeRoute = event.url;
});
}
isActive(route: string): boolean {
if (route === '/dashboard') {
return this.activeRoute === '/dashboard';
}
return this.activeRoute.startsWith(route);
}
navigate(route: string): void {
this.router.navigate([route]);
}
logout(): void {
this.authService.logout();
}
}
@@ -1,33 +1,13 @@
<div class="dashboard"> <div class="dashboard-content">
<header class="dashboard-header"> <div class="dashboard-header">
<div class="container"> <h1>Welcome back, {{ currentUser?.username }}! 👋</h1>
<div class="header-content"> <p>Here's an overview of your application lifecycle data.</p>
<div class="branding">
<h1>LDPv2</h1>
<p class="subtitle">Lifecycle Data Platform</p>
</div> </div>
<div class="user-menu">
<span class="user-info" *ngIf="currentUser">
<span class="user-icon">👤</span>
<span class="username">{{ currentUser.username }}</span>
<span class="role-badge">{{ currentUser.role }}</span>
</span>
<button (click)="logout()" class="btn-logout">Logout</button>
</div>
</div>
</div>
</header>
<main class="dashboard-main">
<div class="container">
<section class="welcome-section">
<h2>Welcome back, {{ currentUser?.username }}! 👋</h2>
<p>Manage your applications, environments, and business units from one place.</p>
</section>
<section class="stats-section"> <section class="stats-section">
<h2>Overview</h2>
<div class="stats-grid"> <div class="stats-grid">
<div class="stat-card" *ngFor="let stat of stats"> <div class="stat-card" *ngFor="let stat of stats" [style.border-left-color]="stat.color">
<div class="stat-icon">{{ stat.icon }}</div> <div class="stat-icon">{{ stat.icon }}</div>
<div class="stat-content"> <div class="stat-content">
<div class="stat-value">{{ stat.value }}</div> <div class="stat-value">{{ stat.value }}</div>
@@ -37,59 +17,50 @@
</div> </div>
</section> </section>
<section class="features-section"> <section class="activity-section">
<h3>Quick Access</h3> <h2>Recent Activity</h2>
<div class="features-grid"> <div class="activity-list">
<div <div class="activity-item" *ngFor="let activity of recentActivity">
class="feature-card" <div class="activity-icon">
*ngFor="let feature of features" <span *ngIf="activity.action === 'Created'"></span>
(click)="navigate(feature.route)" <span *ngIf="activity.action === 'Updated'">📝</span>
[style.border-left-color]="feature.color"> <span *ngIf="activity.action === 'Deleted'">🗑️</span>
<div class="feature-icon">{{ feature.icon }}</div> </div>
<div class="feature-content"> <div class="activity-details">
<h4>{{ feature.title }}</h4> <div class="activity-main">
<p>{{ feature.description }}</p> <strong>{{ activity.action }}</strong> {{ activity.entity }}:
<span class="entity-name">{{ activity.name }}</span>
</div>
<div class="activity-time">{{ activity.time }}</div>
</div> </div>
<div class="feature-arrow"></div>
</div> </div>
</div> </div>
</section> </section>
<section class="getting-started"> <section class="quick-tips">
<h3>Getting Started</h3> <h2>Quick Tips</h2>
<div class="steps-grid"> <div class="tips-grid">
<div class="step-card"> <div class="tip-card">
<div class="step-number">1</div> <div class="tip-icon">💡</div>
<h4>Create Business Units</h4> <div class="tip-content">
<p>Organize your applications by business units</p> <h3>Get Started</h3>
<button (click)="navigate('/business-units')" class="btn-link"> <p>Use the sidebar to navigate between different sections of the application.</p>
Go to Business Units →
</button>
</div> </div>
<div class="step-card">
<div class="step-number">2</div>
<h4>Add Applications</h4>
<p>Register your applications and track their lifecycle</p>
<button (click)="navigate('/applications')" class="btn-link">
Go to Applications →
</button>
</div> </div>
<div class="step-card"> <div class="tip-card">
<div class="step-number">3</div> <div class="tip-icon">🔍</div>
<h4>Configure Environments</h4> <div class="tip-content">
<p>Set up deployment environments</p> <h3>Search & Filter</h3>
<button (click)="navigate('/environments')" class="btn-link"> <p>Most lists support search and filtering to help you find what you need quickly.</p>
Go to Environments → </div>
</button> </div>
<div class="tip-card">
<div class="tip-icon">🎯</div>
<div class="tip-content">
<h3>Track Lifecycle</h3>
<p>Monitor your applications' lifecycle from idea to decommission.</p>
</div>
</div> </div>
</div> </div>
</section> </section>
</div> </div>
</main>
<footer class="dashboard-footer">
<div class="container">
<p>LDPv2 - Lifecycle Data Platform v2 | © 2026</p>
</div>
</footer>
</div>
@@ -1,280 +1,184 @@
.dashboard { .dashboard-content {
min-height: 100vh; padding: 2rem;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); max-width: 1400px;
display: flex;
flex-direction: column;
}
.container {
max-width: 1200px;
margin: 0 auto; margin: 0 auto;
padding: 0 2rem;
width: 100%;
} }
.dashboard-header { .dashboard-header {
background: rgba(255, 255, 255, 0.1); margin-bottom: 2rem;
backdrop-filter: blur(10px);
padding: 1.5rem 0;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
.header-content { h1 {
display: flex;
justify-content: space-between;
align-items: center;
}
.branding h1 {
color: white;
font-size: 2rem; font-size: 2rem;
margin: 0; margin: 0 0 0.5rem 0;
font-weight: 700; color: #333;
}
.branding .subtitle {
color: rgba(255, 255, 255, 0.8);
margin: 0;
font-size: 0.9rem;
}
.user-menu {
display: flex;
align-items: center;
gap: 1rem;
}
.user-info {
display: flex;
align-items: center;
gap: 0.5rem;
color: white;
.user-icon { font-size: 1.5rem; }
.username { font-weight: 500; }
.role-badge {
background: rgba(255, 255, 255, 0.2);
padding: 0.25rem 0.75rem;
border-radius: 12px;
font-size: 0.75rem;
text-transform: uppercase;
}
}
.btn-logout {
background: rgba(255, 255, 255, 0.2);
color: white;
border: 1px solid rgba(255, 255, 255, 0.3);
padding: 0.5rem 1.5rem;
border-radius: 20px;
cursor: pointer;
font-weight: 500;
transition: all 0.3s ease;
&:hover {
background: rgba(255, 255, 255, 0.3);
transform: translateY(-2px);
}
}
}
.dashboard-main {
flex: 1;
padding: 3rem 0;
}
.welcome-section {
text-align: center;
color: white;
margin-bottom: 3rem;
h2 {
font-size: 2.5rem;
margin: 0 0 1rem 0;
font-weight: 700;
} }
p { p {
font-size: 1.2rem; margin: 0;
opacity: 0.9; color: #666;
font-size: 1.1rem;
}
}
section {
margin-bottom: 3rem;
h2 {
font-size: 1.5rem;
margin: 0 0 1.5rem 0;
color: #333;
} }
} }
.stats-grid { .stats-grid {
display: grid; display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 1.5rem; gap: 1.5rem;
margin-bottom: 3rem;
} }
.stat-card { .stat-card {
background: white; background: white;
padding: 2rem; padding: 1.5rem;
border-radius: 12px; border-radius: 8px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
display: flex; display: flex;
align-items: center; align-items: center;
gap: 1.5rem; gap: 1rem;
transition: transform 0.3s ease; border-left: 4px solid;
transition: transform 0.2s ease, box-shadow 0.2s ease;
&:hover { transform: translateY(-5px); } &:hover {
transform: translateY(-4px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
.stat-icon { font-size: 3rem; } .stat-icon {
.stat-value {
font-size: 2.5rem; font-size: 2.5rem;
}
.stat-content {
flex: 1;
.stat-value {
font-size: 2rem;
font-weight: 700; font-weight: 700;
color: #333; color: #333;
line-height: 1;
} }
.stat-label { .stat-label {
color: #666; color: #666;
font-size: 0.9rem; font-size: 0.9rem;
margin-top: 0.25rem;
}
} }
} }
.features-section { .activity-section {
margin-bottom: 3rem; .activity-list {
background: white;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
overflow: hidden;
}
h3 { .activity-item {
color: white; display: flex;
font-size: 1.8rem; align-items: center;
margin-bottom: 1.5rem; gap: 1rem;
font-weight: 600; padding: 1rem 1.5rem;
border-bottom: 1px solid #f5f5f5;
transition: background-color 0.2s ease;
&:last-child {
border-bottom: none;
}
&:hover {
background-color: #f9f9f9;
}
.activity-icon {
font-size: 1.5rem;
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
background: #f5f5f5;
border-radius: 50%;
}
.activity-details {
flex: 1;
.activity-main {
color: #333;
margin-bottom: 0.25rem;
.entity-name {
color: #667eea;
font-weight: 500;
} }
} }
.features-grid { .activity-time {
color: #999;
font-size: 0.85rem;
}
}
}
}
.quick-tips {
.tips-grid {
display: grid; display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 1.5rem; gap: 1.5rem;
} }
.feature-card { .tip-card {
background: white; background: white;
padding: 2rem; padding: 1.5rem;
border-radius: 12px; border-radius: 8px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
display: flex; display: flex;
align-items: center; gap: 1rem;
gap: 1.5rem;
cursor: pointer;
transition: all 0.3s ease;
border-left: 4px solid;
&:hover { .tip-icon {
transform: translateY(-5px); font-size: 2rem;
box-shadow: 0 8px 12px rgba(0, 0, 0, 0.15);
} }
.feature-icon { font-size: 3rem; } .tip-content {
.feature-content {
flex: 1; flex: 1;
h4 { h3 {
margin: 0 0 0.5rem 0; margin: 0 0 0.5rem 0;
color: #333; color: #333;
font-size: 1.3rem; font-size: 1.1rem;
} }
p { p {
margin: 0; margin: 0;
color: #666; color: #666;
font-size: 0.9rem; font-size: 0.9rem;
line-height: 1.5;
} }
} }
.feature-arrow {
font-size: 1.5rem;
color: #999;
}
}
.getting-started {
h3 {
color: white;
font-size: 1.8rem;
margin-bottom: 1.5rem;
font-weight: 600;
}
}
.steps-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 1.5rem;
}
.step-card {
background: rgba(255, 255, 255, 0.95);
padding: 2rem;
border-radius: 12px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
.step-number {
width: 40px;
height: 40px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-weight: 700;
font-size: 1.2rem;
margin-bottom: 1rem;
}
h4 {
color: #333;
margin: 0 0 0.5rem 0;
font-size: 1.2rem;
}
p {
color: #666;
margin: 0 0 1rem 0;
}
.btn-link {
background: none;
border: none;
color: #667eea;
font-weight: 500;
cursor: pointer;
padding: 0;
transition: color 0.3s ease;
&:hover {
color: #764ba2;
text-decoration: underline;
}
}
}
.dashboard-footer {
background: rgba(0, 0, 0, 0.2);
padding: 1.5rem 0;
text-align: center;
color: white;
margin-top: auto;
p {
margin: 0;
opacity: 0.8;
} }
} }
@media (max-width: 768px) { @media (max-width: 768px) {
.dashboard-header .header-content { .dashboard-content {
flex-direction: column; padding: 1rem;
gap: 1rem;
} }
.welcome-section h2 { .dashboard-header h1 {
font-size: 1.8rem; font-size: 1.5rem;
} }
.stats-grid, .stats-grid,
.features-grid, .tips-grid {
.steps-grid {
grid-template-columns: 1fr; grid-template-columns: 1fr;
} }
} }
@@ -1,6 +1,5 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { Router } from '@angular/router';
import { AuthService } from '../../core/auth/auth.service'; import { AuthService } from '../../core/auth/auth.service';
import { User } from '../../shared/models/user.model'; import { User } from '../../shared/models/user.model';
@@ -14,72 +13,27 @@ import { User } from '../../shared/models/user.model';
export class DashboardComponent implements OnInit { export class DashboardComponent implements OnInit {
currentUser: User | null = null; currentUser: User | null = null;
features = [ stats = [
{ { label: 'Business Units', value: '4', icon: '🏢', color: '#3f51b5' },
title: 'Business Units', { label: 'Applications', value: '7', icon: '📱', color: '#009688' },
description: 'Manage organizational business units', { label: 'Environments', value: '4', icon: '🌍', color: '#ff9800' },
icon: '🏢', { label: 'Persons', value: '4', icon: '👤', color: '#e91e63' },
route: '/business-units', { label: 'Contacts', value: '0', icon: '👥', color: '#9c27b0' },
color: '#3f51b5' { label: 'Contact Roles', value: '8', icon: '🎭', color: '#607d8b' }
},
{
title: 'Applications',
description: 'Manage applications and their lifecycle',
icon: '📱',
route: '/applications',
color: '#009688'
},
{
title: 'Environments',
description: 'Manage deployment environments',
icon: '🌍',
route: '/environments',
color: '#ff9800'
},
{
title: 'Persons',
description: 'Manage individual contacts',
icon: '👤',
route: '/persons',
color: '#e91e63'
},
{
title: 'Contacts',
description: 'Manage functional contacts and roles',
icon: '👥',
route: '/contacts',
color: '#9c27b0'
},
{
title: 'Contact Roles',
description: 'View predefined contact roles',
icon: '🎭',
route: '/contact-roles',
color: '#607d8b'
}
]; ];
stats = [ recentActivity = [
{ label: 'Business Units', value: '4', icon: '🏢' }, { action: 'Created', entity: 'Application', name: 'Mobile App', time: '2 hours ago' },
{ label: 'Applications', value: '7', icon: '📱' }, { action: 'Updated', entity: 'Business Unit', name: 'Digital Services', time: '5 hours ago' },
{ label: 'Environments', value: '4', icon: '🌍' }, { action: 'Created', entity: 'Person', name: 'John Doe', time: '1 day ago' },
{ label: 'Persons', value: '4', icon: '👤' } { action: 'Updated', entity: 'Environment', name: 'PROD-EU', time: '2 days ago' }
]; ];
constructor( constructor(
private router: Router,
private authService: AuthService private authService: AuthService
) {} ) {}
ngOnInit(): void { ngOnInit(): void {
this.currentUser = this.authService.getCurrentUser(); this.currentUser = this.authService.getCurrentUser();
} }
navigate(route: string): void {
this.router.navigate([route]);
}
logout(): void {
this.authService.logout();
}
} }