actualizacion

This commit is contained in:
luis cespedes 2025-04-29 09:15:15 -04:00
parent 8ab593e713
commit 53f0220073
20 changed files with 715 additions and 56 deletions

View File

@ -34,6 +34,7 @@
"styles": [
"src/styles.scss",
"node_modules/animate.css/animate.min.css",
"node_modules/primeflex/primeflex.css"
],
"scripts": []
},

View File

@ -13,8 +13,12 @@ export const appConfig: ApplicationConfig = {
provideAnimations(),
providePrimeNG({
theme: {
preset: Aura
preset: Aura,
options: {
darkModeSelector: false || 'none'
}
}
})
]
};

View File

@ -1,9 +1,20 @@
import { Routes } from '@angular/router';
import { LoginComponent } from './pages/login/login.component';
import { SidebarComponent } from './components/sidebar/sidebar.component';
import { LayoutComponent } from './components/layout/layout.component';
import { HomeComponent } from './pages/home/home.component';
export const routes: Routes = [
{ path: '', redirectTo: 'login', pathMatch: 'full' },
{ path: 'login', component: LoginComponent },
{ path: '**', redirectTo: 'login' }
{
path: '',
component: LayoutComponent,
children: [
{ path: '', redirectTo: 'home', pathMatch: 'full' },
{ path: 'home', component: HomeComponent },
]
},
{ path: '**', redirectTo: 'home' }
];

View File

@ -0,0 +1,29 @@
<div class="layout-wrapper">
<!-- Fixed sidebar -->
<div class="sidebar-wrapper" [ngClass]="{'sidebar-visible': isSidebarVisible}">
<app-sidebar></app-sidebar>
</div>
<!-- Main content area -->
<div class="main-content-wrapper" [ngStyle]="{'margin-left': isSidebarVisible ? '250px' : '0'}">
<!-- Top navbar -->
<app-navbar (sidebarToggle)="toggleSidebar()"></app-navbar>
<!-- Page content -->
<div class="page-content">
<router-outlet></router-outlet>
</div>
<!-- Footer -->
<footer class="footer">
<div class="footer-left">
<div>Superintendencia de Servicios Sanitarios</div>
<div>Área de Información y Tecnología</div>
</div>
<div class="footer-right">
<div>Dirección: Moneda 673 Piso 9 - Metro Santa Lucía</div>
<div>Mesa Central +56 2 23824000</div>
</div>
</footer>
</div>
</div>

View File

@ -0,0 +1,73 @@
/* src/app/components/layout/layout.component.scss */
.layout-wrapper {
display: flex;
min-height: 100vh;
}
.sidebar-wrapper {
flex: 0 0 250px;
width: 250px;
position: fixed;
height: 100vh;
z-index: 100;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
background-color: #0088cc;
transition: transform 0.3s ease, width 0.3s ease;
}
/* Para pantallas grandes */
.sidebar-wrapper:not(.sidebar-visible) {
transform: translateX(-250px);
width: 0;
}
.main-content-wrapper {
flex: 1;
margin-left: 250px;
display: flex;
flex-direction: column;
min-height: 100vh;
background-color: #f8f9fa;
transition: margin-left 0.3s ease;
}
/* Ajustar el margen cuando el sidebar está oculto */
.sidebar-wrapper:not(.sidebar-visible) ~ .main-content-wrapper {
margin-left: 0;
}
.page-content {
flex: 1;
padding: 0;
background-color: #f8f9fa;
}
.footer {
display: flex;
justify-content: space-between;
background-color: #0088cc;
color: white;
padding: 0.75rem 1rem;
font-size: 0.8rem;
}
.footer-left, .footer-right {
display: flex;
flex-direction: column;
}
/* Ajustes para tablets y móviles */
@media (max-width: 992px) {
.sidebar-wrapper {
transform: translateX(-100%);
transition: transform 0.3s;
}
.main-content-wrapper {
margin-left: 0;
}
.sidebar-wrapper.sidebar-visible {
transform: translateX(0);
}
}

View File

@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { LayoutComponent } from './layout.component';
describe('LayoutComponent', () => {
let component: LayoutComponent;
let fixture: ComponentFixture<LayoutComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [LayoutComponent]
})
.compileComponents();
fixture = TestBed.createComponent(LayoutComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,32 @@
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';
import { NavbarComponent } from '../navbar/navbar.component';
import { SidebarComponent } from '../sidebar/sidebar.component';
@Component({
selector: 'app-layout',
imports: [
CommonModule,
RouterModule,
NavbarComponent,
SidebarComponent
],
templateUrl: './layout.component.html',
styleUrl: './layout.component.scss',
standalone: true,
})
export class LayoutComponent {
isSidebarVisible: boolean = true;
toggleSidebar() {
console.log('Toggling sidebar, current state:', this.isSidebarVisible);
this.isSidebarVisible = !this.isSidebarVisible;
console.log('New sidebar state:', this.isSidebarVisible);
// Aplicar clase al body solo para móviles
if (window.innerWidth <= 992) {
document.body.classList.toggle('sidebar-visible', this.isSidebarVisible);
}
}
}

View File

@ -0,0 +1,25 @@
<div class="navbar-container">
<!-- Left navbar section with menu toggle -->
<div class="navbar-left">
<button pButton icon="pi pi-bars" class="p-button-text p-button-rounded sidebar-toggle"
(click)="toggleSidebar()"></button>
<span class="app-title">Administrador de Cronogramas</span>
</div>
<!-- Right navbar section with user info -->
<div class="navbar-right">
<span class="user-name">Luis Muñoz</span>
<button pButton icon="pi pi-sign-out" class="p-button-text p-button-rounded logout-button">
</button>
</div>
</div>
<!-- Page title and breadcrumb -->
<div class="page-header">
<div class="page-title">{{ pageTitle }}</div>
<div class="breadcrumb-container">
<a routerLink="/dashboard" class="breadcrumb-link">Home</a>
<span class="breadcrumb-separator">/</span>
<span class="breadcrumb-current">{{ pageTitle }}</span>
</div>
</div>

View File

@ -0,0 +1,92 @@
.navbar-container {
display: flex;
justify-content: space-between;
align-items: center;
background-color: #bcdaef;
height: 48px;
padding: 0 1rem;
width: 100%;
}
.navbar-left {
display: flex;
align-items: center;
}
.sidebar-toggle {
color: #343a40;
margin-right: 0.5rem;
}
.app-title {
font-weight: bold;
color: #0a2847;
font-size: 1rem;
}
.navbar-right {
display: flex;
align-items: center;
}
.user-name {
margin-right: 0.5rem;
font-size: 0.9rem;
color: #0a2847;
}
.logout-button {
color: #0a2847;
}
/* Page header styles */
.page-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem;
border-bottom: 1px solid #dee2e6;
background-color: #fff;
}
.page-title {
font-size: 1.25rem;
font-weight: 500;
color: #495057;
}
.breadcrumb-container {
font-size: 0.875rem;
color: #6c757d;
}
.breadcrumb-link {
color: #0088cc;
text-decoration: none;
}
.breadcrumb-link:hover {
text-decoration: underline;
}
.breadcrumb-separator {
margin: 0 0.25rem;
}
.breadcrumb-current {
color: #6c757d;
}
/* Sobrescribir estilos de PrimeNG para los botones en el navbar */
:host ::ng-deep .p-button.p-button-text {
padding: 0.5rem;
color: #0a2847;
&:focus {
box-shadow: none;
}
.p-button-icon {
font-size: 1rem;
}
}

View File

@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { NavbarComponent } from './navbar.component';
describe('NavbarComponent', () => {
let component: NavbarComponent;
let fixture: ComponentFixture<NavbarComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [NavbarComponent]
})
.compileComponents();
fixture = TestBed.createComponent(NavbarComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,17 @@
import { Component, EventEmitter, Output } from '@angular/core';
@Component({
selector: 'app-navbar',
imports: [],
templateUrl: './navbar.component.html',
styleUrl: './navbar.component.scss'
})
export class NavbarComponent {
@Output() sidebarToggle = new EventEmitter<void>();
pageTitle: string = 'Starter Page';
toggleSidebar() {
this.sidebarToggle.emit();
}
}

View File

@ -0,0 +1,62 @@
<div class="sidebar">
<!-- Logo container -->
<div class="logo-container">
<!-- Imagen del logo con posicionamiento para el badge -->
<div class="logo-image-container">
<img src="img/SAC-2.jpeg" alt="SISS Logo" class="logo-image">
<div class="version-badge">1.0</div>
</div>
<!-- Subtítulo del logo -->
</div>
<!-- Separador -->
<div class="separator"></div>
<!-- Navigation Menu -->
<div class="menu-container">
<ul class="sidebar-menu">
<li class="menu-item active" routerLinkActive="active">
<a routerLink="/inicio" class="menu-link">
<i class="menu-icon pi pi-cog"></i>
<span class="menu-text">Inicio</span>
</a>
</li>
<li class="menu-item" routerLinkActive="active">
<a routerLink="/unidad-concesiones" class="menu-link">
<i class="menu-icon pi pi-cog"></i>
<span class="menu-text">Unidad de Concesiones</span>
</a>
</li>
<li class="menu-item" routerLinkActive="active">
<a routerLink="/ct-actualizacion" class="menu-link">
<i class="menu-icon pi pi-flag"></i>
<span class="menu-text">CT Actualización de PD</span>
</a>
</li>
<li class="menu-item" routerLinkActive="active">
<a routerLink="/ct-ajuste" class="menu-link">
<i class="menu-icon pi pi-sliders-h"></i>
<span class="menu-text">CT Ajuste de PD</span>
</a>
</li>
<li class="menu-item" routerLinkActive="active">
<a routerLink="/resumen" class="menu-link">
<i class="menu-icon pi pi-list"></i>
<span class="menu-text">Resumen</span>
</a>
</li>
<li class="menu-item" routerLinkActive="active">
<a routerLink="/unidad-informacion" class="menu-link">
<i class="menu-icon pi pi-box"></i>
<span class="menu-text">Unidad de Información</span>
</a>
</li>
</ul>
</div>
</div>

View File

@ -0,0 +1,114 @@
.sidebar {
width: 250px;
height: 100%;
background-color: #bcdaef;
display: flex;
flex-direction: column;
}
.logo-container {
text-align: center;
}
.logo-image-container {
position: relative;
display: inline-block;
margin-bottom: 0.5rem;
}
.logo-image {
width: 100%;
height: auto;
display: block;
margin: 0 auto;
}
.version-badge {
position: absolute;
top: 0;
right: 20px;
background-color: #0088cc;
color: white;
border-radius: 50%;
width: 24px;
height: 24px;
display: flex;
align-items: center;
justify-content: center;
font-size: 0.7rem;
font-weight: bold;
}
.logo-text {
font-size: 1.5rem;
font-weight: bold;
color: #0a2847;
margin-bottom: 0.25rem;
}
.logo-subtitle {
font-size: 0.7rem;
color: #0a2847;
max-width: 180px;
margin: 0 auto;
line-height: 1.2;
}
.separator {
height: 1px;
background-color: #a3c5e6;
margin: 0 0.5rem;
}
.menu-container {
padding: 0.5rem 0;
flex: 1;
overflow-y: auto;
}
.sidebar-menu {
list-style: none;
padding: 0;
margin: 0;
}
.menu-item {
margin: 2px 0;
padding: 0 0.5rem; /* Añadimos padding lateral al ítem */
}
.menu-link {
display: flex;
align-items: center;
padding: 0.75rem 1rem;
color: #0a2847;
text-decoration: none;
transition: background-color 0.2s, box-shadow 0.3s;
border-left: 3px solid transparent;
border-radius: .25rem;
width: calc(100% - 1rem); /* Reducimos el ancho para crear margen */
}
.menu-link:hover {
background-color: #dadada !important;
}
.menu-icon {
margin-right: 0.75rem;
width: 1.25rem;
text-align: center;
color: #0a2847;
}
.menu-text {
font-size: 0.9rem;
}
.menu-item.active .menu-link {
background: linear-gradient(90deg, rgba(255,255,255,0.3) 0%, rgba(255,255,255,0) 100%) !important;
border-left: 3px solid white !important;
color: #706f6f !important;
font-weight: 600;
box-shadow: 0 1px 3px rgba(0,0,0,.12), 0 1px 2px rgba(0,0,0,.24) !important;
margin: 0 auto; /* Centra el elemento */
}

View File

@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { SidebarComponent } from './sidebar.component';
describe('SidebarComponent', () => {
let component: SidebarComponent;
let fixture: ComponentFixture<SidebarComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [SidebarComponent]
})
.compileComponents();
fixture = TestBed.createComponent(SidebarComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,11 @@
import { Component } from '@angular/core';
@Component({
selector: 'app-sidebar',
imports: [],
templateUrl: './sidebar.component.html',
styleUrl: './sidebar.component.scss'
})
export class SidebarComponent {
}

View File

@ -0,0 +1,38 @@
<!-- src/app/pages/home/home.component.html -->
<div class="home-page">
<!-- Simple Card -->
<p-card styleClass="mb-4">
<ng-template pTemplate="title">
<div class="card-title">Simple Card</div>
</ng-template>
<ng-template pTemplate="content">
<p>Lorem ipsum dolor sit amet...</p>
</ng-template>
</p-card>
<!-- Accordion sections -->
<p-accordion [multiple]="true">
<p-accordionTab header="Header I" [selected]="true">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore
magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est
laborum.
</p>
</p-accordionTab>
<p-accordionTab header="Header II">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore
magna aliqua.
</p>
</p-accordionTab>
<p-accordionTab header="Header III">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</p>
</p-accordionTab>
</p-accordion>
</div>

View File

@ -0,0 +1,62 @@
/* src/app/pages/home/home.component.scss */
.home-page {
padding: 1rem;
}
.card-title {
font-size: 1.1rem;
font-weight: 500;
color: #495057;
}
/* Personalización del estilo de la card */
:host ::ng-deep .p-card {
border-radius: 0;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
.p-card-title {
font-size: 1.1rem;
margin-bottom: 0.5rem;
}
.p-card-content {
padding-top: 0;
}
}
/* Personalización del estilo del acordeón */
:host ::ng-deep .p-accordion {
.p-accordion-header {
.p-accordion-header-link {
background-color: #f8f9fa;
color: #495057;
border-radius: 0;
font-weight: 500;
padding: 1rem;
&:focus {
box-shadow: none;
}
.p-accordion-toggle-icon {
color: #0088cc;
}
}
&.p-highlight .p-accordion-header-link {
background-color: #f8f9fa;
color: #495057;
border-color: #dee2e6;
}
}
.p-accordion-content {
background-color: #ffffff;
border-color: #dee2e6;
padding: 1rem;
}
}
.mb-4 {
margin-bottom: 1rem;
}

View File

@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { HomeComponent } from './home.component';
describe('HomeComponent', () => {
let component: HomeComponent;
let fixture: ComponentFixture<HomeComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [HomeComponent]
})
.compileComponents();
fixture = TestBed.createComponent(HomeComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,21 @@
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
// Importaciones de PrimeNG
import { CardModule } from 'primeng/card';
import { AccordionModule } from 'primeng/accordion';
@Component({
selector: 'app-home',
imports: [
CommonModule,
CardModule,
AccordionModule
],
standalone: true,
templateUrl: './home.component.html',
styleUrl: './home.component.scss'
})
export class HomeComponent {
}

View File

@ -1,69 +1,44 @@
:root {
--primary-color: #0088cc; // Color principal azul SISS
--secondary-color: #0a2847; // Color azul oscuro
--light-blue: #d3e9f7; // Color para el header
--danger-color: #dc3545; // Color rojo para los indicadores en inputs
--font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
--primary-color: #0088cc; /* Azul principal SISS */
--primary-light: #bcdaef; /* Azul claro para fondos */
--text-color: #0a2847; /* Color texto principal */
--secondary-text: #6c757d; /* Texto secundario */
--border-color: #dee2e6; /* Color bordes */
--background-color: #f8f9fa; /* Fondo gris claro */
}
// Estilos generales
/* Estilos globales */
html, body {
margin: 0;
padding: 0;
height: 100%;
font-family: var(--font-family);
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
font-size: 14px;
color: var(--text-color);
}
body {
background-color: #f0f0f0;
background-color: var(--background-color);
}
// Estilos específicos para inputs
.p-inputtext {
padding: 0.75rem 0.75rem;
font-size: 1rem;
/* Clases de utilidad */
.mb-1 { margin-bottom: 0.25rem !important; }
.mb-2 { margin-bottom: 0.5rem !important; }
.mb-3 { margin-bottom: 1rem !important; }
.mb-4 { margin-bottom: 1.5rem !important; }
.mt-1 { margin-top: 0.25rem !important; }
.mt-2 { margin-top: 0.5rem !important; }
.mt-3 { margin-top: 1rem !important; }
.mt-4 { margin-top: 1.5rem !important; }
/* Personalizaciones globales de PrimeNG */
.p-component {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}
// Sobreescritura de estilos de PrimeNG
.p-button {
padding: 0.75rem 1.25rem;
border-radius: 4px;
&.p-button-primary {
background-color: var(--primary-color);
border-color: var(--primary-color);
&:hover {
background-color: darken(#0088cc, 10%);
border-color: darken(#0088cc, 10%);
}
.p-button.p-button-text {
&:focus {
box-shadow: none;
}
}
// Clase para fondos rojos en los addons de input
.bg-red-600 {
background-color: var(--danger-color) !important;
border-color: var(--danger-color) !important;
color: white !important;
}
// Sobreescribe el estilo de los iconos en los input groups
.p-inputgroup-addon {
.pi {
color: #6c757d;
}
}
// Ajustes para espaciado consistente
.mb-3 {
margin-bottom: 1rem !important;
}
.mb-4 {
margin-bottom: 1.5rem !important;
}
// Ajustes para el ancho completo
.w-full {
width: 100% !important;
}