Commit 86f4c48d authored by Heber Cordova's avatar Heber Cordova

feat: added navigation

added sidebar, navigation and routes
parent d8c50604
......@@ -26,7 +26,8 @@
],
"styles": [
"src/styles.css",
"node_modules/bootstrap/dist/css/bootstrap.min.css"
"node_modules/bootstrap/dist/css/bootstrap.min.css",
"node_modules/bootstrap-icons/font/bootstrap-icons.min.css"
],
"scripts": [
"node_modules/bootstrap/dist/js/bootstrap.bundle.min.js"
......
......@@ -18,6 +18,7 @@
"@angular/router": "^16.2.0",
"axios": "^1.5.1",
"bootstrap": "^5.3.2",
"bootstrap-icons": "^1.11.1",
"json-server": "^0.17.4",
"json-server-auth": "^2.1.0",
"rxjs": "~7.8.0",
......@@ -4269,6 +4270,21 @@
"@popperjs/core": "^2.11.8"
}
},
"node_modules/bootstrap-icons": {
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.11.1.tgz",
"integrity": "sha512-F0DDp7nKUX+x/QtpfRZ+XHFya60ng9nfdpdS59vDDfs4Uhuxp7zym/QavMsu/xx51txkoM9eVmpE7D08N35blw==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/twbs"
},
{
"type": "opencollective",
"url": "https://opencollective.com/bootstrap"
}
]
},
"node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
......
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { AgentHomePageComponent } from './pages/home-page/home-page.component';
import { PassengersComponent } from './pages/passengers/passengers.component';
import { ReservationsComponent } from './pages/reservations/reservations.component';
const routes: Routes = [
{
path: '',
title: 'Home',
component: AgentHomePageComponent,
children: [
{
path: 'passengers',
title: 'Pasajeros',
component: PassengersComponent
},
{
path: 'reservations',
title: 'Reservas',
component: ReservationsComponent
}
]
},
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class AgentRoutingModule { }
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { SharedModule } from '../shared/shared.module';
import { AgentRoutingModule } from './agent-routing.module';
import { AgentHomePageComponent } from './pages/home-page/home-page.component';
import { PassengersComponent } from './pages/passengers/passengers.component';
import { ReservationsComponent } from './pages/reservations/reservations.component';
@NgModule({
declarations: [
AgentHomePageComponent,
PassengersComponent,
ReservationsComponent
],
imports: [
CommonModule,
SharedModule,
AgentRoutingModule
],
exports:[
AgentRoutingModule
]
})
export class AgentModule { }
<div class="d-flex">
<div class="w-auto">
<shared-sidebar [toggle]="toggleSidebar" [menuItems]="menuItems"></shared-sidebar>
</div>
<div class="w-100">
<shared-navigation [navigationItems]="menuItems" (toggleSidebarEvent)="toggleSidebarEvent()"></shared-navigation>
<router-outlet></router-outlet>
</div>
</div>
import { Component } from '@angular/core';
import { MenuItem } from 'src/app/shared/interfaces/menu-item.interface';
@Component({
selector: 'agent-home-page',
templateUrl: './home-page.component.html',
styleUrls: ['./home-page.component.css']
})
export class AgentHomePageComponent {
public toggleSidebar: boolean = false;
public menuItems: MenuItem[] = [
{
label: 'Pasajeros',
icon: 'bi-heart',
link: '/agents/passengers'
},
{
label: 'Reservas',
icon: 'bi-bookmarks',
link: '/agents/reservations'
},
];
toggleSidebarEvent(): void {
this.toggleSidebar = !this.toggleSidebar;
}
}
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Itaque nisi earum libero illo neque, fugiat maiores esse voluptatem quisquam, qui quam iste facilis hic necessitatibus doloribus, excepturi quos cum inventore.</p>
import { Component } from '@angular/core';
@Component({
selector: 'app-passengers',
templateUrl: './passengers.component.html',
styleUrls: ['./passengers.component.css']
})
export class PassengersComponent {
}
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Veniam harum facilis sequi excepturi asperiores labore, aliquam officiis tempore, eveniet illum voluptates fugiat rem ex rerum quaerat hic iure vero. Consectetur.</p>
import { Component } from '@angular/core';
@Component({
selector: 'app-reservations',
templateUrl: './reservations.component.html',
styleUrls: ['./reservations.component.css']
})
export class ReservationsComponent {
}
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
const routes: Routes = [];
const routes: Routes = [
{
path: 'passengers',
loadChildren: () => import('./passenger/passenger.module').then(m => m.PassengerModule)
},
{
path: 'agents',
loadChildren: () => import('./agent/agent.module').then(m => m.AgentModule)
},
{
path: 'supervisors',
loadChildren: () => import('./supervisor/supervisor.module').then(m => m.SupervisorModule)
}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
......
/* You can add global styles to this file, and also import other style files */
:root {
--blue: #007bff;
--indigo: #6610f2;
--purple: #6f42c1;
--pink: #e83e8c;
--red: #dc3545;
--orange: #fd7e14;
--yellow: #ffc107;
--green: #28a745;
--teal: #20c997;
--cyan: #17a2b8;
--white: #fff;
--gray: #6c757d;
--gray-dark: #343a40;
--primary: #007bff;
--secondary: #6c757d;
--success: #28a745;
--info: #17a2b8;
--warning: #ffc107;
--danger: #dc3545;
--light: #f8f9fa;
--dark: #343a40;
--breakpoint-xs: 0;
--breakpoint-sm: 576px;
--breakpoint-md: 768px;
--breakpoint-lg: 992px;
--breakpoint-xl: 1200px;
--font-family-sans-serif: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";
--font-family-monospace: SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;
}
.body {
font-family: var(--font-family-sans-serif);
}
\ No newline at end of file
<h1 class="text-center pt-4">Hello world!</h1>
<router-outlet></router-outlet>
\ No newline at end of file
import { Component } from '@angular/core';
import { Component, OnInit } from '@angular/core';
import { MenuItem } from './shared/interfaces/menu-item.interface';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'flight-agency-app';
export class AppComponent implements OnInit{
public toggleSidebar: boolean = false;
public passengerMenuItems: MenuItem[] = [
{
label: 'Mis reservas',
icon: 'bi-bookmarks',
link: '/passengers/reservations'
},
];
public supervisorMenuItems: MenuItem[] = [
{
label: 'Agentes',
icon: 'bi-people',
link: '/supervisors/agents'
},
{
label: 'Vuelos',
icon: 'bi-airplane',
link: '/supervisors/flight-config'
},
];
public agentMenuItems: MenuItem[] = [
{
label: 'Pasajeros',
icon: 'bi-heart',
link: '/agents/passengers'
},
{
label: 'Reservas',
icon: 'bi-bookmarks',
link: '/agents/reservations'
},
];
public menuItems: MenuItem[] = [];
ngOnInit(): void {
this.menuItems = this.agentMenuItems;
}
toggleSidebarEvent(): void {
this.toggleSidebar = !this.toggleSidebar;
}
}
......@@ -3,6 +3,10 @@ import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { SupervisorModule } from './supervisor/supervisor.module';
import { AgentModule } from './agent/agent.module';
import { PassengerModule } from './passenger/passenger.module';
import { SharedModule } from './shared/shared.module';
@NgModule({
declarations: [
......@@ -10,7 +14,11 @@ import { AppComponent } from './app.component';
],
imports: [
BrowserModule,
AppRoutingModule
AppRoutingModule,
SharedModule,
SupervisorModule,
AgentModule,
PassengerModule
],
providers: [],
bootstrap: [AppComponent]
......
import axios, { AxiosInstance } from 'axios';
const http: AxiosInstance = axios.create({
baseURL: 'http://localhost:3000/',
timeout: 10000,
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
'Authorization': 'Bearer YOUR_ACCESS_TOKEN', // TODO: Replace with my token
},
});
export { http };
<div class="d-flex">
<div class="w-auto">
<shared-sidebar [toggle]="toggleSidebar" [menuItems]="menuItems"></shared-sidebar>
</div>
<div class="w-100">
<shared-navigation (toggleSidebarEvent)="toggleSidebarEvent()"></shared-navigation>
<router-outlet></router-outlet>
</div>
</div>
\ No newline at end of file
import { Component } from '@angular/core';
import { MenuItem } from 'src/app/shared/interfaces/menu-item.interface';
@Component({
selector: 'passenger-home-page',
templateUrl: './home-page.component.html',
styleUrls: ['./home-page.component.css']
})
export class HomePageComponent {
public toggleSidebar: boolean = false;
public menuItems: MenuItem[] = [
{
label: 'Mis reservas',
icon: 'bi-bookmarks',
link: '/passengers/reservations'
},
];
toggleSidebarEvent(): void {
this.toggleSidebar = !this.toggleSidebar;
}
}
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Officia, tempora possimus. Repellendus pariatur quisquam illo, eius qui harum quasi tempore aspernatur debitis hic assumenda ex dolorem ullam quod vel temporibus.</p>
import { Component } from '@angular/core';
@Component({
selector: 'passenger-my-reservations',
templateUrl: './my-reservations.component.html',
styleUrls: ['./my-reservations.component.css']
})
export class MyReservationsComponent {
}
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomePageComponent } from './pages/home-page/home-page.component';
import { MyReservationsComponent } from './pages/my-reservations/my-reservations.component';
const routes: Routes = [
{
path: '',
title: 'Home',
component: HomePageComponent,
children: [
{
path: 'reservations',
title: 'Mis reservas',
component: MyReservationsComponent
},
]
},
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class PassengerRoutingModule { }
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { SharedModule } from '../shared/shared.module';
import { PassengerRoutingModule } from './passenger-rounting.module';
import { HomePageComponent } from './pages/home-page/home-page.component';
import { MyReservationsComponent } from './pages/my-reservations/my-reservations.component';
@NgModule({
declarations: [
HomePageComponent,
MyReservationsComponent
],
imports: [
CommonModule,
SharedModule,
PassengerRoutingModule
],
exports: [
PassengerRoutingModule
]
})
export class PassengerModule { }
.navigation {
padding: 0 25px 15px 25px;
}
.navigation h2 {
margin-top: 10px;
margin-bottom: 0;
}
.navigation p {
margin-bottom: 0;
font-size: 12px;
font-weight: 400px;
}
.navigation-1 {
background-color: #f3f3f4;
padding: 15px 30px 15px 20px;
}
.container-image {
padding: 8px;
}
.user {
margin-right: 10px;
font-size: 13px;
font-weight: 300;
cursor: pointer;
}
.user span {
margin-right: 5px;
}
.btn-menu {
background-color: #1a7bb9;
color: white;
font-weight: 700;
}
<div class="d-flex justify-content-between align-items-center navigation-1">
<div class="d-flex">
<div class="d-flex align-items-center">
<button class="btn btn-menu" (click)="toggleSidebar()">
<i class="bi bi-list"></i>
</button>
</div>
<div class="container-image">
<img height="35" src="assets/byte-banner.png" alt="Byte banner">
</div>
</div>
<div class="d-flex align-items-center">
<div class="user">
<span>Nombre</span>
<i class="bi bi-caret-down-fill"></i>
</div>
<button class="btn">
<i class="bi bi-list-task"></i>
</button>
<button class="btn">
<i class="bi bi-box-arrow-right"></i>
</button>
</div>
</div>
<div *ngIf="titleRoute" class="bg-white navigation">
<h2>{{ titleRoute }}</h2>
<p class="d-flex gap-2">
<span>Inicio</span>
<span> / </span>
<strong>{{ titleRoute }}</strong>
</p>
</div>
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { MenuItem } from '../../interfaces/menu-item.interface';
@Component({
selector: 'shared-navigation',
templateUrl: './navigation.component.html',
styleUrls: ['./navigation.component.css']
})
export class NavigationComponent implements OnInit {
constructor(private activatedRoute: ActivatedRoute) {}
ngOnInit(): void {
// TODO: Subscribe to the title of the current route
this.activatedRoute.title.subscribe(title => {
this.titleRoute = title;
});
}
public titleRoute?: string;
@Input()
public navigationItems: MenuItem[] = [];
@Output()
public toggleSidebarEvent: EventEmitter<void> = new EventEmitter<void>();
toggleSidebar():void {
this.toggleSidebarEvent.emit();
}
}
.wrapper {
background-color: #374653;
height: 100vh;
display: none;
}
@media (min-width: 768px) {
.wrapper {
width: 210px;
display: inline-block;
}
/* .wrapper .active {
width: 210px;
} */
}
.container-image {
display: flex;
justify-content: center;
align-items: center;
background-color: #2f4151;
}
.container-image img {
margin: 18px 0;
height: 48px;
}
@media (min-width: 768px) {
.container-image {
padding: 33px 25px;
}
.container-image img {
margin: 0;
width: 60px;
height: 60px;
}
}
.navigation {
margin: 0;
padding: 0;
}
.navigation-item {
display: flex;
list-style: none;
padding: 14px 25px;
color: #a7b1c2;
font-size: 12px;
font-weight: 600;
position: relative;
}
.navigation-item.toggle span{
display: none;
}
.navigation-item:hover {
background-color: #293947;
color: #fff;
}
.navigation-item i {
margin-right: 12px;
}
.navigation-item span {
display: none;
}
@media (min-width: 768px) {
.navigation-item span {
display: block;
}
}
.active {
background-color: #293947;
color: #fff;
font-weight: bold;
}
.active::before {
position: absolute;
content: '';
height: 100%;
width: 6px;
left: 0;
top: 0;
background: #19aa8d;
border-radius: 2px;
}
.toggle {
max-width: 70px !important;
overflow: hidden;
}
\ No newline at end of file
<div class="wrapper" [ngClass]="{'toggle': toggle}">
<div class="container-image">
<img src="assets/logo_byte_menu.png" alt="Logo Byte">
</div>
<ul class="navigation">
<li *ngFor="let item of menuItems" class="navigation-item" [ngClass]="{'toggle': toggle}" [routerLink]="[item.link]" routerLinkActive="active" [routerLinkActiveOptions]="{ exact: true }">
<i class="bi {{item.icon}}"></i>
<span>{{ item.label }}</span>
</li>
</ul>
</div>
import { Component, Input } from '@angular/core';
import { MenuItem } from '../../interfaces/menu-item.interface';
@Component({
selector: 'shared-sidebar',
templateUrl: './sidebar.component.html',
styleUrls: ['./sidebar.component.css']
})
export class SidebarComponent {
@Input()
public menuItems: MenuItem[] = [];
@Input()
public toggle: boolean = false;
}
export interface MenuItem {
label: string;
icon: string;
link: string;
subMenuItems?: MenuItem[];
}
\ No newline at end of file
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { SidebarComponent } from './components/sidebar/sidebar.component';
import { RouterModule } from '@angular/router';
import { NavigationComponent } from './components/navigation/navigation.component';
@NgModule({
declarations: [
SidebarComponent,
NavigationComponent
],
imports: [
CommonModule,
RouterModule,
],
exports: [
SidebarComponent,
NavigationComponent
]
})
export class SharedModule { }
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Repudiandae, sint ut totam quisquam ducimus, veniam aliquid commodi fuga necessitatibus quo dolor. Suscipit autem harum amet temporibus dignissimos sed tempora modi!</p>
import { Component } from '@angular/core';
@Component({
selector: 'app-agents',
templateUrl: './agents.component.html',
styleUrls: ['./agents.component.css']
})
export class AgentsComponent {
}
<p>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Nulla saepe soluta labore, dolore ad assumenda enim natus veritatis possimus vel animi, culpa, voluptatum facere. Ut reprehenderit quidem sint molestias tempore.</p>
\ No newline at end of file
import { Component } from '@angular/core';
@Component({
selector: 'app-flight-config',
templateUrl: './flight-config.component.html',
styleUrls: ['./flight-config.component.css']
})
export class FlightConfigComponent {
}
<div class="d-flex">
<div class="w-auto">
<shared-sidebar [toggle]="toggleSidebar" [menuItems]="menuItems"></shared-sidebar>
</div>
<div class="w-100">
<shared-navigation (toggleSidebarEvent)="toggleSidebarEvent()"></shared-navigation>
<router-outlet></router-outlet>
</div>
</div>
\ No newline at end of file
import { Component } from '@angular/core';
import { MenuItem } from 'src/app/shared/interfaces/menu-item.interface';
@Component({
selector: 'app-home-page',
templateUrl: './home-page.component.html',
styleUrls: ['./home-page.component.css']
})
export class HomePageComponent {
public toggleSidebar: boolean = false;
public menuItems: MenuItem[] = [
{
label: 'Agentes',
icon: 'bi-people',
link: '/supervisors/agents'
},
{
label: 'Vuelos',
icon: 'bi-airplane',
link: '/supervisors/flight-config'
},
];
toggleSidebarEvent(): void {
this.toggleSidebar = !this.toggleSidebar;
}
}
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomePageComponent } from './pages/home-page/home-page.component';
import { FlightConfigComponent } from './pages/flight-config/flight-config.component';
import { AgentsComponent } from './pages/agents/agents.component';
const routes: Routes = [
{
path: '',
title: 'Home',
component: HomePageComponent,
children: [
{
path: 'flight-config',
title: 'Configuración de vuelos',
component: FlightConfigComponent
},
{
path: 'agents',
title: 'Agentes',
component: AgentsComponent
},
]
},
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class SupervisorRoutingModule { }
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { SharedModule } from '../shared/shared.module';
import { SupervisorRoutingModule } from './supervisor-routing.module';
import { FlightConfigComponent } from './pages/flight-config/flight-config.component';
import { AgentsComponent } from './pages/agents/agents.component';
import { HomePageComponent } from './pages/home-page/home-page.component';
@NgModule({
declarations: [
FlightConfigComponent,
AgentsComponent,
HomePageComponent
],
imports: [
CommonModule,
SharedModule,
SupervisorRoutingModule
],
exports:[
SupervisorRoutingModule
]
})
export class SupervisorModule { }
/* You can add global styles to this file, and also import other style files */
/* You can add global styles to this file, and also import other style files */
:root {
--blue: #007bff;
--indigo: #6610f2;
--purple: #6f42c1;
--pink: #e83e8c;
--red: #dc3545;
--orange: #fd7e14;
--yellow: #ffc107;
--green: #28a745;
--teal: #20c997;
--cyan: #17a2b8;
--white: #fff;
--gray: #6c757d;
--gray-dark: #343a40;
--primary: #007bff;
--secondary: #6c757d;
--success: #28a745;
--info: #17a2b8;
--warning: #ffc107;
--danger: #dc3545;
--light: #f8f9fa;
--dark: #343a40;
--breakpoint-xs: 0;
--breakpoint-sm: 576px;
--breakpoint-md: 768px;
--breakpoint-lg: 992px;
--breakpoint-xl: 1200px;
--font-family-sans-serif: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";
--font-family-monospace: SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;
}
.body {
font-family: var(--font-family-sans-serif);
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment