import { Component, computed, inject, signal } from '@angular/core';
import { toSignal } from '@angular/core/rxjs-interop';
import { NavigationEnd, Router, RouterOutlet } from '@angular/router';
import { filter, map, startWith } from 'rxjs';
import {
type AfricaniesMenuItem,
type AfricaniesNavItem,
type AfricaniesNotification,
type AfricaniesSideNavItem,
BreadcrumbComponent,
ConfirmService,
SegmentComponent,
SideNavComponent,
TabDefDirective,
TabsComponent,
ToastService,
} from '@africanies/africanies-ui';
import { DemoSectionComponent } from '../shared/demo-section.component';
import { PageHeaderComponent } from '../shared/page-header.component';
import {
NAV_APP_SHELL,
NAV_BREADCRUMB,
NAV_LOCAL_TABS,
NAV_ROUTED_TABS,
NAV_SEGMENT,
NAV_SIDE,
} from '../snippets';
import { AppShellViewportPreviewComponent } from './viewport-preview.component';
/**
*
*/
@Component({
selector: 'app-navigation-page',
standalone: true,
imports: [
AppShellViewportPreviewComponent,
BreadcrumbComponent,
TabsComponent,
TabDefDirective,
SegmentComponent,
SideNavComponent,
RouterOutlet,
PageHeaderComponent,
DemoSectionComponent,
],
template: `
Active
{{ sideActiveId() }}
{{
sideCollapsed()
? 'Rail collapsed — hover an icon for the label blade.'
: 'Expanded — open Shipments for nested items.'
}}
Active density from URL:
{{
densityId() ?? '—'
}}
Local panel Alpha (not tied to the URL).
Local panel Beta (not tied to the URL).
`,
})
export class NavigationPage {
private readonly router = inject(Router);
private readonly confirm = inject(ConfirmService);
private readonly toast = inject(ToastService);
private readonly url = toSignal(
this.router.events.pipe(
filter((e): e is NavigationEnd => e instanceof NavigationEnd),
map(() => this.router.url),
startWith(this.router.url),
),
{ initialValue: this.router.url },
);
protected readonly routeTabId = signal(null);
protected readonly densityId = signal(null);
protected readonly localTabId = signal('alpha');
protected readonly sideCollapsed = signal(false);
protected readonly sideActiveId = signal('track');
protected readonly shellBreadcrumbs: AfricaniesNavItem[] = [
{ id: 'home', label: 'Home', icon: 'home' },
{ id: 'shipments', label: 'Shipments' },
{ id: 'track', label: 'STN-1042' },
];
protected readonly userMenuItems: AfricaniesMenuItem[] = [
{ label: 'Profile', icon: 'user', onClick: () => undefined },
{ label: 'Settings', icon: 'cog', onClick: () => undefined },
{
label: 'Log out',
icon: 'sign-out',
danger: true,
dividerBefore: true,
onClick: () => this.confirmLogout(),
},
];
protected readonly shellNotifications: AfricaniesNotification[] = [
{
id: 'n1',
title: 'Shipment STN-1042 delivered',
body: 'POD captured at Lagos hub.',
timestamp: new Date().toISOString(),
},
{
id: 'n2',
title: 'Warehouse sync complete',
timestamp: new Date(Date.now() - 3_600_000).toISOString(),
read: true,
},
];
protected readonly sideNav: AfricaniesSideNavItem[] = [
{ id: 'home', label: 'Home', icon: 'home' },
{
id: 'shipments',
label: 'Shipments',
icon: 'truck',
badge: true,
children: [
{ id: 'track', label: 'Track', icon: 'map-marker', badge: true },
{ id: 'create', label: 'Create', icon: 'plus' },
],
},
{ id: 'warehouse', label: 'Warehouse', icon: 'warehouse' },
{ id: 'settings', label: 'Settings', icon: 'cog' },
];
protected readonly routeTabs: AfricaniesNavItem[] = [
{
id: 'overview',
label: 'Overview',
icon: 'inbox',
routerLink: '/components/navigation/overview',
},
{
id: 'documents',
label: 'Documents',
icon: 'file-add',
routerLink: '/components/navigation/documents',
},
{
id: 'events',
label: 'Events',
icon: 'alarm',
routerLink: '/components/navigation/events',
},
];
protected readonly densitySegments: AfricaniesNavItem[] = [
{
id: 'comfortable',
label: 'Comfortable',
routerLink: '/components/navigation/overview',
queryParams: { density: 'comfortable' },
},
{
id: 'compact',
label: 'Compact',
routerLink: '/components/navigation/overview',
queryParams: { density: 'compact' },
},
{
id: 'dense',
label: 'Dense',
routerLink: '/components/navigation/overview',
queryParams: { density: 'dense' },
},
];
protected readonly localTabs: AfricaniesNavItem[] = [
{ id: 'alpha', label: 'Alpha' },
{ id: 'beta', label: 'Beta' },
];
protected readonly breadcrumbCode = NAV_BREADCRUMB;
protected readonly routedTabsCode = NAV_ROUTED_TABS;
protected readonly segmentCode = NAV_SEGMENT;
protected readonly localTabsCode = NAV_LOCAL_TABS;
protected readonly sideNavCode = NAV_SIDE;
protected readonly appShellCode = NAV_APP_SHELL;
/** Breadcrumb trail derived from the current URL (consumer pattern). */
protected readonly crumbs = computed((): AfricaniesNavItem[] => {
const path = this.url().split('?')[0] ?? '';
const leaf =
path.includes('/documents')
? 'Documents'
: path.includes('/events')
? 'Events'
: 'Overview';
return [
{ id: 'home', label: 'Home', routerLink: '/overview', icon: 'home' },
{
id: 'nav',
label: 'Navigation',
routerLink: '/components/navigation/overview',
},
{ id: 'leaf', label: leaf },
];
});
private confirmLogout(): void {
this.confirm
.confirm({
title: 'Log out?',
message:
'This signs you out of this device and every other session.',
confirmLabel: 'Log out',
danger: true,
})
.subscribe((ok) => {
if (ok) {
this.toast.success('You have been logged out.');
}
});
}
}