diff --git a/angular.json b/angular.json
index 47839e8..93e6b3e 100644
--- a/angular.json
+++ b/angular.json
@@ -34,6 +34,7 @@
"styles": [
"src/styles.scss",
"node_modules/animate.css/animate.min.css",
+ "node_modules/primeflex/primeflex.css"
],
"scripts": []
},
diff --git a/src/app/app.config.ts b/src/app/app.config.ts
index 79b54c7..6119fcd 100644
--- a/src/app/app.config.ts
+++ b/src/app/app.config.ts
@@ -13,8 +13,12 @@ export const appConfig: ApplicationConfig = {
provideAnimations(),
providePrimeNG({
theme: {
- preset: Aura
+ preset: Aura,
+ options: {
+ darkModeSelector: false || 'none'
+ }
}
+
})
]
};
diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts
index a127a54..d763f1a 100644
--- a/src/app/app.routes.ts
+++ b/src/app/app.routes.ts
@@ -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' }
];
diff --git a/src/app/components/layout/layout.component.html b/src/app/components/layout/layout.component.html
new file mode 100644
index 0000000..da62be0
--- /dev/null
+++ b/src/app/components/layout/layout.component.html
@@ -0,0 +1,29 @@
+
\ No newline at end of file
diff --git a/src/app/components/layout/layout.component.scss b/src/app/components/layout/layout.component.scss
new file mode 100644
index 0000000..2ac6b11
--- /dev/null
+++ b/src/app/components/layout/layout.component.scss
@@ -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);
+ }
+ }
\ No newline at end of file
diff --git a/src/app/components/layout/layout.component.spec.ts b/src/app/components/layout/layout.component.spec.ts
new file mode 100644
index 0000000..09aa9fc
--- /dev/null
+++ b/src/app/components/layout/layout.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { LayoutComponent } from './layout.component';
+
+describe('LayoutComponent', () => {
+ let component: LayoutComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ imports: [LayoutComponent]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(LayoutComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/components/layout/layout.component.ts b/src/app/components/layout/layout.component.ts
new file mode 100644
index 0000000..e07acbb
--- /dev/null
+++ b/src/app/components/layout/layout.component.ts
@@ -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);
+ }
+ }
+}
diff --git a/src/app/components/navbar/navbar.component.html b/src/app/components/navbar/navbar.component.html
new file mode 100644
index 0000000..bcefa32
--- /dev/null
+++ b/src/app/components/navbar/navbar.component.html
@@ -0,0 +1,25 @@
+
+
+
+
+ Administrador de Cronogramas
+
+
+
+
+ Luis Muñoz
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/app/components/navbar/navbar.component.scss b/src/app/components/navbar/navbar.component.scss
new file mode 100644
index 0000000..63d1a0e
--- /dev/null
+++ b/src/app/components/navbar/navbar.component.scss
@@ -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;
+ }
+ }
\ No newline at end of file
diff --git a/src/app/components/navbar/navbar.component.spec.ts b/src/app/components/navbar/navbar.component.spec.ts
new file mode 100644
index 0000000..cfedf9e
--- /dev/null
+++ b/src/app/components/navbar/navbar.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { NavbarComponent } from './navbar.component';
+
+describe('NavbarComponent', () => {
+ let component: NavbarComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ imports: [NavbarComponent]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(NavbarComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/components/navbar/navbar.component.ts b/src/app/components/navbar/navbar.component.ts
new file mode 100644
index 0000000..bb9c46f
--- /dev/null
+++ b/src/app/components/navbar/navbar.component.ts
@@ -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();
+ pageTitle: string = 'Starter Page';
+
+ toggleSidebar() {
+ this.sidebarToggle.emit();
+ }
+
+}
diff --git a/src/app/components/sidebar/sidebar.component.html b/src/app/components/sidebar/sidebar.component.html
new file mode 100644
index 0000000..0465865
--- /dev/null
+++ b/src/app/components/sidebar/sidebar.component.html
@@ -0,0 +1,62 @@
+
\ No newline at end of file
diff --git a/src/app/components/sidebar/sidebar.component.scss b/src/app/components/sidebar/sidebar.component.scss
new file mode 100644
index 0000000..366dfe8
--- /dev/null
+++ b/src/app/components/sidebar/sidebar.component.scss
@@ -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 */
+}
\ No newline at end of file
diff --git a/src/app/components/sidebar/sidebar.component.spec.ts b/src/app/components/sidebar/sidebar.component.spec.ts
new file mode 100644
index 0000000..5445f3c
--- /dev/null
+++ b/src/app/components/sidebar/sidebar.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { SidebarComponent } from './sidebar.component';
+
+describe('SidebarComponent', () => {
+ let component: SidebarComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ imports: [SidebarComponent]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(SidebarComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/components/sidebar/sidebar.component.ts b/src/app/components/sidebar/sidebar.component.ts
new file mode 100644
index 0000000..4da8bba
--- /dev/null
+++ b/src/app/components/sidebar/sidebar.component.ts
@@ -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 {
+
+}
diff --git a/src/app/pages/home/home.component.html b/src/app/pages/home/home.component.html
new file mode 100644
index 0000000..686a623
--- /dev/null
+++ b/src/app/pages/home/home.component.html
@@ -0,0 +1,38 @@
+
+
+
+
+
+ Simple Card
+
+
+ Lorem ipsum dolor sit amet...
+
+
+
+
+
+
+
+ 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.
+
+
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore
+ magna aliqua.
+
+
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+
+
+
+
\ No newline at end of file
diff --git a/src/app/pages/home/home.component.scss b/src/app/pages/home/home.component.scss
new file mode 100644
index 0000000..0bf0724
--- /dev/null
+++ b/src/app/pages/home/home.component.scss
@@ -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;
+ }
\ No newline at end of file
diff --git a/src/app/pages/home/home.component.spec.ts b/src/app/pages/home/home.component.spec.ts
new file mode 100644
index 0000000..1191557
--- /dev/null
+++ b/src/app/pages/home/home.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { HomeComponent } from './home.component';
+
+describe('HomeComponent', () => {
+ let component: HomeComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ imports: [HomeComponent]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(HomeComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/pages/home/home.component.ts b/src/app/pages/home/home.component.ts
new file mode 100644
index 0000000..ef3febf
--- /dev/null
+++ b/src/app/pages/home/home.component.ts
@@ -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 {
+
+
+}
diff --git a/src/styles.scss b/src/styles.scss
index 2811923..b6bea4b 100644
--- a/src/styles.scss
+++ b/src/styles.scss
@@ -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;
- }
\ No newline at end of file
+
\ No newline at end of file