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
+123 -123
View File
@@ -12,139 +12,139 @@ export const routes: Routes = [
loadComponent: () => import('./core/auth/login/login.component').then(m => m.LoginComponent)
},
{
path: 'dashboard',
canActivate: [authGuard],
loadComponent: () => import('./features/dashboard/dashboard.component').then(m => m.DashboardComponent)
},
{
path: 'business-units',
path: '',
canActivate: [authGuard],
loadComponent: () => import('./core/layout/main-layout/main-layout.component').then(m => m.MainLayoutComponent),
children: [
{
path: '',
loadComponent: () => import('./features/business-units/business-unit-list/business-unit-list.component')
.then(m => m.BusinessUnitListComponent)
path: 'dashboard',
loadComponent: () => import('./features/dashboard/dashboard.component').then(m => m.DashboardComponent)
},
{
path: 'new',
loadComponent: () => import('./features/business-units/business-unit-form/business-unit-form.component')
.then(m => m.BusinessUnitFormComponent)
path: 'business-units',
children: [
{
path: '',
loadComponent: () => import('./features/business-units/business-unit-list/business-unit-list.component')
.then(m => m.BusinessUnitListComponent)
},
{
path: 'new',
loadComponent: () => import('./features/business-units/business-unit-form/business-unit-form.component')
.then(m => m.BusinessUnitFormComponent)
},
{
path: ':id',
loadComponent: () => import('./features/business-units/business-unit-detail/business-unit-detail.component')
.then(m => m.BusinessUnitDetailComponent)
},
{
path: ':id/edit',
loadComponent: () => import('./features/business-units/business-unit-form/business-unit-form.component')
.then(m => m.BusinessUnitFormComponent)
}
]
},
{
path: ':id',
loadComponent: () => import('./features/business-units/business-unit-detail/business-unit-detail.component')
.then(m => m.BusinessUnitDetailComponent)
path: 'applications',
children: [
{
path: '',
loadComponent: () => import('./features/applications/application-list/application-list.component')
.then(m => m.ApplicationListComponent)
},
{
path: 'new',
loadComponent: () => import('./features/applications/application-form/application-form.component')
.then(m => m.ApplicationFormComponent)
},
{
path: ':id',
loadComponent: () => import('./features/applications/application-detail/application-detail.component')
.then(m => m.ApplicationDetailComponent)
},
{
path: ':id/edit',
loadComponent: () => import('./features/applications/application-form/application-form.component')
.then(m => m.ApplicationFormComponent)
}
]
},
{
path: ':id/edit',
loadComponent: () => import('./features/business-units/business-unit-form/business-unit-form.component')
.then(m => m.BusinessUnitFormComponent)
path: 'environments',
children: [
{
path: '',
loadComponent: () => import('./features/environments/environment-list/environment-list.component')
.then(m => m.EnvironmentListComponent)
},
{
path: 'new',
loadComponent: () => import('./features/environments/environment-form/environment-form.component')
.then(m => m.EnvironmentFormComponent)
},
{
path: ':id',
loadComponent: () => import('./features/environments/environment-detail/environment-detail.component')
.then(m => m.EnvironmentDetailComponent)
},
{
path: ':id/edit',
loadComponent: () => import('./features/environments/environment-form/environment-form.component')
.then(m => m.EnvironmentFormComponent)
}
]
},
{
path: 'persons',
children: [
{
path: '',
loadComponent: () => import('./features/persons/person-list/person-list.component')
.then(m => m.PersonListComponent)
},
{
path: 'new',
loadComponent: () => import('./features/persons/person-form/person-form.component')
.then(m => m.PersonFormComponent)
},
{
path: ':id',
loadComponent: () => import('./features/persons/person-detail/person-detail.component')
.then(m => m.PersonDetailComponent)
},
{
path: ':id/edit',
loadComponent: () => import('./features/persons/person-form/person-form.component')
.then(m => m.PersonFormComponent)
}
]
},
{
path: 'contacts',
children: [
{
path: '',
loadComponent: () => import('./features/contacts/contact-list/contact-list.component')
.then(m => m.ContactListComponent)
},
{
path: 'new',
loadComponent: () => import('./features/contacts/contact-form/contact-form.component')
.then(m => m.ContactFormComponent)
},
{
path: ':id',
loadComponent: () => import('./features/contacts/contact-detail/contact-detail.component')
.then(m => m.ContactDetailComponent)
}
]
},
{
path: 'contact-roles',
loadComponent: () => import('./features/contacts/contact-role-list/contact-role-list.component')
.then(m => m.ContactRoleListComponent)
}
]
},
{
path: 'applications',
canActivate: [authGuard],
children: [
{
path: '',
loadComponent: () => import('./features/applications/application-list/application-list.component')
.then(m => m.ApplicationListComponent)
},
{
path: 'new',
loadComponent: () => import('./features/applications/application-form/application-form.component')
.then(m => m.ApplicationFormComponent)
},
{
path: ':id',
loadComponent: () => import('./features/applications/application-detail/application-detail.component')
.then(m => m.ApplicationDetailComponent)
},
{
path: ':id/edit',
loadComponent: () => import('./features/applications/application-form/application-form.component')
.then(m => m.ApplicationFormComponent)
}
]
},
{
path: 'environments',
canActivate: [authGuard],
children: [
{
path: '',
loadComponent: () => import('./features/environments/environment-list/environment-list.component')
.then(m => m.EnvironmentListComponent)
},
{
path: 'new',
loadComponent: () => import('./features/environments/environment-form/environment-form.component')
.then(m => m.EnvironmentFormComponent)
},
{
path: ':id',
loadComponent: () => import('./features/environments/environment-detail/environment-detail.component')
.then(m => m.EnvironmentDetailComponent)
},
{
path: ':id/edit',
loadComponent: () => import('./features/environments/environment-form/environment-form.component')
.then(m => m.EnvironmentFormComponent)
}
]
},
{
path: 'persons',
canActivate: [authGuard],
children: [
{
path: '',
loadComponent: () => import('./features/persons/person-list/person-list.component')
.then(m => m.PersonListComponent)
},
{
path: 'new',
loadComponent: () => import('./features/persons/person-form/person-form.component')
.then(m => m.PersonFormComponent)
},
{
path: ':id',
loadComponent: () => import('./features/persons/person-detail/person-detail.component')
.then(m => m.PersonDetailComponent)
},
{
path: ':id/edit',
loadComponent: () => import('./features/persons/person-form/person-form.component')
.then(m => m.PersonFormComponent)
}
]
},
{
path: 'contacts',
canActivate: [authGuard],
children: [
{
path: '',
loadComponent: () => import('./features/contacts/contact-list/contact-list.component')
.then(m => m.ContactListComponent)
},
{
path: 'new',
loadComponent: () => import('./features/contacts/contact-form/contact-form.component')
.then(m => m.ContactFormComponent)
},
{
path: ':id',
loadComponent: () => import('./features/contacts/contact-detail/contact-detail.component')
.then(m => m.ContactDetailComponent)
}
]
},
{
path: 'contact-roles',
canActivate: [authGuard],
loadComponent: () => import('./features/contacts/contact-role-list/contact-role-list.component')
.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,95 +1,66 @@
<div class="dashboard">
<header class="dashboard-header">
<div class="container">
<div class="header-content">
<div class="branding">
<h1>LDPv2</h1>
<p class="subtitle">Lifecycle Data Platform</p>
</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 class="dashboard-content">
<div class="dashboard-header">
<h1>Welcome back, {{ currentUser?.username }}! 👋</h1>
<p>Here's an overview of your application lifecycle data.</p>
</div>
<section class="stats-section">
<h2>Overview</h2>
<div class="stats-grid">
<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-content">
<div class="stat-value">{{ stat.value }}</div>
<div class="stat-label">{{ stat.label }}</div>
</div>
</div>
</div>
</header>
</section>
<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">
<div class="stats-grid">
<div class="stat-card" *ngFor="let stat of stats">
<div class="stat-icon">{{ stat.icon }}</div>
<div class="stat-content">
<div class="stat-value">{{ stat.value }}</div>
<div class="stat-label">{{ stat.label }}</div>
</div>
</div>
<section class="activity-section">
<h2>Recent Activity</h2>
<div class="activity-list">
<div class="activity-item" *ngFor="let activity of recentActivity">
<div class="activity-icon">
<span *ngIf="activity.action === 'Created'"></span>
<span *ngIf="activity.action === 'Updated'">📝</span>
<span *ngIf="activity.action === 'Deleted'">🗑️</span>
</div>
</section>
<section class="features-section">
<h3>Quick Access</h3>
<div class="features-grid">
<div
class="feature-card"
*ngFor="let feature of features"
(click)="navigate(feature.route)"
[style.border-left-color]="feature.color">
<div class="feature-icon">{{ feature.icon }}</div>
<div class="feature-content">
<h4>{{ feature.title }}</h4>
<p>{{ feature.description }}</p>
</div>
<div class="feature-arrow"></div>
<div class="activity-details">
<div class="activity-main">
<strong>{{ activity.action }}</strong> {{ activity.entity }}:
<span class="entity-name">{{ activity.name }}</span>
</div>
<div class="activity-time">{{ activity.time }}</div>
</div>
</section>
<section class="getting-started">
<h3>Getting Started</h3>
<div class="steps-grid">
<div class="step-card">
<div class="step-number">1</div>
<h4>Create Business Units</h4>
<p>Organize your applications by business units</p>
<button (click)="navigate('/business-units')" class="btn-link">
Go to Business Units →
</button>
</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 class="step-card">
<div class="step-number">3</div>
<h4>Configure Environments</h4>
<p>Set up deployment environments</p>
<button (click)="navigate('/environments')" class="btn-link">
Go to Environments →
</button>
</div>
</div>
</section>
</div>
</div>
</main>
</section>
<footer class="dashboard-footer">
<div class="container">
<p>LDPv2 - Lifecycle Data Platform v2 | © 2026</p>
<section class="quick-tips">
<h2>Quick Tips</h2>
<div class="tips-grid">
<div class="tip-card">
<div class="tip-icon">💡</div>
<div class="tip-content">
<h3>Get Started</h3>
<p>Use the sidebar to navigate between different sections of the application.</p>
</div>
</div>
<div class="tip-card">
<div class="tip-icon">🔍</div>
<div class="tip-content">
<h3>Search & Filter</h3>
<p>Most lists support search and filtering to help you find what you need quickly.</p>
</div>
</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>
</footer>
</section>
</div>
@@ -1,280 +1,184 @@
.dashboard {
min-height: 100vh;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
display: flex;
flex-direction: column;
}
.container {
max-width: 1200px;
.dashboard-content {
padding: 2rem;
max-width: 1400px;
margin: 0 auto;
padding: 0 2rem;
width: 100%;
}
.dashboard-header {
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
padding: 1.5rem 0;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
margin-bottom: 2rem;
.header-content {
display: flex;
justify-content: space-between;
align-items: center;
}
.branding h1 {
color: white;
h1 {
font-size: 2rem;
margin: 0;
font-weight: 700;
}
.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;
margin: 0 0 0.5rem 0;
color: #333;
}
p {
font-size: 1.2rem;
opacity: 0.9;
margin: 0;
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 {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 1.5rem;
margin-bottom: 3rem;
}
.stat-card {
background: white;
padding: 2rem;
border-radius: 12px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
padding: 1.5rem;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
display: flex;
align-items: center;
gap: 1.5rem;
transition: transform 0.3s ease;
&:hover { transform: translateY(-5px); }
.stat-icon { font-size: 3rem; }
.stat-value {
font-size: 2.5rem;
font-weight: 700;
color: #333;
}
.stat-label {
color: #666;
font-size: 0.9rem;
}
}
.features-section {
margin-bottom: 3rem;
h3 {
color: white;
font-size: 1.8rem;
margin-bottom: 1.5rem;
font-weight: 600;
}
}
.features-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 1.5rem;
}
.feature-card {
background: white;
padding: 2rem;
border-radius: 12px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
display: flex;
align-items: center;
gap: 1.5rem;
cursor: pointer;
transition: all 0.3s ease;
gap: 1rem;
border-left: 4px solid;
transition: transform 0.2s ease, box-shadow 0.2s ease;
&:hover {
transform: translateY(-5px);
box-shadow: 0 8px 12px rgba(0, 0, 0, 0.15);
transform: translateY(-4px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
.feature-icon { font-size: 3rem; }
.feature-content {
.stat-icon {
font-size: 2.5rem;
}
.stat-content {
flex: 1;
h4 {
margin: 0 0 0.5rem 0;
.stat-value {
font-size: 2rem;
font-weight: 700;
color: #333;
font-size: 1.3rem;
line-height: 1;
}
p {
margin: 0;
.stat-label {
color: #666;
font-size: 0.9rem;
margin-top: 0.25rem;
}
}
}
.feature-arrow {
font-size: 1.5rem;
color: #999;
.activity-section {
.activity-list {
background: white;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
overflow: hidden;
}
}
.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%;
.activity-item {
display: flex;
align-items: center;
justify-content: center;
font-weight: 700;
font-size: 1.2rem;
margin-bottom: 1rem;
}
gap: 1rem;
padding: 1rem 1.5rem;
border-bottom: 1px solid #f5f5f5;
transition: background-color 0.2s ease;
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;
&:last-child {
border-bottom: none;
}
&:hover {
color: #764ba2;
text-decoration: underline;
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;
}
}
.activity-time {
color: #999;
font-size: 0.85rem;
}
}
}
}
.dashboard-footer {
background: rgba(0, 0, 0, 0.2);
padding: 1.5rem 0;
text-align: center;
color: white;
margin-top: auto;
.quick-tips {
.tips-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 1.5rem;
}
p {
margin: 0;
opacity: 0.8;
.tip-card {
background: white;
padding: 1.5rem;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
display: flex;
gap: 1rem;
.tip-icon {
font-size: 2rem;
}
.tip-content {
flex: 1;
h3 {
margin: 0 0 0.5rem 0;
color: #333;
font-size: 1.1rem;
}
p {
margin: 0;
color: #666;
font-size: 0.9rem;
line-height: 1.5;
}
}
}
}
@media (max-width: 768px) {
.dashboard-header .header-content {
flex-direction: column;
gap: 1rem;
.dashboard-content {
padding: 1rem;
}
.welcome-section h2 {
font-size: 1.8rem;
.dashboard-header h1 {
font-size: 1.5rem;
}
.stats-grid,
.features-grid,
.steps-grid {
.tips-grid {
grid-template-columns: 1fr;
}
}
@@ -1,6 +1,5 @@
import { Component, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { Router } from '@angular/router';
import { AuthService } from '../../core/auth/auth.service';
import { User } from '../../shared/models/user.model';
@@ -14,72 +13,27 @@ import { User } from '../../shared/models/user.model';
export class DashboardComponent implements OnInit {
currentUser: User | null = null;
features = [
{
title: 'Business Units',
description: 'Manage organizational business units',
icon: '🏢',
route: '/business-units',
color: '#3f51b5'
},
{
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 = [
{ label: 'Business Units', value: '4', icon: '🏢', color: '#3f51b5' },
{ label: 'Applications', value: '7', icon: '📱', color: '#009688' },
{ label: 'Environments', value: '4', icon: '🌍', color: '#ff9800' },
{ label: 'Persons', value: '4', icon: '👤', color: '#e91e63' },
{ label: 'Contacts', value: '0', icon: '👥', color: '#9c27b0' },
{ label: 'Contact Roles', value: '8', icon: '🎭', color: '#607d8b' }
];
stats = [
{ label: 'Business Units', value: '4', icon: '🏢' },
{ label: 'Applications', value: '7', icon: '📱' },
{ label: 'Environments', value: '4', icon: '🌍' },
{ label: 'Persons', value: '4', icon: '👤' }
recentActivity = [
{ action: 'Created', entity: 'Application', name: 'Mobile App', time: '2 hours ago' },
{ action: 'Updated', entity: 'Business Unit', name: 'Digital Services', time: '5 hours ago' },
{ action: 'Created', entity: 'Person', name: 'John Doe', time: '1 day ago' },
{ action: 'Updated', entity: 'Environment', name: 'PROD-EU', time: '2 days ago' }
];
constructor(
private router: Router,
private authService: AuthService
) {}
ngOnInit(): void {
this.currentUser = this.authService.getCurrentUser();
}
navigate(route: string): void {
this.router.navigate([route]);
}
logout(): void {
this.authService.logout();
}
}