ADDED Materialize theme

This commit is contained in:
Marek Lesko
2025-10-13 18:18:04 +02:00
parent 9451589a9d
commit 4dda50cbf4
1669 changed files with 146258 additions and 1 deletions

View File

@@ -0,0 +1 @@
<router-outlet></router-outlet>

View File

@@ -0,0 +1,35 @@
import { TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { AppComponent } from './app.component';
describe('AppComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [
RouterTestingModule
],
declarations: [
AppComponent
],
}).compileComponents();
});
it('should create the app', () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app).toBeTruthy();
});
it(`should have as title 'Angular15'`, () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app.title).toEqual('Angular15');
});
it('should render title', () => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.nativeElement as HTMLElement;
expect(compiled.querySelector('.content span')?.textContent).toContain('Angular15 app is running!');
});
});

View File

@@ -0,0 +1,11 @@
import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
@Component({
selector: 'app-root',
imports: [RouterOutlet],
templateUrl: './app.component.html'
})
export class AppComponent {
title = 'Modernize Angular Admin Tempplate';
}

View File

@@ -0,0 +1,92 @@
import {
ApplicationConfig,
provideZoneChangeDetection,
importProvidersFrom,
} from '@angular/core';
import {
HttpClient,
provideHttpClient,
withInterceptorsFromDi,
} from '@angular/common/http';
import { routes } from './app.routes';
import {
provideRouter,
withComponentInputBinding,
withInMemoryScrolling,
} from '@angular/router';
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
import { provideClientHydration } from '@angular/platform-browser';
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { ToastrModule } from 'ngx-toastr';
import { provideToastr } from 'ngx-toastr';
// icons
import { TablerIconsModule } from 'angular-tabler-icons';
import * as TablerIcons from 'angular-tabler-icons/icons';
// perfect scrollbar
import { NgScrollbarModule } from 'ngx-scrollbar';
import { NgxPermissionsModule } from 'ngx-permissions';
//Import all material modules
import { MaterialModule } from './material.module';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { CalendarModule, DateAdapter } from 'angular-calendar';
import { adapterFactory } from 'angular-calendar/date-adapters/date-fns';
// code view
import { provideHighlightOptions } from 'ngx-highlightjs';
import 'highlight.js/styles/atom-one-dark.min.css';
export function HttpLoaderFactory(http: HttpClient): any {
return new TranslateHttpLoader(http, './assets/i18n/', '.json');
}
export const appConfig: ApplicationConfig = {
providers: [
provideAnimationsAsync(), // required animations providers
provideToastr(), // Toastr providers
provideZoneChangeDetection({ eventCoalescing: true }),
provideHighlightOptions({
coreLibraryLoader: () => import('highlight.js/lib/core'),
lineNumbersLoader: () => import('ngx-highlightjs/line-numbers'), // Optional, add line numbers if needed
languages: {
typescript: () => import('highlight.js/lib/languages/typescript'),
css: () => import('highlight.js/lib/languages/css'),
xml: () => import('highlight.js/lib/languages/xml'),
},
}),
provideRouter(
routes,
withInMemoryScrolling({
scrollPositionRestoration: 'enabled',
anchorScrolling: 'enabled',
}),
withComponentInputBinding()
),
provideHttpClient(withInterceptorsFromDi()),
provideClientHydration(),
provideAnimationsAsync(),
importProvidersFrom(
FormsModule,
ToastrModule.forRoot(),
ReactiveFormsModule,
MaterialModule,
NgxPermissionsModule.forRoot(),
TablerIconsModule.pick(TablerIcons),
NgScrollbarModule,
CalendarModule.forRoot({
provide: DateAdapter,
useFactory: adapterFactory,
}),
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: HttpLoaderFactory,
deps: [HttpClient],
},
})
),
],
};

View File

@@ -0,0 +1,107 @@
import { Routes } from '@angular/router';
import { BlankComponent } from './layouts/blank/blank.component';
import { FullComponent } from './layouts/full/full.component';
export const routes: Routes = [
{
path: '',
component: FullComponent,
children: [
{
path: '',
redirectTo: '/dashboards/dashboard1',
pathMatch: 'full',
},
{
path: 'starter',
loadChildren: () =>
import('./pages/pages.routes').then((m) => m.PagesRoutes),
},
{
path: 'dashboards',
loadChildren: () =>
import('./pages/dashboards/dashboards.routes').then(
(m) => m.DashboardsRoutes
),
},
{
path: 'forms',
loadChildren: () =>
import('./pages/forms/forms.routes').then((m) => m.FormsRoutes),
},
{
path: 'charts',
loadChildren: () =>
import('./pages/charts/charts.routes').then((m) => m.ChartsRoutes),
},
{
path: 'apps',
loadChildren: () =>
import('./pages/apps/apps.routes').then((m) => m.AppsRoutes),
},
{
path: 'widgets',
loadChildren: () =>
import('./pages/widgets/widgets.routes').then((m) => m.WidgetsRoutes),
},
{
path: 'tables',
loadChildren: () =>
import('./pages/tables/tables.routes').then((m) => m.TablesRoutes),
},
{
path: 'datatable',
loadChildren: () =>
import('./pages/datatable/datatable.routes').then(
(m) => m.DatatablesRoutes
),
},
{
path: 'theme-pages',
loadChildren: () =>
import('./pages/theme-pages/theme-pages.routes').then(
(m) => m.ThemePagesRoutes
),
},
{
path: 'ui-components',
loadChildren: () =>
import('./pages/ui-components/ui-components.routes').then(
(m) => m.UiComponentsRoutes
),
},
],
},
{
path: '',
component: BlankComponent,
children: [
{
path: 'authentication',
loadChildren: () =>
import('./pages/authentication/authentication.routes').then(
(m) => m.AuthenticationRoutes
),
},
{
path: 'landingpage',
loadChildren: () =>
import('./pages/theme-pages/landingpage/landingpage.routes').then(
(m) => m.LandingPageRoutes
),
},
{
path: 'front-pages',
loadChildren: () =>
import('./pages/front-pages/front-pages.routes').then(
(m) => m.FrontPagesRoutes
),
},
],
},
{
path: '**',
redirectTo: 'authentication/error',
},
];

View File

@@ -0,0 +1,23 @@
<mat-card class="b-1 shadow-none">
<div>
@if (isTitle) {
<div class="p-16 b-b-1">
<mat-card-title><ng-content select="[Ctitle]"></ng-content></mat-card-title>
</div>
}
</div>
<mat-tab-group animationDuration="0ms" mat-stretch-tabs="false">
<mat-tab label="Preview">
<div class="p-16">
<ng-content select="[output]"></ng-content>
</div>
</mat-tab>
<mat-tab label="HTML">
<ng-content select="[htmlView]"></ng-content>
</mat-tab>
<mat-tab label="Typescript">
<ng-content select="[tsView]"></ng-content>
</mat-tab>
</mat-tab-group>
</mat-card>

View File

@@ -0,0 +1,14 @@
import { Component, OnInit, Input } from '@angular/core';
import { MatCardModule } from '@angular/material/card';
import { MatTabsModule } from '@angular/material/tabs';
@Component({
selector: 'app-code-view',
templateUrl: './code-view.component.html',
imports: [MatTabsModule, MatCardModule],
})
export class AppCodeViewComponent implements OnInit {
constructor() {}
@Input() isTitle!: boolean;
ngOnInit(): void {}
}

View File

@@ -0,0 +1,31 @@
<!-- Customers -->
<mat-card class="cardWithShadow overflow-hidden">
<mat-card-content>
<mat-card-subtitle class="p-b-4">Customers</mat-card-subtitle>
<h5 class="f-s-21 m-t-4 f-w-600">36,358</h5>
<div class="d-flex align-items-center m-t-16">
<button
mat-mini-fab
class="bg-light-error text-error shadow-none icon-27"
>
<i-tabler name="arrow-down-left" class="icon-20 d-flex"></i-tabler>
</button>
<div class="f-s-14 f-w-600 m-l-12">+9%</div>
</div>
</mat-card-content>
<!-- ---------------------------- -->
<!-- charts here -->
<!-- ---------------------------- -->
<apx-chart
[series]="customerChart.series"
[dataLabels]="customerChart.dataLabels"
[chart]="customerChart.chart"
[legend]="customerChart.legend"
[colors]="customerChart.colors"
[stroke]="customerChart.stroke"
[tooltip]="customerChart.tooltip"
[plotOptions]="customerChart.plotOptions"
[responsive]="customerChart.responsive"
></apx-chart>
</mat-card>

View File

@@ -0,0 +1,79 @@
import { Component, ViewChild } from '@angular/core';
import {
ApexChart,
ChartComponent,
ApexDataLabels,
ApexLegend,
ApexStroke,
ApexTooltip,
ApexAxisChartSeries,
ApexPlotOptions,
ApexResponsive,
NgApexchartsModule,
} from 'ng-apexcharts';
import { MaterialModule } from '../../../material.module';
import { TablerIconsModule } from 'angular-tabler-icons';
export interface customerChart {
series: ApexAxisChartSeries;
chart: ApexChart;
dataLabels: ApexDataLabels;
plotOptions: ApexPlotOptions;
tooltip: ApexTooltip;
stroke: ApexStroke;
legend: ApexLegend;
responsive: ApexResponsive;
}
@Component({
selector: 'app-customers',
imports: [NgApexchartsModule, MaterialModule, TablerIconsModule],
templateUrl: './customers.component.html',
})
export class AppCustomersComponent {
@ViewChild('chart') chart: ChartComponent = Object.create(null);
public customerChart!: Partial<customerChart> | any;
constructor() {
this.customerChart = {
series: [
{
name: '',
color: '#49BEFF',
data: [30, 25, 35, 20, 30, 40],
},
],
chart: {
type: 'area',
fontFamily: "'Plus Jakarta Sans', sans-serif;",
foreColor: '#adb0bb',
toolbar: {
show: false,
},
height: 80,
sparkline: {
enabled: true,
},
group: 'sparklines',
},
stroke: {
curve: 'smooth',
width: 2,
},
fill: {
colors: ['#E8F7FF'],
type: 'solid',
opacity: 0.05,
},
markers: {
size: 0,
},
tooltip: {
theme: 'dark',
x: {
show: false,
},
},
};
}
}

View File

@@ -0,0 +1,50 @@
<mat-card class="cardWithShadow">
<mat-card-header>
<mat-card-title>Employee Salary</mat-card-title>
<mat-card-subtitle>Every month</mat-card-subtitle>
</mat-card-header>
<mat-card-content>
<!-- ---------------------------- -->
<!-- charts here -->
<!-- ---------------------------- -->
<apx-chart
[series]="employeeChart.series"
[plotOptions]="employeeChart.plotOptions"
[dataLabels]="employeeChart.dataLabels"
[chart]="employeeChart.chart"
[legend]="employeeChart.legend"
[colors]="employeeChart.colors"
[tooltip]="employeeChart.tooltip"
[xaxis]="employeeChart.xaxis"
[yaxis]="employeeChart.yaxis"
[grid]="employeeChart.grid"
></apx-chart>
<div class="d-flex align-items-center justify-content-between m-t-16">
<div class="d-flex align-items-center">
<span
class="text-primary bg-light-primary rounded icon-40 d-flex align-items-center justify-content-center"
>
<i-tabler name="grid-dots" class="icon-20"></i-tabler>
</span>
<div class="m-l-12">
<span class="f-s-14">Salary</span>
<h5 class="f-s-16 f-w-600 m-t-4">$36,358</h5>
</div>
</div>
<div class="d-flex align-items-center">
<span
class="bg-light text-body rounded icon-40 d-flex align-items-center justify-content-center"
>
<i-tabler name="grid-dots" class="icon-20"></i-tabler>
</span>
<div class="m-l-12">
<span class="f-s-14">Profit</span>
<h5 class="f-s-16 f-w-600 m-t-4">$5,296</h5>
</div>
</div>
</div>
</mat-card-content>
</mat-card>

View File

@@ -0,0 +1,102 @@
import { Component, ViewChild } from '@angular/core';
import {
ApexChart,
ChartComponent,
ApexDataLabels,
ApexLegend,
ApexTooltip,
ApexAxisChartSeries,
ApexPlotOptions,
ApexGrid,
ApexXAxis,
ApexYAxis,
NgApexchartsModule,
} from 'ng-apexcharts';
import { MaterialModule } from '../../../material.module';
import { TablerIconsModule } from 'angular-tabler-icons';
export interface employeeChart {
series: ApexAxisChartSeries;
chart: ApexChart;
dataLabels: ApexDataLabels;
plotOptions: ApexPlotOptions;
tooltip: ApexTooltip;
legend: ApexLegend;
grid: ApexGrid;
xaxis: ApexXAxis;
yaxis: ApexYAxis;
}
@Component({
selector: 'app-employee-salary',
imports: [NgApexchartsModule, MaterialModule, TablerIconsModule],
templateUrl: './employee-salary.component.html',
})
export class AppEmployeeSalaryComponent {
@ViewChild('chart') chart: ChartComponent = Object.create(null);
public employeeChart!: Partial<employeeChart> | any;
constructor() {
this.employeeChart = {
series: [
{
name: '',
data: [20, 15, 30, 25, 10, 15],
},
],
chart: {
type: 'bar',
fontFamily: "'Plus Jakarta Sans', sans-serif;",
foreColor: '#adb0bb',
toolbar: {
show: false,
},
height: 270,
},
colors: [
'#ECF2FF',
'#ECF2FF',
'#5D87FF',
'#ECF2FF',
'#ECF2FF',
'#ECF2FF',
],
plotOptions: {
bar: {
borderRadius: 4,
columnWidth: '45%',
distributed: true,
endingShape: 'rounded',
},
},
dataLabels: {
enabled: false,
},
legend: {
show: false,
},
grid: {
yaxis: {
lines: {
show: false,
},
},
},
xaxis: {
categories: [['Apr'], ['May'], ['June'], ['July'], ['Aug'], ['Sept']],
axisBorder: {
show: false,
},
},
yaxis: {
labels: {
show: false,
},
},
tooltip: {
theme: 'dark',
},
};
}
}

View File

@@ -0,0 +1,38 @@
<mat-card class="cardWithShadow overflow-hidden">
<mat-card-header class="d-flex align-items-center">
<mat-card-title>Monthly Earnings</mat-card-title>
<div class="m-l-auto">
<button mat-fab class="bg-secondary shadow-none icon-48">
<i-tabler name="currency-dollar" class="text-white d-flex"></i-tabler>
</button>
</div>
</mat-card-header>
<mat-card-content>
<h4 class="f-s-24">$6,820</h4>
<div class="d-flex align-items-center m-t-16">
<button
mat-mini-fab
class="bg-light-error text-error shadow-none icon-27"
>
<i-tabler name="arrow-down-right" class="icon-20 d-flex"></i-tabler>
</button>
<div class="f-s-14 f-w-600 m-l-12">+9%</div>
<div class="f-s-14 f-w-400 m-l-4">last year</div>
</div>
</mat-card-content>
<!-- ---------------------------- -->
<!-- charts here -->
<!-- ---------------------------- -->
<apx-chart
[series]="monthlyChart.series"
[dataLabels]="monthlyChart.dataLabels"
[chart]="monthlyChart.chart"
[legend]="monthlyChart.legend"
[colors]="monthlyChart.colors"
[stroke]="monthlyChart.stroke"
[tooltip]="monthlyChart.tooltip"
[plotOptions]="monthlyChart.plotOptions"
[responsive]="monthlyChart.responsive"
></apx-chart>
</mat-card>

View File

@@ -0,0 +1,80 @@
import { Component, ViewChild } from '@angular/core';
import {
ApexChart,
ChartComponent,
ApexDataLabels,
ApexLegend,
ApexStroke,
ApexTooltip,
ApexAxisChartSeries,
ApexPlotOptions,
ApexResponsive,
NgApexchartsModule,
} from 'ng-apexcharts';
import { MaterialModule } from '../../../material.module';
import { TablerIconsModule } from 'angular-tabler-icons';
export interface monthlyChart {
series: ApexAxisChartSeries;
chart: ApexChart;
dataLabels: ApexDataLabels;
plotOptions: ApexPlotOptions;
tooltip: ApexTooltip;
stroke: ApexStroke;
legend: ApexLegend;
responsive: ApexResponsive;
}
@Component({
selector: 'app-monthly-earnings',
imports: [NgApexchartsModule, MaterialModule, TablerIconsModule],
templateUrl: './monthly-earnings.component.html',
})
export class AppMonthlyEarningsComponent {
@ViewChild('chart') chart: ChartComponent = Object.create(null);
public monthlyChart!: Partial<monthlyChart> | any;
constructor() {
this.monthlyChart = {
series: [
{
name: '',
color: '#49BEFF',
data: [25, 66, 20, 40, 12, 58, 20],
},
],
chart: {
type: 'area',
fontFamily: "'Plus Jakarta Sans', sans-serif;",
foreColor: '#adb0bb',
toolbar: {
show: false,
},
height: 60,
sparkline: {
enabled: true,
},
group: 'sparklines',
},
stroke: {
curve: 'smooth',
width: 2,
},
fill: {
colors: ['#E8F7FF'],
type: 'solid',
opacity: 0.05,
},
markers: {
size: 0,
},
tooltip: {
theme: 'dark',
x: {
show: false,
},
},
};
}
}

View File

@@ -0,0 +1,31 @@
<mat-card class="cardWithShadow">
<mat-card-content>
<mat-card-subtitle class="p-b-4">Projects</mat-card-subtitle>
<h5 class="f-s-21 m-t-4 f-w-600">78,298</h5>
<div class="d-flex align-items-center m-t-16">
<button
mat-mini-fab
class="bg-light-success text-success shadow-none icon-27"
>
<i-tabler name="arrow-up-left" class="icon-20 d-flex"></i-tabler>
</button>
<div class="f-s-14 f-w-600 m-l-12">+9%</div>
</div>
<!-- ---------------------------- -->
<!-- charts here -->
<!-- ---------------------------- -->
<apx-chart
[series]="projectsChart.series"
[chart]="projectsChart.chart"
[plotOptions]="projectsChart.plotOptions"
[tooltip]="projectsChart.tooltip"
[stroke]="projectsChart.stroke"
[xaxis]="projectsChart.xaxis"
[yaxis]="projectsChart.yaxis"
[grid]="projectsChart.grid"
[colors]="projectsChart.colors"
></apx-chart>
</mat-card-content>
</mat-card>

View File

@@ -0,0 +1,109 @@
import { Component, ViewChild } from '@angular/core';
import {
ApexChart,
ChartComponent,
ApexStroke,
ApexTooltip,
ApexAxisChartSeries,
ApexPlotOptions,
ApexGrid,
ApexXAxis,
ApexYAxis,
NgApexchartsModule,
} from 'ng-apexcharts';
import { MaterialModule } from '../../../material.module';
import { TablerIconsModule } from 'angular-tabler-icons';
export interface projectsChart {
series: ApexAxisChartSeries;
chart: ApexChart;
plotOptions: ApexPlotOptions;
tooltip: ApexTooltip;
stroke: ApexStroke;
grid: ApexGrid;
xaxis: ApexXAxis;
yaxis: ApexYAxis;
}
@Component({
selector: 'app-projects',
imports: [NgApexchartsModule, MaterialModule, TablerIconsModule],
templateUrl: './projects.component.html',
})
export class AppProjectsComponent {
@ViewChild('chart') chart: ChartComponent = Object.create(null);
public projectsChart!: Partial<projectsChart> | any;
constructor() {
this.projectsChart = {
series: [
{
name: '',
data: [4, 10, 9, 7, 9, 10, 11, 8, 10],
},
],
chart: {
type: 'bar',
fontFamily: "'Plus Jakarta Sans', sans-serif;",
foreColor: '#adb0bb',
toolbar: {
show: false,
},
height: 80,
resize: true,
barColor: '#fff',
sparkline: {
enabled: true,
},
},
colors: ['#5D87FF'],
grid: {
show: false,
},
plotOptions: {
bar: {
horizontal: false,
startingShape: 'flat',
endingShape: 'flat',
columnWidth: '60%',
barHeight: '20%',
borderRadius: 3,
},
},
stroke: {
show: true,
width: 2.5,
colors: ['rgba(0,0,0,0.01)'],
},
xaxis: {
axisBorder: {
show: false,
},
axisTicks: {
show: false,
},
labels: {
show: false,
},
},
yaxis: {
labels: {
show: false,
},
},
axisBorder: {
show: false,
},
fill: {
opacity: 1,
},
tooltip: {
theme: 'dark',
x: {
show: false,
},
},
};
}
}

View File

@@ -0,0 +1,80 @@
<mat-card class="cardWithShadow">
<mat-card-header class="p-b-12">
<div class="d-flex w-100">
<div>
<mat-card-title>Revenue Updates</mat-card-title>
<mat-card-subtitle>Overview of Profit</mat-card-subtitle>
</div>
<div class="m-l-auto">
<mat-form-field class="theme-select" appearance="outline">
<mat-select value="mar">
@for(month of months; track month.viewValue ) {
<mat-option [value]="month.value">
{{ month.viewValue }}
</mat-option>
}
</mat-select>
</mat-form-field>
</div>
</div>
</mat-card-header>
<mat-card-content>
<div class="row">
<div class="col-sm-8">
<!-- ---------------------------- -->
<!-- charts here -->
<!-- ---------------------------- -->
<apx-chart
[series]="revenueChart.series"
[dataLabels]="revenueChart.dataLabels"
[chart]="revenueChart.chart"
[legend]="revenueChart.legend"
[xaxis]="revenueChart.xaxis"
[yaxis]="revenueChart.yaxis"
[grid]="revenueChart.grid"
[stroke]="revenueChart.stroke"
[tooltip]="revenueChart.tooltip"
[plotOptions]="revenueChart.plotOptions"
></apx-chart>
</div>
<div class="col-sm-4">
<div class="d-flex align-items-center m-t-24">
<span
class="text-primary bg-light-primary rounded icon-40 d-flex align-items-center justify-content-center"
>
<i-tabler name="grid-dots" class="icon-20"></i-tabler>
</span>
<div class="m-l-12">
<h5 class="f-s-24 m-b-4">$63,489.50</h5>
<span class="f-s-14">Total Earnings</span>
</div>
</div>
<div class="d-flex m-t-32">
<i-tabler
name="circle-filled"
class="text-primary icon-12 m-t-4"
></i-tabler>
<div class="m-l-12">
<span class="f-s-14">Earnings this month</span>
<h3 class="f-s-18 f-w-600 m-t-4">$48,820</h3>
</div>
</div>
<div class="d-flex m-t-24">
<i-tabler
name="circle-filled"
class="text-secondary icon-12 m-t-4"
></i-tabler>
<div class="m-l-12">
<span class="f-s-14">Expense this month</span>
<h3 class="f-s-18 f-w-600 m-t-4">$26,498</h3>
</div>
</div>
<button mat-flat-button class="w-100 m-t-32">View Full Report</button>
</div>
</div>
</mat-card-content>
</mat-card>

View File

@@ -0,0 +1,136 @@
import { Component, ViewChild } from '@angular/core';
import {
ApexChart,
ChartComponent,
ApexDataLabels,
ApexLegend,
ApexStroke,
ApexTooltip,
ApexAxisChartSeries,
ApexXAxis,
ApexYAxis,
ApexGrid,
ApexPlotOptions,
ApexFill,
ApexMarkers,
NgApexchartsModule,
} from 'ng-apexcharts';
import { MaterialModule } from '../../../material.module';
import { TablerIconsModule } from 'angular-tabler-icons';
interface month {
value: string;
viewValue: string;
}
export interface revenueChart {
series: ApexAxisChartSeries;
chart: ApexChart;
dataLabels: ApexDataLabels;
plotOptions: ApexPlotOptions;
yaxis: ApexYAxis;
xaxis: ApexXAxis;
fill: ApexFill;
tooltip: ApexTooltip;
stroke: ApexStroke;
legend: ApexLegend;
grid: ApexGrid;
marker: ApexMarkers;
}
@Component({
selector: 'app-revenue-updates',
imports: [NgApexchartsModule, MaterialModule, TablerIconsModule],
templateUrl: './revenue-updates.component.html',
})
export class AppRevenueUpdatesComponent {
@ViewChild('chart') chart: ChartComponent = Object.create(null);
public revenueChart!: Partial<revenueChart> | any;
months: month[] = [
{ value: 'mar', viewValue: 'March 2025' },
{ value: 'apr', viewValue: 'April 2025' },
{ value: 'june', viewValue: 'June 2025' },
];
constructor() {
this.revenueChart = {
series: [
{
name: 'Eanings this month',
data: [1.5, 2.7, 2.2, 3.6, 1.5, 1.0],
color: '#5D87FF',
},
{
name: 'Expense this month',
data: [-1.8, -1.1, -2.5, -1.5, -0.6, -1.8],
color: '#49BEFF',
},
],
chart: {
type: 'bar',
fontFamily: "'Plus Jakarta Sans', sans-serif;",
foreColor: '#adb0bb',
toolbar: {
show: false,
},
height: 340,
stacked: true,
},
plotOptions: {
bar: {
horizontal: false,
columnWidth: '20%',
borderRadius: [6],
borderRadiusApplication: 'end',
borderRadiusWhenStacked: 'all',
},
},
stroke: {
show: false,
},
dataLabels: {
enabled: false,
},
legend: {
show: false,
},
grid: {
borderColor: 'rgba(0,0,0,0.1)',
strokeDashArray: 3,
xaxis: {
lines: {
show: false,
},
},
},
yaxis: {
min: -5,
max: 5,
tickAmount: 4,
},
xaxis: {
categories: [
'16/08',
'17/08',
'18/08',
'19/08',
'20/08',
'21/08',
'22/08',
],
axisBorder: {
show: false,
},
},
tooltip: {
theme: 'dark',
fillSeriesColor: false,
},
};
}
}

View File

@@ -0,0 +1,50 @@
<mat-card class="shadow-none bg-primary">
<mat-card-content class="p-t-32">
<mat-card-title class="text-white">Best selling products</mat-card-title>
<mat-card-subtitle class="text-white">Overview 2025</mat-card-subtitle>
<div class="text-center">
<img
src="assets/images/backgrounds/piggy.png"
alt="image"
width="300"
class="m-t-18 minus-img"
/>
</div>
</mat-card-content>
<mat-card class="shadow-none m-12">
<mat-card-content>
<div class="d-flex align-items-center m-b-8">
<div class="m-r-auto">
<h6 class="f-s-16 f-w-600 m-b-4">MaterialPro</h6>
<span class="f-s-14 f-w-400">$23,568</span>
</div>
<span
class="bg-light-primary text-primary rounded f-w-600 p-4 f-s-12 p-x-12"
>
55%
</span>
</div>
<mat-progress-bar
mode="determinate"
value="55"
class="rounded"
></mat-progress-bar>
<div class="d-flex align-items-center m-b-8 m-t-16">
<div class="m-r-auto">
<h6 class="f-s-16 f-w-600 m-b-4">Flexy Admin</h6>
<span class="f-s-14 f-w-400">$23,568</span>
</div>
<span
class="bg-light-secondary text-secondary rounded f-w-600 p-4 f-s-12 p-x-12"
>
20%
</span>
</div>
<mat-progress-bar
mode="determinate"
value="20"
class="rounded bg-secondary"
></mat-progress-bar>
</mat-card-content>
</mat-card>
</mat-card>

View File

@@ -0,0 +1,9 @@
import { Component } from '@angular/core';
import { MaterialModule } from '../../../material.module';
@Component({
selector: 'app-selling-product',
imports: [MaterialModule],
templateUrl: './selling-product.component.html',
})
export class AppSellingProductComponent {}

View File

@@ -0,0 +1,54 @@
<mat-card class="cardWithShadow">
<mat-card-content>
<div class="d-flex align-items-center">
<img
src="assets/images/profile/user-1.jpg"
alt="social"
width="70"
class="rounded"
/>
<div class="m-l-12">
<mat-card-title>Super awesome, Vue coming soon! </mat-card-title>
<mat-card-subtitle class="f-s-14 f-w-400 m-t-8"
>22 March, 2025</mat-card-subtitle
>
</div>
</div>
<div
class="d-flex align-items-center justify-content-between m-t-32 p-t-10"
>
<div class="social-chips">
<img
src="assets/images/profile/user-2.jpg"
width="40"
alt="social"
class="rounded-circle"
/>
<img
src="assets/images/profile/user-3.jpg"
width="40"
alt="social"
class="rounded-circle"
/>
<img
src="assets/images/profile/user-4.jpg"
width="40"
alt="social"
class="rounded-circle"
/>
<img
src="assets/images/profile/user-5.jpg"
width="40"
alt="social"
class="rounded-circle"
/>
</div>
<button
mat-mini-fab
class="text-primary bg-light-primary rounded"
>
<i-tabler name="message-2" class="icon-20 d-flex"></i-tabler>
</button>
</div>
</mat-card-content>
</mat-card>

View File

@@ -0,0 +1,10 @@
import { Component } from '@angular/core';
import { MaterialModule } from '../../../material.module';
import { TablerIconsModule } from 'angular-tabler-icons';
@Component({
selector: 'app-social-card',
imports: [MaterialModule, TablerIconsModule],
templateUrl: './social-card.component.html',
})
export class AppSocialCardComponent {}

View File

@@ -0,0 +1,22 @@
<div class="row">
@for(topcard of topcards; track topcard.title) {
<div class="col-lg-2 col-sm-4 col-6">
<mat-card class="shadow-none text-center bg-light-{{ topcard.color }}">
<mat-card-content>
<img
[src]="topcard.img"
alt="users"
width="40"
class="rounded-circle"
/>
<h4 class="f-s-14 f-w-600 text-{{ topcard.color }} m-t-8">
{{ topcard.title }}
</h4>
<h6 class="f-s-21 f-w-600 text-{{ topcard.color }} m-t-8">
{{ topcard.subtitle }}
</h6>
</mat-card-content>
</mat-card>
</div>
}
</div>

View File

@@ -0,0 +1,62 @@
import { Component } from '@angular/core';
import { MaterialModule } from '../../../material.module';
interface topcards {
id: number;
img: string;
color: string;
title: string;
subtitle: string;
}
@Component({
selector: 'app-top-cards',
imports: [MaterialModule],
templateUrl: './top-cards.component.html',
})
export class AppTopCardsComponent {
topcards: topcards[] = [
{
id: 1,
color: 'primary',
img: '/assets/images/svgs/icon-user-male.svg',
title: 'Employees',
subtitle: '96',
},
{
id: 2,
color: 'warning',
img: '/assets/images/svgs/icon-briefcase.svg',
title: 'Clients',
subtitle: '3,650',
},
{
id: 3,
color: 'secondary',
img: '/assets/images/svgs/icon-mailbox.svg',
title: 'Projects',
subtitle: '356',
},
{
id: 4,
color: 'error',
img: '/assets/images/svgs/icon-favorites.svg',
title: 'Events',
subtitle: '696',
},
{
id: 5,
color: 'success',
img: '/assets/images/svgs/icon-speech-bubble.svg',
title: 'Payroll',
subtitle: '$96k',
},
{
id: 6,
color: 'secondary',
img: '/assets/images/svgs/icon-connect.svg',
title: 'Reports',
subtitle: '59',
},
];
}

View File

@@ -0,0 +1,109 @@
<mat-card class="cardWithShadow">
<mat-card-header class="d-flex">
<div class="m-r-auto">
<mat-card-title>Top Projects</mat-card-title>
<mat-card-subtitle>Best Products</mat-card-subtitle>
</div>
<mat-form-field class="theme-select" appearance="outline">
<mat-select value="mar">
@for(month of months; track month.viewValue) {
<mat-option [value]="month.value">
{{ month.viewValue }}
</mat-option>
}
</mat-select>
</mat-form-field>
</mat-card-header>
<mat-card-content>
<div class="table-responsive">
<table mat-table [dataSource]="dataSource" class="w-100">
<!-- Position Column -->
<ng-container matColumnDef="assigned">
<th mat-header-cell *matHeaderCellDef class="f-w-600 f-s-14">
Assigned
</th>
<td mat-cell *matCellDef="let element">
<div class="d-flex align-items-center">
<img
[src]="element.imagePath"
alt="users"
width="40"
class="rounded-circle"
/>
<div class="m-l-16">
<h6 class="f-s-14 f-w-600">
{{ element.uname }}
</h6>
<span class="f-w-400 f-s-12">
{{ element.position }}
</span>
</div>
</div>
</td>
</ng-container>
<!-- Name Column -->
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef class="f-w-600 f-s-14">Name</th>
<td mat-cell *matCellDef="let element">
{{ element.productName }}
</td>
</ng-container>
<!-- Weight Column -->
<ng-container matColumnDef="priority">
<th mat-header-cell *matHeaderCellDef class="f-w-600 f-s-14">
Priority
</th>
<td mat-cell *matCellDef="let element">
@if(element.priority == 'low') {
<span
class="bg-light-secondary text-secondary rounded f-w-600 p-x-6 p-y-4 f-s-12"
>
{{ element.priority | titlecase }}
</span>
} @if(element.priority == 'medium') {
<span
class="bg-light-primary text-primary rounded f-w-600 p-x-6 p-y-4 f-s-12"
>
{{ element.priority | titlecase }}
</span>
} @if(element.priority == 'high') {
<span
class="bg-light-warning text-warning rounded f-w-600 p-x-6 p-y-4 f-s-12"
>
{{ element.priority | titlecase }}
</span>
} @if(element.priority == 'critical') {
<span
class="bg-light-error text-error rounded f-w-600 p-x-6 p-y-4 f-s-12"
>
{{ element.priority | titlecase }}
</span>
} @if(element.priority == 'moderate') {
<span
class="bg-light-success text-success rounded f-w-600 p-x-6 p-y-4 f-s-12"
>
{{ element.priority | titlecase }}
</span>
}
</td>
</ng-container>
<!-- Symbol Column -->
<ng-container matColumnDef="budget">
<th mat-header-cell *matHeaderCellDef class="f-w-600 f-s-14">
Budget
</th>
<td mat-cell *matCellDef="let element">
${{ element.budget }}k
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
</table>
</div>
</mat-card-content>
</mat-card>

View File

@@ -0,0 +1,73 @@
import { Component } from '@angular/core';
import { MaterialModule } from '../../../material.module';
import { CommonModule } from '@angular/common';
export interface productsData {
id: number;
imagePath: string;
uname: string;
position: string;
productName: string;
budget: number;
priority: string;
}
const ELEMENT_DATA: productsData[] = [
{
id: 1,
imagePath: 'assets/images/profile/user-1.jpg',
uname: 'Sunil Joshi',
position: 'Web Designer',
productName: 'Elite Admin',
budget: 3.9,
priority: 'low',
},
{
id: 2,
imagePath: 'assets/images/profile/user-2.jpg',
uname: 'Andrew McDownland',
position: 'Project Manager',
productName: 'Real Homes Theme',
budget: 24.5,
priority: 'medium',
},
{
id: 3,
imagePath: 'assets/images/profile/user-3.jpg',
uname: 'Christopher Jamil',
position: 'Project Manager',
productName: 'MedicalPro Theme',
budget: 12.8,
priority: 'high',
},
{
id: 4,
imagePath: 'assets/images/profile/user-4.jpg',
uname: 'Nirav Joshi',
position: 'Frontend Engineer',
productName: 'Hosting Press HTML',
budget: 2.4,
priority: 'critical',
},
];
interface month {
value: string;
viewValue: string;
}
@Component({
selector: 'app-top-projects',
imports: [MaterialModule, CommonModule],
templateUrl: './top-projects.component.html',
})
export class AppTopProjectsComponent {
displayedColumns: string[] = ['assigned', 'name', 'priority', 'budget'];
dataSource = ELEMENT_DATA;
months: month[] = [
{ value: 'mar', viewValue: 'March 2025' },
{ value: 'apr', viewValue: 'April 2025' },
{ value: 'june', viewValue: 'June 2025' },
];
}

View File

@@ -0,0 +1,44 @@
<mat-card class="cardWithShadow">
<mat-card-content class="p-y-30">
<mat-card-title>Weekly Stats</mat-card-title>
<mat-card-subtitle class="m-b-24">Average sales</mat-card-subtitle>
<!-- ---------------------------- -->
<!-- charts here -->
<!-- ---------------------------- -->
<apx-chart
[series]="weeklyCart.series"
[plotOptions]="weeklyCart.plotOptions"
[chart]="weeklyCart.chart"
[tooltip]="weeklyCart.tooltip"
[fill]="weeklyCart.fill"
[stroke]="weeklyCart.stroke"
></apx-chart>
@for(stat of stats; track stat.color) {
<div class="m-t-32">
<div class="d-flex align-items-center">
<span
class="text-{{ stat.color }} bg-light-{{
stat.color
}} rounded icon-40 d-flex align-items-center justify-content-center"
>
<i-tabler name="grid-dots" class="icon-20 d-flex"></i-tabler>
</span>
<div class="m-l-16 m-r-auto">
<h6 class="f-s-16 f-w-600">{{ stat.title }}</h6>
<span class="f-s-14 f-w-400">{{ stat.subtitle }}</span>
</div>
<span
class="bg-light-{{ stat.color }} text-{{
stat.color
}} rounded f-w-600 p-x-6 p-y-4 f-s-14"
>
+{{ stat.percent }}
</span>
</div>
</div>
}
</mat-card-content>
</mat-card>

View File

@@ -0,0 +1,110 @@
import { Component, ViewChild } from '@angular/core';
import {
ApexChart,
ChartComponent,
ApexTooltip,
ApexAxisChartSeries,
ApexPlotOptions,
ApexFill,
ApexStroke,
NgApexchartsModule,
} from 'ng-apexcharts';
import { MaterialModule } from '../../../material.module';
import { TablerIconsModule } from 'angular-tabler-icons';
export interface weeklyCart {
series: ApexAxisChartSeries;
chart: ApexChart;
plotOptions: ApexPlotOptions;
tooltip: ApexTooltip;
fill: ApexFill;
stroke: ApexStroke;
}
interface stats {
id: number;
color: string;
title: string;
subtitle: string;
percent: string;
}
@Component({
selector: 'app-weekly-stats',
imports: [NgApexchartsModule, MaterialModule, TablerIconsModule],
templateUrl: './weekly-stats.component.html',
})
export class AppWeeklyStatsComponent {
@ViewChild('chart') chart: ChartComponent = Object.create(null);
public weeklyCart!: Partial<weeklyCart> | any;
constructor() {
this.weeklyCart = {
series: [
{
name: 'Weekly Stats',
color: '#5D87FF',
data: [5, 15, 5, 10, 5],
},
],
chart: {
type: 'area',
fontFamily: "'Plus Jakarta Sans', sans-serif;",
foreColor: '#adb0bb',
toolbar: {
show: false,
},
height: 130,
sparkline: {
enabled: true,
},
group: 'sparklines',
},
stroke: {
curve: 'smooth',
width: 2,
},
fill: {
type: 'gradient',
gradient: {
shadeIntensity: 0,
inverseColors: false,
opacityFrom: 0.45,
opacityTo: 0,
stops: [20, 180],
},
},
markers: {
size: 0,
},
tooltip: {
theme: 'dark',
},
};
}
stats: stats[] = [
{
id: 1,
color: 'primary',
title: 'Top Sales',
subtitle: 'Johnathan Doe',
percent: '68',
},
{
id: 2,
color: 'success',
title: 'Best Seller',
subtitle: 'Footware',
percent: '45',
},
{
id: 3,
color: 'error',
title: 'Most Commented',
subtitle: 'Fashionware',
percent: '14',
},
];
}

View File

@@ -0,0 +1,55 @@
<mat-card class="cardWithShadow">
<mat-card-header>
<mat-card-title>Yearly Breakup</mat-card-title>
</mat-card-header>
<mat-card-content>
<div class="row">
<div class="col-7">
<h4 class="f-s-24">$36,358</h4>
<div class="d-flex align-items-center m-t-16">
<button
mat-mini-fab
class="bg-light-success text-success shadow-none icon-27 d-flex align-items-center justify-content-center"
>
<i-tabler name="arrow-up-right" class="icon-20 d-flex"></i-tabler>
</button>
<div class="f-s-14 f-w-600 m-l-12">+9%</div>
<div class="f-s-14 f-w-400 m-l-4">last year</div>
</div>
<div class="d-flex align-items-center m-t-32">
<div class="d-flex align-items-center">
<i-tabler
name="circle-filled"
class="text-primary icon-12 d-flex"
></i-tabler>
<div class="f-s-14 f-w-400 m-l-12">2025</div>
</div>
<div class="d-flex align-items-center m-l-16">
<i-tabler
name="circle-filled"
class="text-light-primary icon-12 d-flex"
></i-tabler>
<div class="f-s-14 f-w-400 m-l-12">2024</div>
</div>
</div>
</div>
<div class="col-5">
<!-- ---------------------------- -->
<!-- charts here -->
<!-- ---------------------------- -->
<apx-chart
[series]="yearlyChart.series"
[dataLabels]="yearlyChart.dataLabels"
[chart]="yearlyChart.chart"
[legend]="yearlyChart.legend"
[colors]="yearlyChart.colors"
[stroke]="yearlyChart.stroke"
[tooltip]="yearlyChart.tooltip"
[plotOptions]="yearlyChart.plotOptions"
[responsive]="yearlyChart.responsive"
></apx-chart>
</div>
</div>
</mat-card-content>
</mat-card>

View File

@@ -0,0 +1,85 @@
import { Component, ViewChild } from '@angular/core';
import {
ApexChart,
ChartComponent,
ApexDataLabels,
ApexLegend,
ApexStroke,
ApexTooltip,
ApexAxisChartSeries,
ApexPlotOptions,
ApexResponsive,
NgApexchartsModule,
} from 'ng-apexcharts';
import { MaterialModule } from '../../../material.module';
import { TablerIconsModule } from 'angular-tabler-icons';
export interface yearlyChart {
series: ApexAxisChartSeries;
chart: ApexChart;
dataLabels: ApexDataLabels;
plotOptions: ApexPlotOptions;
tooltip: ApexTooltip;
stroke: ApexStroke;
legend: ApexLegend;
responsive: ApexResponsive;
}
@Component({
selector: 'app-yearly-breakup',
imports: [MaterialModule, NgApexchartsModule, TablerIconsModule],
templateUrl: './yearly-breakup.component.html',
})
export class AppYearlyBreakupComponent {
@ViewChild('chart') chart: ChartComponent = Object.create(null);
public yearlyChart!: Partial<yearlyChart> | any;
constructor() {
this.yearlyChart = {
series: [38, 40, 25],
chart: {
type: 'donut',
fontFamily: "'Plus Jakarta Sans', sans-serif;",
foreColor: '#adb0bb',
toolbar: {
show: false,
},
height: 130,
},
colors: ['#5D87FF', '#ECF2FF', '#F9F9FD'],
plotOptions: {
pie: {
startAngle: 0,
endAngle: 360,
donut: {
size: '75%',
background: 'transparent',
},
},
},
stroke: {
show: false,
},
dataLabels: {
enabled: false,
},
legend: {
show: false,
},
responsive: [
{
breakpoint: 991,
options: {
chart: {
width: 120,
},
},
},
],
tooltip: {
enabled: false,
},
};
}
}

View File

@@ -0,0 +1,41 @@
<mat-card class="cardWithShadow overflow-hidden">
<mat-card-header class="d-flex align-items-center">
<mat-card-title>Monthly Earnings</mat-card-title>
<div class="m-l-auto">
<span
class="bg-light-primary rounded icon-48 d-flex align-items-center justify-content-center"
>
<img src="assets/images/svgs/icon-master-card-2.svg" alt="icon" />
</span>
</div>
</mat-card-header>
<mat-card-content>
<div class="d-flex align-items-center m-b-24">
<h4 class="f-s-24">$6,820</h4>
<div class="d-flex align-items-center m-l-12">
<button
mat-mini-fab
class="bg-light-success text-success shadow-none icon-20"
>
<i-tabler name="arrow-up-left" class="icon-14 d-flex"></i-tabler>
</button>
<div class="f-s-14 f-w-600 m-l-12">+9%</div>
</div>
</div>
</mat-card-content>
<!-- ---------------------------- -->
<!-- charts here -->
<!-- ---------------------------- -->
<apx-chart
[series]="monthlytwoChart.series"
[dataLabels]="monthlytwoChart.dataLabels"
[chart]="monthlytwoChart.chart"
[legend]="monthlytwoChart.legend"
[colors]="monthlytwoChart.colors"
[stroke]="monthlytwoChart.stroke"
[tooltip]="monthlytwoChart.tooltip"
[plotOptions]="monthlytwoChart.plotOptions"
[responsive]="monthlytwoChart.responsive"
></apx-chart>
</mat-card>

View File

@@ -0,0 +1,79 @@
import { Component, ViewChild } from '@angular/core';
import {
ApexChart,
ChartComponent,
ApexDataLabels,
ApexLegend,
ApexStroke,
ApexTooltip,
ApexAxisChartSeries,
ApexPlotOptions,
ApexResponsive,
NgApexchartsModule,
} from 'ng-apexcharts';
import { MaterialModule } from '../../../material.module';
import { TablerIconsModule } from 'angular-tabler-icons';
export interface monthlytwoChart {
series: ApexAxisChartSeries;
chart: ApexChart;
dataLabels: ApexDataLabels;
plotOptions: ApexPlotOptions;
tooltip: ApexTooltip;
stroke: ApexStroke;
legend: ApexLegend;
responsive: ApexResponsive;
}
@Component({
selector: 'app-monthly-earnings-two',
imports: [NgApexchartsModule, MaterialModule, TablerIconsModule],
templateUrl: './monthly-earnings.component.html',
})
export class AppMonthlyEarningsTwoComponent {
@ViewChild('chart') chart: ChartComponent = Object.create(null);
public monthlytwoChart!: Partial<monthlytwoChart> | any;
constructor() {
this.monthlytwoChart = {
series: [
{
name: '',
color: '#5D87FF',
data: [25, 66, 20, 40, 12, 58, 20],
},
],
chart: {
type: 'area',
fontFamily: "'Plus Jakarta Sans', sans-serif;",
foreColor: '#adb0bb',
toolbar: {
show: false,
},
height: 80,
sparkline: {
enabled: true,
},
group: 'sparklines',
},
stroke: {
curve: 'smooth',
width: 2,
},
fill: {
colors: ['#E8F7FF'],
type: 'solid',
},
markers: {
size: 0,
},
tooltip: {
theme: 'dark',
x: {
show: false,
},
},
};
}
}

View File

@@ -0,0 +1,32 @@
<mat-card class="cardWithShadow">
<mat-card-content class="p-y-30">
<mat-card-title>Payment Gateways</mat-card-title>
<mat-card-subtitle class="f-s-14 f-w-400 p-b-16"
>Platform For Income</mat-card-subtitle
>
@for(stat of stats; track stat.color) {
<div class="m-t-32">
<div class="d-flex align-items-center m-b-24">
<span
class="bg-light-{{
stat.color
}} rounded icon-40 d-flex align-items-center justify-content-center"
>
<img [src]="stat.img" alt="icon" />
</span>
<div class="m-l-16 m-r-auto">
<h6 class="f-s-16 f-w-600">{{ stat.title }}</h6>
<span class="f-s-14">{{ stat.subtitle }}</span>
</div>
<span class="f-w-600 f-s-14"> +${{ stat.percent }} </span>
</div>
</div>
}
<button mat-stroked-button color="primary" class="w-100 m-t-8">
View all Transctions
</button>
</mat-card-content>
</mat-card>

View File

@@ -0,0 +1,53 @@
import { Component } from '@angular/core';
import { MaterialModule } from '../../../material.module';
interface stats {
id: number;
color: string;
title: string;
subtitle: string;
img: string;
percent: string;
}
@Component({
selector: 'app-payment-gateways',
imports: [MaterialModule],
templateUrl: './payment-gateways.component.html',
})
export class AppPaymentGatewaysComponent {
stats: stats[] = [
{
id: 1,
color: 'primary',
title: 'Paypal',
subtitle: 'Big Brands',
img: 'assets/images/svgs/icon-paypal.svg',
percent: '6235',
},
{
id: 2,
color: 'success',
title: 'Wallet',
subtitle: 'Bill payment',
img: 'assets/images/svgs/icon-office-bag.svg',
percent: '345',
},
{
id: 3,
color: 'warning',
title: 'Credit Card',
subtitle: 'Money reversed',
img: 'assets/images/svgs/icon-master-card.svg',
percent: '2235',
},
{
id: 4,
color: 'error',
title: 'Refund',
subtitle: 'Bill Payment',
img: 'assets/images/svgs/icon-pie.svg',
percent: '32',
},
];
}

View File

@@ -0,0 +1,24 @@
<mat-card class="cardWithShadow">
<mat-card-content>
<span
class="bg-light-primary rounded icon-40 d-flex align-items-center justify-content-center"
>
<img src="assets/images/svgs/icon-paypal.svg" alt="paypal" />
</span>
<mat-card-subtitle class="f-s-14 f-w-400 p-b-4 m-t-24"
>Payments</mat-card-subtitle
>
<h5 class="f-s-21 m-t-4 f-w-600">$678,298</h5>
<div class="d-flex align-items-center m-t-16">
<button
mat-mini-fab
class="bg-light-success text-success shadow-none icon-27 d-flex align-items-center justify-content-center"
>
<i-tabler name="arrow-up-left" class="icon-20 d-flex"></i-tabler>
</button>
<div class="f-s-14 f-w-600 m-l-12">+9%</div>
</div>
</mat-card-content>
</mat-card>

View File

@@ -0,0 +1,10 @@
import { Component } from '@angular/core';
import { MaterialModule } from '../../../material.module';
import { TablerIconsModule } from 'angular-tabler-icons';
@Component({
selector: 'app-payments',
imports: [MaterialModule, TablerIconsModule],
templateUrl: './payments.component.html',
})
export class AppPaymentsComponent {}

View File

@@ -0,0 +1,18 @@
<mat-card class="cardWithShadow">
<mat-card-content class="p-t-32 p-b-32 m-b-20">
<mat-card-subtitle class="f-s-14 f-w-400 p-b-4">Projects</mat-card-subtitle>
<h5 class="f-s-21 m-t-4 f-w-600">78,298</h5>
</mat-card-content>
<!-- ---------------------------- -->
<!-- charts here -->
<!-- ---------------------------- -->
<apx-chart
[series]="productChart.series"
[chart]="productChart.chart"
[plotOptions]="productChart.plotOptions"
[tooltip]="productChart.tooltip"
[stroke]="productChart.stroke"
[markers]="productChart.markers"
[fill]="productChart.fill"
></apx-chart>
</mat-card>

View File

@@ -0,0 +1,77 @@
import { Component, ViewChild } from '@angular/core';
import {
ApexChart,
ChartComponent,
ApexStroke,
ApexTooltip,
ApexAxisChartSeries,
ApexPlotOptions,
ApexFill,
ApexMarkers,
NgApexchartsModule,
} from 'ng-apexcharts';
import { MaterialModule } from '../../../material.module';
export interface productChart {
series: ApexAxisChartSeries;
chart: ApexChart;
plotOptions: ApexPlotOptions;
tooltip: ApexTooltip;
stroke: ApexStroke;
fill: ApexFill;
markers: ApexMarkers;
}
@Component({
selector: 'app-products',
imports: [NgApexchartsModule, MaterialModule],
templateUrl: './products.component.html',
})
export class AppProductsComponent {
@ViewChild('chart') chart: ChartComponent = Object.create(null);
public productChart!: Partial<productChart> | any;
constructor() {
this.productChart = {
series: [
{
name: '',
color: '#13DEB9',
data: [30, 25, 35, 20, 30, 40],
},
],
chart: {
type: 'area',
fontFamily: "'Plus Jakarta Sans', sans-serif;",
foreColor: '#adb0bb',
toolbar: {
show: false,
},
height: 85,
sparkline: {
enabled: true,
},
group: 'sparklines',
},
stroke: {
curve: 'smooth',
width: 2,
},
fill: {
colors: ['#E6FFFA'],
type: 'solid',
opacity: 0.05,
},
markers: {
size: 0,
},
tooltip: {
theme: 'dark',
x: {
show: false,
},
},
};
}
}

View File

@@ -0,0 +1,28 @@
<mat-card class="cardWithShadow">
<mat-card-content>
<mat-card-title>Recent Transactions</mat-card-title>
<div class="timeline m-t-24">
@for(stat of stats; track stat.title) {
<div class="timeline-item d-flex overflow-hidden">
<div class="time text-right f-s-14">{{ stat.time }}</div>
<div class="point d-flex align-items-center">
<span class="timeline-badge border-{{ stat.color }} m-y-8"></span>
<span class="timline-border d-block"></span>
</div>
<div class="desc">
@if(stat.subtext) {
<span class="f-s-14 lh-20">{{ stat.subtext }}</span>
} @if(stat.title) {
<span class="f-s-14 lh-20 f-w-600 d-block">{{ stat.title }}</span>
} @if(stat.link) {
<a href="#" class="text-primary text-decoration-none f-s-14 f-w-400"
>#ML-3467</a
>
}
</div>
</div>
}
</div>
</mat-card-content>
</mat-card>

View File

@@ -0,0 +1,61 @@
import { Component } from '@angular/core';
import { NgApexchartsModule } from 'ng-apexcharts';
import { MaterialModule } from '../../../material.module';
interface stats {
id: number;
time: string;
color: string;
title?: string;
subtext?: string;
link?: string;
}
@Component({
selector: 'app-recent-transactions',
imports: [NgApexchartsModule, MaterialModule],
templateUrl: './recent-transactions.component.html',
})
export class AppRecentTransactionsComponent {
stats: stats[] = [
{
id: 1,
time: '09.30 am',
color: 'primary',
subtext: 'Payment received from John Doe of $385.90',
},
{
id: 2,
time: '10.30 am',
color: 'accent',
title: 'New sale recorded',
link: '#ML-3467',
},
{
id: 3,
time: '12.30 pm',
color: 'success',
subtext: 'Payment was made of $64.95 to Michael',
},
{
id: 4,
time: '12.30 pm',
color: 'warning',
title: 'New sale recorded',
link: '#ML-3467',
},
{
id: 5,
time: '12.30 pm',
color: 'error',
title: 'New arrival recorded',
link: '#ML-3467',
},
{
id: 6,
time: '12.30 pm',
color: 'success',
subtext: 'Payment Done',
},
];
}

View File

@@ -0,0 +1,46 @@
<mat-card class="cardWithShadow">
<mat-card-header>
<mat-card-title>Revenue Updates</mat-card-title>
<mat-card-subtitle class="f-s-14 f-w-400"
>Overview of Profit</mat-card-subtitle
>
</mat-card-header>
<mat-card-content>
<div class="d-flex align-items-center">
<div class="d-flex align-items-center">
<i-tabler
name="circle-filled"
class="text-primary icon-12 d-flex"
></i-tabler>
<div class="m-l-12 d-flex">
<span class="f-s-12">Footware</span>
</div>
</div>
<div class="d-flex m-l-16 align-items-center">
<i-tabler
name="circle-filled"
class="text-secondary icon-12 d-flex"
></i-tabler>
<div class="m-l-12 d-flex">
<span class="f-s-12">Fashionware</span>
</div>
</div>
</div>
<!-- ---------------------------- -->
<!-- charts here -->
<!-- ---------------------------- -->
<apx-chart
[series]="revenuetwoChart.series"
[dataLabels]="revenuetwoChart.dataLabels"
[chart]="revenuetwoChart.chart"
[legend]="revenuetwoChart.legend"
[xaxis]="revenuetwoChart.xaxis"
[yaxis]="revenuetwoChart.yaxis"
[grid]="revenuetwoChart.grid"
[stroke]="revenuetwoChart.stroke"
[tooltip]="revenuetwoChart.tooltip"
[plotOptions]="revenuetwoChart.plotOptions"
></apx-chart>
</mat-card-content>
</mat-card>

View File

@@ -0,0 +1,108 @@
import { Component, ViewChild } from '@angular/core';
import {
ApexChart,
ChartComponent,
ApexDataLabels,
ApexLegend,
ApexStroke,
ApexTooltip,
ApexAxisChartSeries,
ApexXAxis,
ApexYAxis,
ApexGrid,
ApexPlotOptions,
ApexFill,
ApexMarkers,
NgApexchartsModule,
} from 'ng-apexcharts';
import { MaterialModule } from '../../../material.module';
import { TablerIconsModule } from 'angular-tabler-icons';
export interface revenuetwoChart {
series: ApexAxisChartSeries;
chart: ApexChart;
dataLabels: ApexDataLabels;
plotOptions: ApexPlotOptions;
yaxis: ApexYAxis;
xaxis: ApexXAxis;
fill: ApexFill;
tooltip: ApexTooltip;
stroke: ApexStroke;
legend: ApexLegend;
grid: ApexGrid;
marker: ApexMarkers;
}
@Component({
selector: 'app-revenue-updates-two',
imports: [MaterialModule, NgApexchartsModule, TablerIconsModule],
templateUrl: './revenue-updates.component.html',
})
export class AppRevenueUpdatesTwoComponent {
@ViewChild('chart') chart: ChartComponent = Object.create(null);
public revenuetwoChart!: Partial<revenuetwoChart> | any;
constructor() {
this.revenuetwoChart = {
series: [
{
name: 'Footware',
data: [2.5, 3.7, 3.2, 2.6, 1.9],
color: '#5D87FF',
},
{
name: 'Fashionware',
data: [-2.8, -1.1, -3.0, -1.5, -1.9],
color: '#49BEFF',
},
],
chart: {
type: 'bar',
fontFamily: "'Plus Jakarta Sans', sans-serif;",
foreColor: '#adb0bb',
toolbar: {
show: false,
},
height: 320,
offsetX: -20,
stacked: true,
},
plotOptions: {
bar: {
horizontal: false,
columnWidth: '20%',
borderRadius: [6],
borderRadiusApplication: 'end',
borderRadiusWhenStacked: 'all',
},
},
stroke: {
show: false,
},
dataLabels: {
enabled: false,
},
legend: {
show: false,
},
grid: {
show: false,
},
yaxis: {
min: -5,
max: 5,
tickAmount: 4,
},
xaxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May'],
},
tooltip: {
theme: 'dark',
fillSeriesColor: false,
},
};
}
}

View File

@@ -0,0 +1,49 @@
<mat-card class="cardWithShadow">
<mat-card-header>
<mat-card-title>Sales Overview</mat-card-title>
<mat-card-subtitle class="f-s-14 f-w-400">Every month </mat-card-subtitle>
</mat-card-header>
<mat-card-content>
<!-- ---------------------------- -->
<!-- charts here -->
<!-- ---------------------------- -->
<apx-chart
[series]="salesoverviewChart.series"
[plotOptions]="salesoverviewChart.plotOptions"
[dataLabels]="salesoverviewChart.dataLabels"
[chart]="salesoverviewChart.chart"
[legend]="salesoverviewChart.legend"
[colors]="salesoverviewChart.colors"
[tooltip]="salesoverviewChart.tooltip"
[labels]="salesoverviewChart.labels"
[stroke]="salesoverviewChart.stroke"
></apx-chart>
<div class="d-flex align-items-center justify-content-between m-t-30">
<div class="d-flex align-items-center">
<span
class="text-primary bg-light-primary rounded icon-40 d-flex align-items-center justify-content-center"
>
<i-tabler name="grid-dots" class="icon-20 d-flex"></i-tabler>
</span>
<div class="m-l-12">
<h5 class="f-s-16 f-w-600 m-t-4">$23,450</h5>
<span class="f-s-14">Profit</span>
</div>
</div>
<div class="d-flex align-items-center">
<span
class="text-secondary bg-light-secondary rounded icon-40 d-flex align-items-center justify-content-center"
>
<i-tabler name="grid-dots" class="icon-20 d-flex"></i-tabler>
</span>
<div class="m-l-12">
<h5 class="f-s-16 f-w-600 m-t-4">$23,450</h5>
<span class="f-s-14">Expance</span>
</div>
</div>
</div>
</mat-card-content>
</mat-card>

View File

@@ -0,0 +1,90 @@
import { Component, ViewChild } from '@angular/core';
import {
ApexChart,
ChartComponent,
ApexDataLabels,
ApexLegend,
ApexTooltip,
ApexAxisChartSeries,
ApexPlotOptions,
ApexStroke,
NgApexchartsModule,
} from 'ng-apexcharts';
import { MaterialModule } from '../../../material.module';
import { TablerIconsModule } from 'angular-tabler-icons';
export interface salesoverviewChart {
series: ApexAxisChartSeries;
chart: ApexChart;
dataLabels: ApexDataLabels;
plotOptions: ApexPlotOptions;
tooltip: ApexTooltip;
legend: ApexLegend;
stroke: ApexStroke;
}
@Component({
selector: 'app-sales-overview',
imports: [MaterialModule, NgApexchartsModule, TablerIconsModule],
templateUrl: './sales-overview.component.html',
})
export class AppSalesOverviewComponent {
@ViewChild('chart') chart: ChartComponent = Object.create(null);
public salesoverviewChart!: Partial<salesoverviewChart> | any;
constructor() {
this.salesoverviewChart = {
series: [55, 55, 55],
chart: {
type: 'donut',
fontFamily: "'Plus Jakarta Sans', sans-serif;",
toolbar: {
show: false,
},
height: 275,
},
labels: ['Profit', 'Revenue', 'Expance'],
colors: ['#5D87FF', '#ECF2FF', '#49BEFF'],
plotOptions: {
pie: {
donut: {
size: '89%',
background: 'transparent',
labels: {
show: true,
name: {
show: true,
offsetY: 7,
},
value: {
show: false,
},
total: {
show: true,
color: '#2A3547',
fontSize: '20px',
fontWeight: '600',
label: '$500,458',
},
},
},
},
},
dataLabels: {
enabled: false,
},
stroke: {
show: false,
},
legend: {
show: false,
},
tooltip: {
theme: 'dark',
fillSeriesColor: false,
},
};
}
}

View File

@@ -0,0 +1,24 @@
<mat-card class="cardWithShadow">
<mat-card-content class="p-t-32">
<span
class="bg-light-error rounded icon-40 d-flex align-items-center justify-content-center"
>
<img src="assets/images/svgs/icon-office-bag-2.svg" alt="paypal" />
</span>
<mat-card-subtitle class="f-s-14 f-w-400 p-b-4 m-t-20"
>Sales Profit</mat-card-subtitle
>
<h5 class="f-s-21 m-t-4 f-w-600">$456,120</h5>
<div class="d-flex align-items-center m-t-20">
<button
mat-mini-fab
class="bg-light-error text-error shadow-none icon-20"
>
<i-tabler name="arrow-down-right" class="icon-14 d-flex"></i-tabler>
</button>
<div class="f-s-14 f-w-400 f-w-600 m-l-12">+9%</div>
</div>
</mat-card-content>
</mat-card>

View File

@@ -0,0 +1,10 @@
import { Component } from '@angular/core';
import { MaterialModule } from '../../../material.module';
import { TablerIconsModule } from 'angular-tabler-icons';
@Component({
selector: 'app-sales-profit',
imports: [MaterialModule, TablerIconsModule],
templateUrl: './sales-profit.component.html',
})
export class AppSalesProfitComponent {}

View File

@@ -0,0 +1,104 @@
<mat-card class="cardWithShadow">
<mat-card-header class="d-flex">
<div class="m-r-auto">
<mat-card-title>Top Projects</mat-card-title>
<mat-card-subtitle>Best Products</mat-card-subtitle>
</div>
<mat-form-field class="theme-select" appearance="outline">
<mat-select value="mar">
@for(month of months; track month.value) {
<mat-option [value]="month.value">
{{ month.viewValue }}
</mat-option>
}
</mat-select>
</mat-form-field>
</mat-card-header>
<mat-card-content>
<div class="table-responsive">
<table mat-table [dataSource]="dataSource" class="w-100">
<!-- Position Column -->
<ng-container matColumnDef="product">
<th mat-header-cell *matHeaderCellDef class="f-w-600 f-s-14 p-l-0">
Product
</th>
<td mat-cell *matCellDef="let element" class="p-l-0">
<div class="d-flex align-items-center">
<img
[src]="element.imagePath"
alt="users"
width="48"
class="rounded"
/>
<div class="m-l-16">
<h6 class="f-s-14 f-w-600">
{{ element.pname }}
</h6>
<span class="f-s-14 f-w-400 f-s-12">
{{ element.category }}
</span>
</div>
</div>
</td>
</ng-container>
<!-- Name Column -->
<ng-container matColumnDef="progress">
<th mat-header-cell *matHeaderCellDef class="f-w-600 f-s-14">
Progress
</th>
<td mat-cell *matCellDef="let element" class="f-s-14 f-w-400">
{{ element.progress }}%
</td>
</ng-container>
<!-- Weight Column -->
<ng-container matColumnDef="status">
<th mat-header-cell *matHeaderCellDef class="f-w-600 f-s-14">
Status
</th>
<td mat-cell *matCellDef="let element">
@if(element.status == 'low') {
<span
class="bg-light-success text-success rounded f-w-600 p-6 p-y-4 f-s-12"
>
{{ element.status | titlecase }}
</span>
} @if(element.status == 'medium') {
<span
class="bg-light-warning text-warning rounded f-w-600 p-6 p-y-4 f-s-12"
>
{{ element.status | titlecase }}
</span>
} @if(element.status == 'high') {
<span
class="bg-light-primary text-primary rounded f-w-600 p-6 p-y-4 f-s-12"
>
{{ element.status | titlecase }}
</span>
} @if(element.status == 'critical') {
<span
class="bg-light-error text-error rounded f-w-600 p-6 p-y-4 f-s-12"
>
{{ element.status | titlecase }}
</span>
}
</td>
</ng-container>
<!-- Symbol Column -->
<ng-container matColumnDef="sales">
<th mat-header-cell *matHeaderCellDef class="f-w-600 f-s-14">
Sales
</th>
<td mat-cell *matCellDef="let element" class="f-s-14 f-w-400">
${{ element.sales }}k
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
</table>
</div>
</mat-card-content>
</mat-card>

View File

@@ -0,0 +1,80 @@
import { Component } from '@angular/core';
import { NgApexchartsModule } from 'ng-apexcharts';
import { MaterialModule } from '../../../material.module';
import { TablerIconsModule } from 'angular-tabler-icons';
import { CommonModule } from '@angular/common';
export interface performanceData {
id: number;
imagePath: string;
pname: string;
category: string;
progress: number;
sales: number;
status: string;
}
const ELEMENT_DATA: performanceData[] = [
{
id: 1,
imagePath: 'assets/images/products/s6.jpg',
pname: 'Gaming Console',
category: 'Electronics',
progress: 78.5,
sales: 3.9,
status: 'low',
},
{
id: 2,
imagePath: 'assets/images/products/s9.jpg',
pname: 'Leather Purse',
category: 'Fashion',
progress: 58.6,
sales: 3.5,
status: 'medium',
},
{
id: 3,
imagePath: 'assets/images/products/s7.jpg',
pname: 'Red Velvate Dress',
category: 'Womens Fashion',
progress: 25,
sales: 3.8,
status: 'high',
},
{
id: 4,
imagePath: 'assets/images/products/s4.jpg',
pname: 'Headphone Boat',
category: 'Electronics',
progress: 96.3,
sales: 3.54,
status: 'critical',
},
];
interface month {
value: string;
viewValue: string;
}
@Component({
selector: 'app-top-projects',
imports: [
NgApexchartsModule,
MaterialModule,
TablerIconsModule,
CommonModule,
],
templateUrl: './top-projects.component.html',
})
export class AppTopProjectsComponent {
displayedColumns: string[] = ['product', 'progress', 'status', 'sales'];
dataSource = ELEMENT_DATA;
months: month[] = [
{ value: 'mar', viewValue: 'March 2025' },
{ value: 'apr', viewValue: 'April 2025' },
{ value: 'june', viewValue: 'June 2025' },
];
}

View File

@@ -0,0 +1,22 @@
<mat-card class="cardWithShadow">
<mat-card-content class="p-y-30">
<mat-card-subtitle class="p-b-4">Total Earning</mat-card-subtitle>
<h5 class="f-s-21 m-t-4 f-w-600 m-b-30">$78,298</h5>
<!-- ---------------------------- -->
<!-- charts here -->
<!-- ---------------------------- -->
<apx-chart
[series]="totalEarnChart.series"
[chart]="totalEarnChart.chart"
[plotOptions]="totalEarnChart.plotOptions"
[tooltip]="totalEarnChart.tooltip"
[stroke]="totalEarnChart.stroke"
[fill]="totalEarnChart.fill"
[colors]="totalEarnChart.colors"
[xaxis]="totalEarnChart.xaxis"
[yaxis]="totalEarnChart.yaxis"
[dataLabels]="totalEarnChart.dataLabels"
></apx-chart>
</mat-card-content>
</mat-card>

View File

@@ -0,0 +1,115 @@
import { Component, ViewChild } from '@angular/core';
import {
ApexChart,
ChartComponent,
ApexStroke,
ApexTooltip,
ApexAxisChartSeries,
ApexPlotOptions,
ApexFill,
ApexGrid,
ApexDataLabels,
ApexXAxis,
ApexYAxis,
NgApexchartsModule,
} from 'ng-apexcharts';
import { MaterialModule } from '../../../material.module';
export interface totalEarnChart {
series: ApexAxisChartSeries;
chart: ApexChart;
plotOptions: ApexPlotOptions;
tooltip: ApexTooltip;
stroke: ApexStroke;
fill: ApexFill;
grid: ApexGrid;
dataLabels: ApexDataLabels;
xaxis: ApexXAxis;
yaxis: ApexYAxis;
}
@Component({
selector: 'app-total-earnings',
imports: [NgApexchartsModule, MaterialModule],
templateUrl: './total-earnings.component.html',
})
export class AppTotalEarningsComponent {
@ViewChild('chart') chart: ChartComponent = Object.create(null);
public totalEarnChart!: Partial<totalEarnChart> | any;
constructor() {
this.totalEarnChart = {
series: [
{
name: '',
data: [4, 10, 9, 7, 9, 10, 11, 8, 10],
},
],
chart: {
type: 'bar',
fontFamily: "'Plus Jakarta Sans', sans-serif;",
foreColor: '#adb0bb',
toolbar: {
show: false,
},
height: 65,
resize: true,
barColor: '#fff',
sparkline: {
enabled: true,
},
},
colors: ['#49BEFF'],
grid: {
show: false,
},
plotOptions: {
bar: {
horizontal: false,
startingShape: 'flat',
endingShape: 'flat',
columnWidth: '60%',
barHeight: '20%',
borderRadius: 3,
},
},
dataLabels: {
enabled: false,
},
stroke: {
show: true,
width: 2.5,
colors: ['rgba(0,0,0,0.01)'],
},
xaxis: {
axisBorder: {
show: false,
},
axisTicks: {
show: false,
},
labels: {
show: false,
},
},
yaxis: {
labels: {
show: false,
},
},
axisBorder: {
show: false,
},
fill: {
opacity: 1,
},
tooltip: {
theme: 'dark',
x: {
show: false,
},
},
};
}
}

View File

@@ -0,0 +1,22 @@
<mat-card class="shadow-none bg-light-primary overflow-hidden">
<mat-card-content class="p-32 p-b-0">
<div class="row justify-content-between">
<div class="col-sm-6">
<mat-card-title>Welcome back Mathew!</mat-card-title>
<mat-card-subtitle class="f-s-14 f-w-400 m-t-16 lh-24 m-b-24"
>You have earned 54% more than last month which is great
thing.</mat-card-subtitle
>
<button mat-flat-button>Check</button>
</div>
<div class="col-sm-5">
<img
src="assets/images/backgrounds/welcome-bg2.png"
alt="welcome"
width="300"
class="welcome-img"
/>
</div>
</div>
</mat-card-content>
</mat-card>

View File

@@ -0,0 +1,9 @@
import { Component } from '@angular/core';
import { MaterialModule } from '../../../material.module';
@Component({
selector: 'app-welcome-card',
imports: [MaterialModule],
templateUrl: './welcome-card.component.html',
})
export class AppWelcomeCardComponent {}

View File

@@ -0,0 +1,50 @@
<mat-card class="cardWithShadow">
<mat-card-header>
<mat-card-title>Yearly Sales</mat-card-title>
<mat-card-subtitle>Every month</mat-card-subtitle>
</mat-card-header>
<mat-card-content>
<!-- ---------------------------- -->
<!-- charts here -->
<!-- ---------------------------- -->
<apx-chart
[series]="yearlysaleChart.series"
[plotOptions]="yearlysaleChart.plotOptions"
[dataLabels]="yearlysaleChart.dataLabels"
[chart]="yearlysaleChart.chart"
[legend]="yearlysaleChart.legend"
[colors]="yearlysaleChart.colors"
[tooltip]="yearlysaleChart.tooltip"
[xaxis]="yearlysaleChart.xaxis"
[yaxis]="yearlysaleChart.yaxis"
[grid]="yearlysaleChart.grid"
></apx-chart>
<div class="d-flex align-items-center justify-content-between m-t-24">
<div class="d-flex align-items-center">
<span
class="text-primary bg-light-primary rounded icon-40 d-flex align-items-center justify-content-center"
>
<i-tabler name="grid-dots" class="icon-20"></i-tabler>
</span>
<div class="m-l-12">
<span class="f-s-14">Salary</span>
<h5 class="f-s-16 f-w-600 m-t-4">$36,358</h5>
</div>
</div>
<div class="d-flex align-items-center">
<span
class="text-body-2 bg-light text-gray-100 rounded icon-40 d-flex align-items-center justify-content-center"
>
<i-tabler name="grid-dots" class="icon-20"></i-tabler>
</span>
<div class="m-l-12">
<span class="f-s-14">Expance</span>
<h5 class="f-s-16 f-w-600 m-t-4">$5,296</h5>
</div>
</div>
</div>
</mat-card-content>
</mat-card>

View File

@@ -0,0 +1,102 @@
import { Component, ViewChild } from '@angular/core';
import {
ApexChart,
ChartComponent,
ApexDataLabels,
ApexLegend,
ApexTooltip,
ApexAxisChartSeries,
ApexPlotOptions,
ApexGrid,
ApexXAxis,
ApexYAxis,
NgApexchartsModule,
} from 'ng-apexcharts';
import { MaterialModule } from '../../../material.module';
import { TablerIconsModule } from 'angular-tabler-icons';
export interface yearlysaleChart {
series: ApexAxisChartSeries;
chart: ApexChart;
dataLabels: ApexDataLabels;
plotOptions: ApexPlotOptions;
tooltip: ApexTooltip;
legend: ApexLegend;
grid: ApexGrid;
xaxis: ApexXAxis;
yaxis: ApexYAxis;
}
@Component({
selector: 'app-yearly-sales',
imports: [NgApexchartsModule, MaterialModule, TablerIconsModule],
templateUrl: './yearly-sales.component.html',
})
export class AppYearlySalesComponent {
@ViewChild('chart') chart: ChartComponent = Object.create(null);
public yearlysaleChart!: Partial<yearlysaleChart> | any;
constructor() {
this.yearlysaleChart = {
series: [
{
name: '',
data: [20, 15, 30, 25, 10, 15],
},
],
chart: {
type: 'bar',
fontFamily: "'Plus Jakarta Sans', sans-serif;",
foreColor: '#adb0bb',
toolbar: {
show: false,
},
height: 280,
},
colors: [
'#ECF2FF',
'#ECF2FF',
'#5D87FF',
'#ECF2FF',
'#ECF2FF',
'#ECF2FF',
],
plotOptions: {
bar: {
borderRadius: 4,
columnWidth: '45%',
distributed: true,
endingShape: 'rounded',
},
},
dataLabels: {
enabled: false,
},
legend: {
show: false,
},
grid: {
yaxis: {
lines: {
show: false,
},
},
},
xaxis: {
categories: [['Apr'], ['May'], ['June'], ['July'], ['Aug'], ['Sept']],
axisBorder: {
show: false,
},
},
yaxis: {
labels: {
show: false,
},
},
tooltip: {
theme: 'dark',
},
};
}
}

View File

@@ -0,0 +1,25 @@
export interface AppSettings {
dir: 'ltr' | 'rtl';
theme: string;
sidenavOpened: boolean;
sidenavCollapsed: boolean;
boxed: boolean;
horizontal: boolean;
activeTheme: string;
language: string;
cardBorder: boolean;
navPos: 'side' | 'top';
}
export const defaults: AppSettings = {
dir: 'ltr',
theme: 'light',
sidenavOpened: false,
sidenavCollapsed: false,
boxed: true,
horizontal: false,
cardBorder: false,
activeTheme: 'blue_theme',
language: 'en-us',
navPos: 'side',
};

View File

@@ -0,0 +1,16 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { TablerIconsModule } from 'angular-tabler-icons';
import * as TablerIcons from 'angular-tabler-icons/icons';
@NgModule({
declarations: [],
imports: [
TablerIconsModule.pick(TablerIcons),
CommonModule
],
exports: [TablerIconsModule]
})
export class IconModule { }

View File

@@ -0,0 +1,11 @@
<!-- ============================================================== -->
<!-- Only router without any element -->
<!-- ============================================================== -->
<mat-sidenav-container
[ngClass]="{
cardBorder: options.cardBorder,
}"
[dir]="options.dir!"
>
<router-outlet></router-outlet>
</mat-sidenav-container>

View File

@@ -0,0 +1,51 @@
import { Component } from '@angular/core';
import { CoreService } from 'src/app/services/core.service';
import { AppSettings } from 'src/app/config';
import { CommonModule } from '@angular/common';
import { RouterOutlet } from '@angular/router';
import { MaterialModule } from 'src/app/material.module';
@Component({
selector: 'app-blank',
templateUrl: './blank.component.html',
styleUrls: [],
imports: [RouterOutlet, MaterialModule, CommonModule],
})
export class BlankComponent {
private htmlElement!: HTMLHtmlElement;
options = this.settings.getOptions();
constructor(private settings: CoreService) {
this.htmlElement = document.querySelector('html')!;
// Initialize project theme with options
this.receiveOptions(this.options);
}
receiveOptions(options: AppSettings): void {
this.toggleDarkTheme(options);
this.toggleColorsTheme(options);
}
toggleDarkTheme(options: AppSettings) {
if (options.theme === 'dark') {
this.htmlElement.classList.add('dark-theme');
this.htmlElement.classList.remove('light-theme');
} else {
this.htmlElement.classList.remove('dark-theme');
this.htmlElement.classList.add('light-theme');
}
}
toggleColorsTheme(options: AppSettings) {
// Remove any existing theme class dynamically
this.htmlElement.classList.forEach((className) => {
if (className.endsWith('_theme')) {
this.htmlElement.classList.remove(className);
}
});
// Add the selected theme class
this.htmlElement.classList.add(options.activeTheme);
}
}

View File

@@ -0,0 +1,197 @@
<span [dir]="options.dir!">
<mat-sidenav-container class="mainWrapper" autosize autoFocus [ngClass]="{
'sidebarNav-mini':
options.sidenavCollapsed && options.navPos !== 'top' && !resView,
'sidebarNav-horizontal': options.horizontal,
cardBorder: options.cardBorder
}">
<!-- ============================================================== -->
<!-- Vertical Sidebar -->
<!-- ============================================================== -->
@if (!options.horizontal) {
<mat-sidenav #leftsidenav [mode]="isOver ? 'over' : 'side'" [opened]="
options.navPos === 'side' &&
options.sidenavOpened &&
!isOver &&
!resView
" (openedChange)="onSidenavOpenedChange($event)" (closedStart)="onSidenavClosedStart()" class="sidebarNav">
<div class="flex-layout">
<app-sidebar (toggleMobileNav)="sidenav.toggle()" [showToggle]="isOver"></app-sidebar>
<ng-scrollbar class="position-relative" style="height: 100%">
<mat-nav-list class="sidebar-list">
@for(item of navItems; track item) {
<app-nav-item [item]="item" (notify)="sidenav.toggle()" class="top-parent">
</app-nav-item>
}
</mat-nav-list>
</ng-scrollbar>
<div class="p-24 m-t-auto profile-bar">
<div class="bg-light-secondary d-flex align-items-center rounded p-16">
<img src="/assets/images/profile/user-1.jpg" class="rounded-circle" width="40" />
<div class="m-l-16">
<h4 class="f-w-600">Mathew</h4>
<span class="f-s-12">Designer</span>
</div>
<div class="m-l-auto">
<a mat-icon-button [routerLink]="['/authentication/login']" class="d-flex justify-content-center">
<i-tabler name="power" class="text-primary icon-18 d-flex"></i-tabler>
</a>
</div>
</div>
</div>
</div>
</mat-sidenav>
}
<!-- ============================================================== -->
<!-- horizontal Sidebar -->
<!-- ============================================================== -->
@if (resView) {
<mat-sidenav #leftsidenav [mode]="'over'" [opened]="options.sidenavOpened && !isTablet"
(openedChange)="onSidenavOpenedChange($event)" (closedStart)="onSidenavClosedStart()" class="sidebarNav">
<app-sidebar> </app-sidebar>
<ng-scrollbar class="position-relative" style="height: 100%">
<mat-nav-list class="sidebar-list">
@for(item of navItems; track item) {
<app-nav-item [item]="item" (notify)="sidenav.toggle()">
</app-nav-item>
}
</mat-nav-list>
</ng-scrollbar>
<div class="p-24 m-t-auto profile-bar">
<div class="bg-light-secondary d-flex align-items-center rounded p-16">
<img src="/assets/images/profile/user-1.jpg" class="rounded-circle" width="40" />
<div class="m-l-16">
<h4 class="f-w-600">Mathew</h4>
<span class="f-s-12">Designer</span>
</div>
<div class="m-l-auto">
<a mat-icon-button [routerLink]="['/authentication/login']" class="d-flex justify-content-center">
<i-tabler name="power" class="text-primary icon-18 d-flex"></i-tabler>
</a>
</div>
</div>
</div>
</mat-sidenav>
}
<!-- ============================================================== -->
<!-- Main Content -->
<!-- ============================================================== -->
<mat-sidenav-content class="contentWrapper" #content>
<!-- ============================================================== -->
<!-- VerticalHeader -->
<!-- ============================================================== -->
@if (!options.horizontal) {
<app-header [showToggle]="!isOver" (toggleCollapsed)="toggleCollapsed()" (toggleMobileNav)="sidenav.toggle()"
(toggleMobileFilterNav)="toggleFilterNav()" (optionsChange)="receiveOptions($event)"></app-header>
} @else {
<!-- horizontal header -->
<app-horizontal-header (toggleMobileNav)="sidenav.toggle()" (toggleMobileFilterNav)="toggleFilterNav()"
(optionsChange)="receiveOptions($event)"></app-horizontal-header>
} @if(options.horizontal) {
<app-horizontal-sidebar></app-horizontal-sidebar>
}
<main class="pageWrapper" [ngClass]="{
maxWidth: options.boxed
}">
<app-breadcrumb></app-breadcrumb>
<!-- ============================================================== -->
<!-- Outlet -->
<!-- ============================================================== -->
<router-outlet></router-outlet>
<div class="customizerBtn">
<button mat-fab class="bg-primary text-white" (click)="customizerRight.toggle()">
<mat-icon>settings</mat-icon>
</button>
</div>
</main>
<!-- ------------------------------------------------------------------
Mobile Apps Sidebar
------------------------------------------------------------------ -->
<div [class.open]="isFilterNavOpen" class="filter-sidebar">
<div>
<div class="d-flex justify-content-between align-items-center">
<div class="branding">
@if(options.theme === 'light') {
<a href="/">
<img src="./assets/images/logos/dark-logo.svg" class="align-middle m-2" alt="logo" />
</a>
} @else {
<a href="/">
<img src="./assets/images/logos/light-logo.svg" class="align-middle m-2" alt="logo" />
</a>
}
</div>
<button mat-icon-button (click)="isFilterNavOpen = !isFilterNavOpen" class="d-flex justify-content-center">
<i-tabler name="x" class="icon-18 d-flex"></i-tabler>
</button>
</div>
<mat-accordion>
<mat-expansion-panel class="shadow-none">
<mat-expansion-panel-header>
<mat-panel-title class="f-s-16 f-w-500"> Apps </mat-panel-title>
</mat-expansion-panel-header>
<div>
<div class="row">
@for(appdd of apps; track appdd.img) {
<div class="col-12 text-hover-primary">
<a [routerLink]="[appdd.link]" class="d-flex align-items-center text-decoration-none m-b-24 gap-16">
<button mat-mini-fab class="text-primary bg-light-primary shadow-none rounded">
<img [src]="appdd.img" width="20" />
</button>
<div>
<h5 class="f-s-14 f-w-600 m-0 textprimary f-s-14 hover-text">
{{ appdd.title }}
</h5>
<span class="f-s-14 f-s-12">{{ appdd.subtitle }}</span>
</div>
</a>
</div>
}
</div>
<h4 class="f-s-18 f-w-600 m-b-16">Quick Links</h4>
@for(quicklink of quicklinks; track quicklink.title) {
<div class="text-hover-primary">
<a [routerLink]="['quicklink.link']"
class="hover-text text-decoration-none f-s-14 f-w-600 d-block p-y-8">{{ quicklink.title }}</a>
</div>
}
</div>
</mat-expansion-panel>
</mat-accordion>
<div class="p-x-16">
<a [routerLink]="['/apps/calendar']"
class="d-flex align-items-center text-decoration-none f-s-14 p-y-16 gap-8">
<span class="f-s-15 f-w-500 m-l-8">Calendar</span>
</a>
<a [routerLink]="['/apps/chat']" class="d-flex align-items-center text-decoration-none f-s-14 p-y-16">
<span class="f-s-15 f-w-500 m-l-8">Chat</span>
</a>
<a [routerLink]="['/apps/email/inbox']"
class="d-flex align-items-center text-decoration-none f-s-14 p-y-16 gap-8">
<span class="f-s-15 f-w-500 m-l-8">Email</span>
</a>
</div>
</div>
</div>
</mat-sidenav-content>
<mat-sidenav #customizerRight mode="over" position="end">
<div class="p-x-16 p-y-20 d-flex align-items-center justify-content-between">
<h3 class="f-s-21 f-w-600">Settings</h3>
<button class="d-lg-none" mat-button (click)="customizerRight.toggle()">
Close
</button>
</div>
<mat-divider></mat-divider>
<app-customizer (optionsChange)="receiveOptions($event)"></app-customizer>
</mat-sidenav>
</mat-sidenav-container>
</span>

View File

@@ -0,0 +1,284 @@
import { BreakpointObserver, MediaMatcher } from '@angular/cdk/layout';
import { ChangeDetectorRef, Component, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
import { Subscription } from 'rxjs';
import { MatSidenav, MatSidenavContent } from '@angular/material/sidenav';
import { CoreService } from 'src/app/services/core.service';
import { AppSettings } from 'src/app/config';
import { filter } from 'rxjs/operators';
import { NavigationEnd, Router } from '@angular/router';
import { navItems } from './vertical/sidebar/sidebar-data';
import { NavService } from '../../services/nav.service';
import { AppNavItemComponent } from './vertical/sidebar/nav-item/nav-item.component';
import { RouterModule } from '@angular/router';
import { MaterialModule } from 'src/app/material.module';
import { CommonModule } from '@angular/common';
import { SidebarComponent } from './vertical/sidebar/sidebar.component';
import { NgScrollbarModule } from 'ngx-scrollbar';
import { TablerIconsModule } from 'angular-tabler-icons';
import { HeaderComponent } from './vertical/header/header.component';
import { AppHorizontalHeaderComponent } from './horizontal/header/header.component';
import { AppHorizontalSidebarComponent } from './horizontal/sidebar/sidebar.component';
import { AppBreadcrumbComponent } from './shared/breadcrumb/breadcrumb.component';
import { CustomizerComponent } from './shared/customizer/customizer.component';
const MOBILE_VIEW = 'screen and (max-width: 768px)';
const TABLET_VIEW = 'screen and (min-width: 769px) and (max-width: 1024px)';
const MONITOR_VIEW = 'screen and (min-width: 1024px)';
const BELOWMONITOR = 'screen and (max-width: 1023px)';
// for mobile app sidebar
interface apps {
id: number;
img: string;
title: string;
subtitle: string;
link: string;
}
interface quicklinks {
id: number;
title: string;
link: string;
}
@Component({
selector: 'app-full',
imports: [
RouterModule,
AppNavItemComponent,
MaterialModule,
CommonModule,
SidebarComponent,
NgScrollbarModule,
TablerIconsModule,
HeaderComponent,
AppHorizontalHeaderComponent,
AppHorizontalSidebarComponent,
AppBreadcrumbComponent,
CustomizerComponent,
],
templateUrl: './full.component.html',
encapsulation: ViewEncapsulation.None
})
export class FullComponent implements OnInit {
navItems = navItems;
@ViewChild('leftsidenav')
public sidenav: MatSidenav;
resView = false;
@ViewChild('content', { static: true }) content!: MatSidenavContent;
//get options from service
options = this.settings.getOptions();
private layoutChangesSubscription = Subscription.EMPTY;
private isMobileScreen = false;
private isContentWidthFixed = true;
private isCollapsedWidthFixed = false;
private htmlElement!: HTMLHtmlElement;
get isOver(): boolean {
return this.isMobileScreen;
}
get isTablet(): boolean {
return this.resView;
}
// for mobile app sidebar
apps: apps[] = [
{
id: 1,
img: '/assets/images/svgs/icon-dd-chat.svg',
title: 'Chat Application',
subtitle: 'Messages & Emails',
link: '/apps/chat',
},
{
id: 2,
img: '/assets/images/svgs/icon-dd-cart.svg',
title: 'Todo App',
subtitle: 'Completed task',
link: '/apps/todo',
},
{
id: 3,
img: '/assets/images/svgs/icon-dd-invoice.svg',
title: 'Invoice App',
subtitle: 'Get latest invoice',
link: '/apps/invoice',
},
{
id: 4,
img: '/assets/images/svgs/icon-dd-date.svg',
title: 'Calendar App',
subtitle: 'Get Dates',
link: '/apps/calendar',
},
{
id: 5,
img: '/assets/images/svgs/icon-dd-mobile.svg',
title: 'Contact Application',
subtitle: '2 Unsaved Contacts',
link: '/apps/contacts',
},
{
id: 6,
img: '/assets/images/svgs/icon-dd-lifebuoy.svg',
title: 'Tickets App',
subtitle: 'Create new ticket',
link: '/apps/tickets',
},
{
id: 7,
img: '/assets/images/svgs/icon-dd-message-box.svg',
title: 'Email App',
subtitle: 'Get new emails',
link: '/apps/email/inbox',
},
{
id: 8,
img: '/assets/images/svgs/icon-dd-application.svg',
title: 'Courses',
subtitle: 'Create new course',
link: '/apps/courses',
},
];
quicklinks: quicklinks[] = [
{
id: 1,
title: 'Pricing Page',
link: '/theme-pages/pricing',
},
{
id: 2,
title: 'Authentication Design',
link: '/authentication/login',
},
{
id: 3,
title: 'Register Now',
link: '/authentication/side-register',
},
{
id: 4,
title: '404 Error Page',
link: '/authentication/error',
},
{
id: 5,
title: 'Notes App',
link: '/apps/notes',
},
{
id: 6,
title: 'Employee App',
link: '/apps/employee',
},
{
id: 7,
title: 'Todo Application',
link: '/apps/todo',
},
{
id: 8,
title: 'Treeview',
link: '/theme-pages/treeview',
},
];
constructor(
private settings: CoreService,
private mediaMatcher: MediaMatcher,
private router: Router,
private breakpointObserver: BreakpointObserver,
private navService: NavService, private cdr: ChangeDetectorRef
) {
this.htmlElement = document.querySelector('html')!;
this.layoutChangesSubscription = this.breakpointObserver
.observe([MOBILE_VIEW, TABLET_VIEW, MONITOR_VIEW, BELOWMONITOR])
.subscribe((state) => {
// SidenavOpened must be reset true when layout changes
this.options.sidenavOpened = true;
this.isMobileScreen = state.breakpoints[BELOWMONITOR];
if (this.options.sidenavCollapsed == false) {
this.options.sidenavCollapsed = state.breakpoints[TABLET_VIEW];
}
this.isContentWidthFixed = state.breakpoints[MONITOR_VIEW];
this.resView = state.breakpoints[BELOWMONITOR];
});
// Initialize project theme with options
this.receiveOptions(this.options);
// This is for scroll to top
this.router.events
.pipe(filter((event) => event instanceof NavigationEnd))
.subscribe((e) => {
this.content.scrollTo({ top: 0 });
});
}
isFilterNavOpen = false;
toggleFilterNav() {
this.isFilterNavOpen = !this.isFilterNavOpen;
console.log('Sidebar open:', this.isFilterNavOpen);
this.cdr.detectChanges(); // Ensures Angular updates the view
}
ngOnInit(): void {}
ngOnDestroy() {
this.layoutChangesSubscription.unsubscribe();
}
toggleCollapsed() {
this.isContentWidthFixed = false;
this.options.sidenavCollapsed = !this.options.sidenavCollapsed;
this.resetCollapsedState();
}
resetCollapsedState(timer = 400) {
setTimeout(() => this.settings.setOptions(this.options), timer);
}
onSidenavClosedStart() {
this.isContentWidthFixed = false;
}
onSidenavOpenedChange(isOpened: boolean) {
this.isCollapsedWidthFixed = !this.isOver;
this.options.sidenavOpened = isOpened;
this.settings.setOptions(this.options);
}
receiveOptions(options: AppSettings): void {
this.toggleDarkTheme(options);
this.toggleColorsTheme(options);
}
toggleDarkTheme(options: AppSettings) {
if (options.theme === 'dark') {
this.htmlElement.classList.add('dark-theme');
this.htmlElement.classList.remove('light-theme');
} else {
this.htmlElement.classList.remove('dark-theme');
this.htmlElement.classList.add('light-theme');
}
}
toggleColorsTheme(options: AppSettings) {
// Remove any existing theme class dynamically
this.htmlElement.classList.forEach((className) => {
if (className.endsWith('_theme')) {
this.htmlElement.classList.remove(className);
}
});
// Add the selected theme class
this.htmlElement.classList.add(options.activeTheme);
}
}

View File

@@ -0,0 +1,296 @@
<mat-toolbar class="topbar horizontal-topbar">
<div class="container">
<div class="d-none d-sm-flex branding">
<app-branding></app-branding>
</div>
<!-- Mobile Menu -->
<button
mat-icon-button
(click)="toggleMobileNav.emit()"
class="d-block d-lg-none"
>
<i-tabler name="menu-2" class="icon-20 d-flex"></i-tabler>
</button>
<!-- --------------------------------------------------------------- -->
<!-- --------------------------------------------------------------- -->
<!-- Search -->
<!-- --------------------------------------------------------------- -->
<button mat-icon-button (click)="openDialog()" class="d-flex">
<i-tabler name="search" class="icon-20 d-flex"></i-tabler>
</button>
<div class="d-none d-lg-flex">
<!-- --------------------------------------------------------------- -->
<!-- Links -->
<!-- --------------------------------------------------------------- -->
<button
mat-button
[matMenuTriggerFor]="appsmenu"
aria-label="Notifications"
>
<div class="d-flex align-items-center">
Apps <i-tabler name="chevron-down" class="icon-16 m-l-4"></i-tabler>
</div>
</button>
<mat-menu #appsmenu="matMenu" class="apps-dd cardWithShadow">
<div class="row">
<div class="col-sm-8 b-r-1 p-r-0">
<div class="p-32 p-b-0">
<div class="row">
@for(appdd of apps; track appdd.title) {
<div class="col-sm-6 text-hover-primary">
<a
[routerLink]="[appdd.link]"
class="d-flex align-items-center text-decoration-none m-b-24"
>
<span
class="text-primary bg-light rounded icon-40 d-flex align-items-center justify-content-center"
>
<img [src]="appdd.img" width="20" />
</span>
<div class="m-l-16">
<h5
class="f-s-14 f-w-600 m-0 textprimary hover-text"
>
{{ appdd.title }}
</h5>
<span class="text-body f-s-12">{{
appdd.subtitle
}}</span>
</div>
</a>
</div>
}
</div>
</div>
<div
class="b-t-1 p-24 d-none d-lg-flex align-items-center justify-content-between"
>
<span
class="d-flex align-items-center f-s-16 f-w-500"
>
<i-tabler name="help" class="icon-20 m-r-8"></i-tabler
>Frequently Asked Questions
</span>
<a
[routerLink]="['/theme-pages/faq']"
mat-flat-button
color="primary"
>Check</a
>
</div>
</div>
<div class="col-sm-4">
<div class="p-x-16 p-y-32">
<h4 class="f-s-18 f-w-600 m-b-16">Quick Links</h4>
@for(quicklink of quicklinks; track quicklink.title) {
<div class="text-hover-primary">
<a
[routerLink]="[quicklink.link]"
class="hover-text text-decoration-none f-s-14 f-w-600 d-block p-y-8"
>{{ quicklink.title }}</a
>
</div>
}
</div>
</div>
</div>
</mat-menu>
<a mat-button [routerLink]="['/apps/chat']">Chat</a>
<a mat-button [routerLink]="['/apps/calendar']">Calendar</a>
<a mat-button [routerLink]="['/apps/email/inbox']">Email</a>
</div>
<span class="flex-1-auto"></span>
<!-- Mobile Menu -->
<button
mat-icon-button
(click)="toggleMobileFilterNav.emit()"
class="d-flex d-lg-none justify-content-center"
>
<i-tabler name="grid-dots" class="icon-20 d-flex"></i-tabler>
</button>
<!-- --------------------------------------------------------------- -->
<!-- langugage Dropdown -->
<!-- --------------------------------------------------------------- -->
<button [matMenuTriggerFor]="flags" mat-icon-button class="m-r-5">
<img
[src]="selectedLanguage.icon"
class="rounded-circle object-cover icon-20"
/>
</button>
<mat-menu #flags="matMenu" class="cardWithShadow">
@for(lang of languages; track lang.icon) {
<button mat-menu-item (click)="changeLanguage(lang)">
<div class="d-flex align-items-center">
<img
[src]="lang.icon"
class="rounded-circle object-cover m-r-8 icon-20"
/>
<span class=" f-s-14">{{ lang.language }}</span>
</div>
</button>
}
</mat-menu>
@if(options.theme=='light'){
<button mat-icon-button aria-label="lightdark" class="d-flex justify-content-center" (click)="setlightDark('dark')" >
<i-tabler class="d-flex icon-22" [name]="'moon'"></i-tabler>
</button>
}@else{
<button mat-icon-button aria-label="lightdark" class="d-flex justify-content-center" (click)="setlightDark('light')">
<i-tabler class="d-flex icon-22" [name]="'sun'"></i-tabler>
</button>
}
<!-- --------------------------------------------------------------- -->
<!-- Notification Dropdown -->
<!-- --------------------------------------------------------------- -->
<button
mat-icon-button matBadge="5"
[matMenuTriggerFor]="notificationmenu"
aria-label="Notifications" class="m-x-5 notification-badge"
>
<i-tabler
class="d-flex"
name="bell"
></i-tabler>
</button>
<mat-menu
#notificationmenu="matMenu"
xPosition="before"
class="topbar-dd cardWithShadow"
>
<div class="d-flex align-items-center p-x-32 p-y-16">
<h6 class="f-s-16 f-w-600 m-0 ">Notifications</h6>
<span class="m-l-auto">
<span class="bg-primary text-white p-x-8 p-y-4 f-w-500 rounded f-s-12"
>5 new</span
>
</span>
</div>
@for(notification of notifications; track notification.title) {
<button mat-menu-item class="p-x-32 p-y-16">
<div class="d-flex align-items-center">
<img [src]="notification.img" class="rounded-circle" width="48" />
<div class="m-l-16">
<h5 class="f-s-14 f-w-600 m-0 ">
{{ notification.title }}
</h5>
<span>{{ notification.subtitle }}</span>
</div>
</div>
</button>
}
<div class="p-y-12 p-x-32">
<button mat-stroked-button color="primary" class="w-100">
See all notifications
</button>
</div>
</mat-menu>
<!-- --------------------------------------------------------------- -->
<!-- profile Dropdown -->
<!-- --------------------------------------------------------------- -->
<button
mat-icon-button
[matMenuTriggerFor]="profilemenu"
aria-label="Notifications"
>
<img
src="/assets/images/profile/user-1.jpg"
class="rounded-circle object-cover icon-35 profile-dd"
width="35"
/>
</button>
<mat-menu
#profilemenu="matMenu"
xPosition="before"
class="topbar-dd cardWithShadow"
>
<div class="p-x-32 p-y-16">
<h6 class="f-s-16 f-w-600 m-0 ">User Profile</h6>
<div class="d-flex align-items-center p-b-24 b-b-1 m-t-16">
<img
src="/assets/images/profile/user-1.jpg"
class="rounded-circle"
width="95"
/>
<div class="m-l-16">
<h6 class="f-s-14 f-w-600 m-0 ">Mathew Anderson</h6>
<span class="f-s-14 d-block m-b-4">Designer</span>
<span class="d-flex align-items-center">
<i-tabler name="mail" class="icon-15 m-r-4"></i-tabler>
info&#64;modernize.com
</span>
</div>
</div>
</div>
<div class="p-x-32">
@for(profile of profiledd; track profile.title) {
<a
class="p-y-16 text-decoration-none d-block text-hover-primary"
[routerLink]="[profile.link]"
>
<div class="d-flex align-items-center">
<button
mat-mini-fab
class="text-primary bg-light-primary shadow-none rounded"
>
<img [src]="profile.img" width="20" />
</button>
<div class="m-l-16">
<h5
class="f-s-14 f-w-600 m-0 textprimary hover-text"
>
{{ profile.title }}
</h5>
<span class="f-s-14 text-body">{{ profile.subtitle }}</span>
</div>
</div>
</a>
}
<!-- upgrade -->
<div
class="p-24 overflow-hidden bg-light-primary rounded position-relative m-y-16"
>
<div class="d-flex align-items-center">
<div>
<h5 class="f-s-18 m-0 f-w-600 m-b-12 ">
Unlimited <br />
Access
</h5>
<button mat-flat-button color="primary">Upgrade</button>
</div>
<div class="m-l-auto">
<img
src="/assets/images/backgrounds/unlimited-bg.png"
alt="upgrade-bg"
class="upgrade-bg"
/>
</div>
</div>
</div>
</div>
<div class="p-y-12 p-x-32">
<a
[routerLink]="['/authentication/login']"
mat-stroked-button
color="primary"
class="w-100"
>Logout</a
>
</div>
</mat-menu>
</div>
</mat-toolbar>

View File

@@ -0,0 +1,292 @@
import { Component, Output, EventEmitter, Input } from '@angular/core';
import { CoreService } from 'src/app/services/core.service';
import { MatDialog } from '@angular/material/dialog';
import { navItems } from '../../vertical/sidebar/sidebar-data';
import { TranslateService } from '@ngx-translate/core';
import { RouterModule } from '@angular/router';
import { TablerIconsModule } from 'angular-tabler-icons';
import { MaterialModule } from 'src/app/material.module';
import { BrandingComponent } from '../../vertical/sidebar/branding.component';
import { FormsModule } from '@angular/forms';
import { AppSettings } from 'src/app/config';
interface notifications {
id: number;
img: string;
title: string;
subtitle: string;
}
interface profiledd {
id: number;
img: string;
title: string;
subtitle: string;
link: string;
}
interface apps {
id: number;
img: string;
title: string;
subtitle: string;
link: string;
}
interface quicklinks {
id: number;
title: string;
link: string;
}
@Component({
selector: 'app-horizontal-header',
imports: [RouterModule, TablerIconsModule, MaterialModule, BrandingComponent],
templateUrl: './header.component.html'
})
export class AppHorizontalHeaderComponent {
@Input() showToggle = true;
@Input() toggleChecked = false;
@Output() toggleMobileNav = new EventEmitter<void>();
@Output() toggleMobileFilterNav = new EventEmitter<void>();
@Output() toggleCollapsed = new EventEmitter<void>();
showFiller = false;
public selectedLanguage: any = {
language: 'English',
code: 'en',
type: 'US',
icon: '/assets/images/flag/icon-flag-en.svg',
};
public languages: any[] = [
{
language: 'English',
code: 'en',
type: 'US',
icon: '/assets/images/flag/icon-flag-en.svg',
},
{
language: 'Español',
code: 'es',
icon: '/assets/images/flag/icon-flag-es.svg',
},
{
language: 'Français',
code: 'fr',
icon: '/assets/images/flag/icon-flag-fr.svg',
},
{
language: 'German',
code: 'de',
icon: '/assets/images/flag/icon-flag-de.svg',
},
];
@Output() optionsChange = new EventEmitter<AppSettings>();
constructor(
private settings: CoreService,
private vsidenav: CoreService,
public dialog: MatDialog,
private translate: TranslateService
) {
translate.setDefaultLang('en');
}
options = this.settings.getOptions();
openDialog() {
const dialogRef = this.dialog.open(AppHorizontalSearchDialogComponent);
dialogRef.afterClosed().subscribe((result) => {
console.log(`Dialog result: ${result}`);
});
}
private emitOptions() {
this.optionsChange.emit(this.options);
}
setlightDark(theme: string) {
this.options.theme = theme;
this.emitOptions();
}
changeLanguage(lang: any): void {
this.translate.use(lang.code);
this.selectedLanguage = lang;
}
notifications: notifications[] = [
{
id: 1,
img: '/assets/images/profile/user-1.jpg',
title: 'Roman Joined thes Team!',
subtitle: 'Congratulate him',
},
{
id: 2,
img: '/assets/images/profile/user-2.jpg',
title: 'New message received',
subtitle: 'Salma sent you new message',
},
{
id: 3,
img: '/assets/images/profile/user-3.jpg',
title: 'New Payment received',
subtitle: 'Check your earnings',
},
{
id: 4,
img: '/assets/images/profile/user-4.jpg',
title: 'Jolly completed tasks',
subtitle: 'Assign her new tasks',
},
{
id: 5,
img: '/assets/images/profile/user-5.jpg',
title: 'Roman Joined the Team!',
subtitle: 'Congratulate him',
},
];
profiledd: profiledd[] = [
{
id: 1,
img: '/assets/images/svgs/icon-account.svg',
title: 'My Profile',
subtitle: 'Account Settings',
link: '/',
},
{
id: 2,
img: '/assets/images/svgs/icon-inbox.svg',
title: 'My Inbox',
subtitle: 'Messages & Email',
link: '/apps/email/inbox',
},
{
id: 3,
img: '/assets/images/svgs/icon-tasks.svg',
title: 'My Tasks',
subtitle: 'To-do and Daily Tasks',
link: '/apps/taskboard',
},
];
apps: apps[] = [
{
id: 1,
img: '/assets/images/svgs/icon-dd-chat.svg',
title: 'Chat Application',
subtitle: 'Messages & Emails',
link: '/apps/chat',
},
{
id: 2,
img: '/assets/images/svgs/icon-dd-cart.svg',
title: 'eCommerce App',
subtitle: 'Buy a Product',
link: '/apps/email/inbox',
},
{
id: 3,
img: '/assets/images/svgs/icon-dd-invoice.svg',
title: 'Invoice App',
subtitle: 'Get latest invoice',
link: '/apps/invoice',
},
{
id: 4,
img: '/assets/images/svgs/icon-dd-date.svg',
title: 'Calendar App',
subtitle: 'Get Dates',
link: '/apps/calendar',
},
{
id: 5,
img: '/assets/images/svgs/icon-dd-mobile.svg',
title: 'Contact Application',
subtitle: '2 Unsaved Contacts',
link: '/apps/contacts',
},
{
id: 6,
img: '/assets/images/svgs/icon-dd-lifebuoy.svg',
title: 'Tickets App',
subtitle: 'Create new ticket',
link: '/apps/tickets',
},
{
id: 7,
img: '/assets/images/svgs/icon-dd-message-box.svg',
title: 'Email App',
subtitle: 'Get new emails',
link: '/apps/email/inbox',
},
{
id: 8,
img: '/assets/images/svgs/icon-dd-application.svg',
title: 'Courses',
subtitle: 'Create new course',
link: '/apps/courses',
},
];
quicklinks: quicklinks[] = [
{
id: 1,
title: 'Pricing Page',
link: '/theme-pages/pricing',
},
{
id: 2,
title: 'Authentication Design',
link: '/authentication/login',
},
{
id: 3,
title: 'Register Now',
link: '/authentication/side-register',
},
{
id: 4,
title: '404 Error Page',
link: '/authentication/error',
},
{
id: 5,
title: 'Notes App',
link: '/apps/notes',
},
{
id: 6,
title: 'Employee App',
link: '/apps/employee',
},
{
id: 7,
title: 'Todo Application',
link: '/apps/todo',
},
{
id: 8,
title: 'Treeview',
link: '/theme-pages/treeview',
},
];
}
@Component({
selector: 'app-search-dialog',
imports: [RouterModule, MaterialModule, TablerIconsModule, FormsModule],
templateUrl: 'search-dialog.component.html'
})
export class AppHorizontalSearchDialogComponent {
searchText: string = '';
navItems = navItems;
navItemsData = navItems.filter((navitem) => navitem.displayName);
}

View File

@@ -0,0 +1,39 @@
<div class="p-24 p-b-0">
<div class="row">
<div class="col-10">
<mat-form-field
appearance="outline"
color="primary"
class="hide-hint w-100"
>
<input matInput placeholder="Search here" [(ngModel)]="searchText" />
</mat-form-field>
</div>
<div class="col-2 d-flex justify-content-end">
<button
mat-icon-button
mat-dialog-close
class="d-flex justify-content-center"
>
<i-tabler name="x" class="icon-18 d-flex"></i-tabler>
</button>
</div>
</div>
</div>
<mat-divider></mat-divider>
<mat-dialog-content class="mat-typography search-dialog">
<h4 class="f-s-18 f-w-500 m-b-16">Quick Page Links</h4>
@for(item of navItemsData; track item.route) {
<a
[routerLink]="[item.route]"
mat-dialog-close
class="p-y-12 text-decoration-none d-block"
>
<h5 class="f-s-14 f-w-500 d-block m-0">
{{ item.displayName }}
</h5>
<span class="f-s-12 f-s-16">{{ item.route }}</span>
</a>
}
</mat-dialog-content>

View File

@@ -0,0 +1,24 @@
@if(!item.navCap) {
<a
class="cursor-pointer menuLink"
(click)="onItemSelected(item)"
[ngClass]="{
activeMenu: item.route ? router.isActive(item.route, true) : false
}"
>
<i-tabler class="routeIcon icon-18" name="{{ item.iconName }}"></i-tabler>
{{ item.displayName }}
@if(item.children && item.children.length) {
<span class="down-icon d-flex m-l-auto">
<mat-icon> expand_more </mat-icon>
</span>
}
</a>
} @if(item.children){
<div class="childBox">
@for(child of item.children; track child) {
<app-horizontal-nav-item [item]="child" class="ddmenu">
</app-horizontal-nav-item>
}
</div>
}

View File

@@ -0,0 +1,33 @@
import {
Component,
OnInit,
Input,
} from '@angular/core';
import { Router } from '@angular/router';
import { NavService } from '../../../../../services/nav.service';
import { TablerIconsModule } from 'angular-tabler-icons';
import { CommonModule } from '@angular/common';
import { MatIconModule } from '@angular/material/icon';
@Component({
selector: 'app-horizontal-nav-item',
imports: [TablerIconsModule, CommonModule, MatIconModule],
templateUrl: './nav-item.component.html'
})
export class AppHorizontalNavItemComponent implements OnInit {
@Input() depth: any;
@Input() item: any;
constructor(public navService: NavService, public router: Router) {
if (this.depth === undefined) {
this.depth = 0;
}
}
ngOnInit() { }
onItemSelected(item: any) {
if (!item.children || !item.children.length) {
this.router.navigate([item.route]);
}
}
}

View File

@@ -0,0 +1,633 @@
import { NavItem } from '../../vertical/sidebar/nav-item/nav-item';
export const navItems: NavItem[] = [
{
navCap: 'Home',
},
{
displayName: 'Dashboards',
iconName: 'home',
route: 'dashboards',
children: [
{
displayName: 'Analytical',
iconName: 'point',
route: 'dashboards/dashboard1',
},
{
displayName: 'eCommerce',
iconName: 'point',
route: 'dashboards/dashboard2',
},
],
},
{
displayName: 'Frontend pages',
iconName: 'app-window',
route: 'front-pages',
children: [
{
displayName: 'Home Page',
iconName: 'point',
route: 'front-pages/homepage',
} ,
{
displayName: 'About Us',
iconName: 'point',
route: 'front-pages/about',
} ,
{
displayName: 'Blog',
iconName: 'point',
route: 'front-pages/blog',
} ,
{
displayName: 'Blog Details',
iconName: 'point',
route: 'front-pages/blog-details',
} ,
{
displayName: 'Portfolio',
iconName: 'point',
route: 'front-pages/portfolio',
},
{
displayName: 'Pricing',
iconName: 'point',
route: 'front-pages/pricing',
},
{
displayName: 'Contact',
iconName: 'point',
route: 'front-pages/contact',
}
]
},
{
displayName: 'Apps',
iconName: 'apps',
route: 'apps',
ddType: '',
children: [
{
displayName: 'Chat',
iconName: 'point',
route: 'apps/chat',
},
{
displayName: 'Calendar',
iconName: 'point',
route: 'apps/calendar',
},
{
displayName: 'Email',
iconName: 'point',
route: 'apps/email/inbox',
},
{
displayName: 'Contacts',
iconName: 'point',
route: 'apps/contacts',
},
{
displayName: 'Contact List',
iconName: 'point',
route: 'apps/contact-list',
},
{
displayName: 'Courses',
iconName: 'point',
route: 'apps/courses',
},
{
displayName: 'Employee',
iconName: 'point',
route: 'apps/employee',
},
{
displayName: 'Notes',
iconName: 'point',
route: 'apps/notes',
},
{
displayName: 'Tickets',
iconName: 'point',
route: 'apps/tickets',
},
{
displayName: 'Invoice',
iconName: 'point',
route: 'apps/invoice',
},
{
displayName: 'ToDo',
iconName: 'point',
route: 'apps/todo',
},
{
displayName: 'Kanban',
iconName: 'point',
route: 'apps/kanban',
},
{
displayName: 'Blog',
iconName: 'point',
route: 'apps/blog',
children: [
{
displayName: 'Post',
iconName: 'point',
route: 'apps/blog/post',
},
{
displayName: 'Detail',
iconName: 'point',
route: 'apps/blog/detail/Early Black Friday Amazon deals: cheap TVs, headphones, laptops',
},
],
},
{
displayName: 'User Profile',
iconName: 'point',
route: 'apps/profile-details',
children: [
{
displayName: 'Profile',
iconName: 'point',
route: 'apps/profile-details/profile',
},
{
displayName: 'Followers',
iconName: 'point',
route: 'apps/profile-details/followers',
},
{
displayName: 'Friends',
iconName: 'point',
route: 'apps/profile-details/friends',
},
{
displayName: 'Gellary',
iconName: 'point',
route: 'apps/profile-details/gallery',
},
],
},
{
displayName: 'Ecommerce',
iconName: 'point',
route: 'apps/product',
children: [
{
displayName: 'Product List',
iconName: 'point',
route: 'apps/product/product-list',
},
{
displayName: 'Add Product',
iconName: 'point',
route: 'apps/product/add-product',
},
{
displayName: 'Edit Product',
iconName: 'point',
route: 'apps/product/edit-product',
},
{
displayName: 'Shop',
iconName: 'point',
route: 'apps/product/shop',
},
],
},
],
},
{
displayName: 'Ui',
iconName: 'components',
route: 'ui-components',
ddType: '',
children: [
{
displayName: 'Badge',
iconName: 'point',
route: 'ui-components/badge',
},
{
displayName: 'Expansion Panel',
iconName: 'point',
route: 'ui-components/expansion',
},
{
displayName: 'Chips',
iconName: 'point',
route: 'ui-components/chips',
},
{
displayName: 'Dialog',
iconName: 'point',
route: 'ui-components/dialog',
},
{
displayName: 'Lists',
iconName: 'point',
route: 'ui-components/lists',
},
{
displayName: 'Divider',
iconName: 'point',
route: 'ui-components/divider',
},
{
displayName: 'Menu',
iconName: 'point',
route: 'ui-components/menu',
},
{
displayName: 'Paginator',
iconName: 'point',
route: 'ui-components/paginator',
},
{
displayName: 'Progress Bar',
iconName: 'point',
route: 'ui-components/progress',
},
{
displayName: 'Progress Spinner',
iconName: 'point',
route: 'ui-components/progress-spinner',
},
{
displayName: 'Ripples',
iconName: 'point',
route: 'ui-components/ripples',
},
{
displayName: 'Slide Toggle',
iconName: 'point',
route: 'ui-components/slide-toggle',
},
{
displayName: 'Slider',
iconName: 'point',
route: 'ui-components/slider',
},
{
displayName: 'Snackbar',
iconName: 'point',
route: 'ui-components/snackbar',
},
{
displayName: 'Tabs',
iconName: 'point',
route: 'ui-components/tabs',
},
{
displayName: 'Toolbar',
iconName: 'point',
route: 'ui-components/toolbar',
},
{
displayName: 'Tooltips',
iconName: 'point',
route: 'ui-components/tooltips',
},
],
},
{
displayName: 'Pages',
iconName: 'clipboard',
route: 'theme-pages',
ddType: '',
children: [
{
displayName: 'Treeview',
iconName: 'point',
route: 'theme-pages/treeview',
},
{
displayName: 'Pricing',
iconName: 'point',
route: 'theme-pages/pricing',
},
{
displayName: 'Account Setting',
iconName: 'point',
route: 'theme-pages/account-setting',
},
{
displayName: 'FAQ',
iconName: 'point',
route: 'theme-pages/faq',
},
{
displayName: 'Landingpage',
iconName: 'point',
route: 'landingpage',
},
{
displayName: 'Widgets',
iconName: 'point',
route: 'widgets',
children: [
{
displayName: 'Cards',
iconName: 'point',
route: 'widgets/cards',
},
{
displayName: 'Banners',
iconName: 'point',
route: 'widgets/banners',
},
{
displayName: 'Charts',
iconName: 'point',
route: 'widgets/charts',
},
],
},
{
displayName: 'Charts',
iconName: 'point',
route: 'charts',
children: [
{
displayName: 'Line',
iconName: 'point',
route: '/charts/line',
},
{
displayName: 'Gredient',
iconName: 'point',
route: '/charts/gredient',
},
{
displayName: 'Area',
iconName: 'point',
route: '/charts/area',
},
{
displayName: 'Candlestick',
iconName: 'point',
route: '/charts/candlestick',
},
{
displayName: 'Column',
iconName: 'point',
route: '/charts/column',
},
{
displayName: 'Doughnut & Pie',
iconName: 'point',
route: '/charts/doughnut-pie',
},
{
displayName: 'Radialbar & Radar',
iconName: 'point',
route: '/charts/radial-radar',
},
],
},
{
displayName: 'Auth',
iconName: 'point',
route: '/',
children: [
{
displayName: 'Login',
iconName: 'point',
route: '/authentication',
children: [
{
displayName: 'Login 1',
iconName: 'point',
route: '/authentication/login',
},
{
displayName: 'Boxed Login',
iconName: 'point',
route: '/authentication/boxed-login',
},
],
},
{
displayName: 'Register',
iconName: 'point',
route: '/authentication',
children: [
{
displayName: 'Login 1',
iconName: 'point',
route: '/authentication/side-register',
},
{
displayName: 'Boxed Login',
iconName: 'point',
route: '/authentication/boxed-register',
},
],
},
{
displayName: 'Forgot Password',
iconName: 'point',
route: '/authentication',
children: [
{
displayName: 'Side Forgot Password',
iconName: 'point',
route: '/authentication/side-forgot-pwd',
},
{
displayName: 'Boxed Forgot Password',
iconName: 'point',
route: '/authentication/boxed-forgot-pwd',
},
],
},
{
displayName: 'Two Steps',
iconName: 'point',
route: '/authentication',
children: [
{
displayName: 'Side Two Steps',
iconName: 'point',
route: '/authentication/side-two-steps',
},
{
displayName: 'Boxed Two Steps',
iconName: 'point',
route: '/authentication/boxed-two-steps',
},
],
},
{
displayName: 'Error',
iconName: 'point',
route: '/authentication/error',
},
{
displayName: 'Maintenance',
iconName: 'point',
route: '/authentication/maintenance',
},
],
},
],
},
{
displayName: 'Forms',
iconName: 'file-description',
route: 'forms',
ddType: '',
children: [
{
displayName: 'Form elements',
iconName: 'point',
route: 'forms/forms-elements',
children: [
{
displayName: 'Autocomplete',
iconName: 'point',
route: 'forms/forms-elements/autocomplete',
},
{
displayName: 'Button',
iconName: 'point',
route: 'forms/forms-elements/button',
},
{
displayName: 'Checkbox',
iconName: 'point',
route: 'forms/forms-elements/checkbox',
},
{
displayName: 'Radio',
iconName: 'point',
route: 'forms/forms-elements/radio',
},
{
displayName: 'Datepicker',
iconName: 'point',
route: 'forms/forms-elements/datepicker',
},
],
},
{
displayName: 'Form Layouts',
iconName: 'point',
route: '/forms/form-layouts',
},
{
displayName: 'Form Horizontal',
iconName: 'point',
route: '/forms/form-horizontal',
},
{
displayName: 'Form Vertical',
iconName: 'point',
route: '/forms/form-vertical',
},
{
displayName: 'Form Wizard',
iconName: 'point',
route: '/forms/form-wizard',
},
{
displayName: 'Toastr',
iconName: 'point',
route: '/forms/form-toastr',
},
{
displayName: 'Editor',
iconName: 'point',
route: '/forms/form-editor',
},
],
},
{
displayName: 'Tables',
iconName: 'layout',
route: 'tables',
ddType: '',
children: [
{
displayName: 'Basic Table',
iconName: 'point',
route: 'tables/basic-table',
},
{
displayName: 'Dynamic Table',
iconName: 'point',
route: 'tables/dynamic-table',
},
{
displayName: 'Expand Table',
iconName: 'point',
route: 'tables/expand-table',
},
{
displayName: 'Filterable Table',
iconName: 'point',
route: 'tables/filterable-table',
},
{
displayName: 'Footer Row Table',
iconName: 'point',
route: 'tables/footer-row-table',
},
{
displayName: 'HTTP Table',
iconName: 'point',
route: 'tables/http-table',
},
{
displayName: 'Mix Table',
iconName: 'point',
route: 'tables/mix-table',
},
{
displayName: 'Multi Header Footer',
iconName: 'point',
route: 'tables/multi-header-footer-table',
},
{
displayName: 'Pagination Table',
iconName: 'point',
route: 'tables/pagination-table',
},
{
displayName: 'Row Context Table',
iconName: 'point',
route: 'tables/row-context-table',
},
{
displayName: 'Selection Table',
iconName: 'point',
route: 'tables/selection-table',
},
{
displayName: 'Sortable Table',
iconName: 'point',
route: 'tables/sortable-table',
},
{
displayName: 'Sticky Column',
iconName: 'point',
route: 'tables/sticky-column-table',
},
{
displayName: 'Sticky Header Footer',
iconName: 'point',
route: 'tables/sticky-header-footer-table',
},
{
displayName: 'Data table',
iconName: 'point',
route: '/datatable/kichen-sink',
},
],
},
];

View File

@@ -0,0 +1,16 @@
@if(mobileQuery.matches) {
<div class="horizontal-sidebar p-y-8 p-y-8 b-b-1">
<div class="container">
<div>
<div class="horizontal-navbar hstack align-items-center">
@for(item of navItems; track item) {
<app-horizontal-nav-item [item]="item" class="parentBox {{ item.ddType }}" [ngClass]="{
pactive: item.route == parentActive ? 'pactive' : ''
}">
</app-horizontal-nav-item>
}
</div>
</div>
</div>
</div>
}

View File

@@ -0,0 +1,48 @@
import {
Component,
OnInit,
Input,
ChangeDetectorRef,
OnChanges,
} from '@angular/core';
import { navItems } from './sidebar-data';
import { Router } from '@angular/router';
import { NavService } from '../../../../services/nav.service';
import { MediaMatcher } from '@angular/cdk/layout';
import { AppHorizontalNavItemComponent } from './nav-item/nav-item.component';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-horizontal-sidebar',
imports: [AppHorizontalNavItemComponent, CommonModule],
templateUrl: './sidebar.component.html',
})
export class AppHorizontalSidebarComponent implements OnInit {
navItems = navItems;
parentActive = '';
mobileQuery: MediaQueryList;
private _mobileQueryListener: () => void;
constructor(
public navService: NavService,
public router: Router,
media: MediaMatcher,
changeDetectorRef: ChangeDetectorRef
) {
this.mobileQuery = media.matchMedia('(min-width: 1100px)');
this._mobileQueryListener = () => changeDetectorRef.detectChanges();
this.mobileQuery.addListener(this._mobileQueryListener);
this.router.events.subscribe(
() => (this.parentActive = this.router.url.split('/')[1])
);
}
ngOnInit(): void {
this.parentActive = this.router.url.split('/')[1];
this.router.events.subscribe(() => {
this.parentActive = this.router.url.split('/')[1];
});
}
}

View File

@@ -0,0 +1,36 @@
@if(pageInfo?.['title'] != 'Analytical' && pageInfo?.['title'] != 'eCommerce'){
<div class="bg-light-primary rounded p-y-30 p-x-24 m-b-30 overflow-hidden">
<div class="row">
<div class="col-sm-8">
<h4 class="page-title m-0 f-s-20 f-w-600 m-b-16">
{{ pageInfo?.['title'] }}
</h4>
<div class="d-flex align-items-center overflow-hidden">
<ul class="breadcrumb">
@for (url of pageInfo?.['urls']; track url.url;let index = $index,last
= $last ) { @if(!last){
<li class="breadcrumb-item" [routerLink]="url.url">
<a [routerLink]="url.url">{{ url.title }}</a>
</li>
}@else {
<li class="breadcrumb-item">
<i-tabler name="circle-filled" class="icon-8"></i-tabler>
</li>
<li class="breadcrumb-item active f-s-14">{{ url.title }}</li>
} }
</ul>
</div>
</div>
<div class="col-sm-4 text-right position-relative">
<div class="breadcrumb-icon">
<img
src="/assets/images/breadcrumb/ChatBc.png"
alt="breadcrumb"
width="165"
/>
</div>
</div>
</div>
</div>
}

View File

@@ -0,0 +1,43 @@
import { Component, OnInit } from '@angular/core';
import { Title } from '@angular/platform-browser';
import { RouterModule } from '@angular/router';
import { Router, NavigationEnd, ActivatedRoute, Data } from '@angular/router';
import { filter, map, mergeMap } from 'rxjs/operators';
import { TablerIconsModule } from 'angular-tabler-icons';
@Component({
selector: 'app-breadcrumb',
imports: [RouterModule, TablerIconsModule],
templateUrl: './breadcrumb.component.html',
styleUrls: []
})
export class AppBreadcrumbComponent {
// @Input() layout;
pageInfo: Data | any = Object.create(null);
myurl: any = this.router.url.slice(1).split('/');
constructor(
private router: Router,
private activatedRoute: ActivatedRoute,
private titleService: Title
) {
this.router.events
.pipe(filter((event) => event instanceof NavigationEnd))
.pipe(map(() => this.activatedRoute))
.pipe(
map((route) => {
while (route.firstChild) {
route = route.firstChild;
}
return route;
})
)
.pipe(filter((route) => route.outlet === 'primary'))
.pipe(mergeMap((route) => route.data))
// tslint:disable-next-line - Disables all
.subscribe((event) => {
// tslint:disable-next-line - Disables all
this.titleService.setTitle(event['title'] + ' - Angular 20');
this.pageInfo = event;
});
}
}

View File

@@ -0,0 +1,173 @@
<div class="customizerNav">
<ng-scrollbar class="position-relative" style="height: calc(100vh - 85px)">
<div class="p-24">
<h6 class="f-s-16 f-w-600 f-s-16 m-b-16">Theme Option</h6>
<mat-button-toggle-group #group="matButtonToggleGroup" [(ngModel)]="options.theme" (change)="setDark()"
class="customizer-button-group gap-16" [hideSingleSelectionIndicator]="hideSingleSelectionIndicator()">
<mat-button-toggle [value]="'light'">
<div class="d-flex align-items-center f-w-500">
<i-tabler name="sun-high" class="d-flex m-r-8 fill-icon"></i-tabler>
Light
</div>
</mat-button-toggle>
<mat-button-toggle [value]="'dark'">
<div class="d-flex align-items-center f-w-500">
<i-tabler name="moon" class="d-flex m-r-8 fill-icon"></i-tabler>
Dark
</div>
</mat-button-toggle>
</mat-button-toggle-group>
<div>
<h6 class="f-s-16 f-w-600 f-s-16 m-b-16 m-t-24 p-t-16">
Theme Colors
</h6>
<mat-button-toggle-group #group="matButtonToggleGroup" [(ngModel)]="options.activeTheme"
(change)="setColor($event.value)" class="customizer-button-group theme-colors two-row"
[hideSingleSelectionIndicator]="hideSingleSelectionIndicator()">
<mat-button-toggle [value]="'blue_theme'">
<span class="theme-circle blue_theme" matTooltip="blue_theme" matTooltipClass="text-uppercase"
matTooltipPosition="above">
<i-tabler name="check" class="icon-16 theme-icon"></i-tabler>
</span>
</mat-button-toggle>
<mat-button-toggle [value]="'aqua_theme'">
<span class="theme-circle aqua_theme" matTooltip="aqua_theme" matTooltipClass="text-uppercase"
matTooltipPosition="above">
<i-tabler name="check" class="icon-16 theme-icon"></i-tabler>
</span>
</mat-button-toggle>
<mat-button-toggle [value]="'purple_theme'">
<span class="theme-circle purple_theme" matTooltip="purple_theme" matTooltipClass="text-uppercase"
matTooltipPosition="above">
<i-tabler name="check" class="icon-16 theme-icon"></i-tabler>
</span>
</mat-button-toggle>
<mat-button-toggle [value]="'green_theme'">
<span class="theme-circle green_theme" matTooltip="green_theme" matTooltipClass="text-uppercase"
matTooltipPosition="above">
<i-tabler name="check" class="icon-16 theme-icon"></i-tabler>
</span>
</mat-button-toggle>
<mat-button-toggle [value]="'cyan_theme'">
<span class="theme-circle cyan_theme" matTooltip="cyan_theme" matTooltipClass="text-uppercase"
matTooltipPosition="above">
<i-tabler name="check" class="icon-16 theme-icon"></i-tabler>
</span>
</mat-button-toggle>
<mat-button-toggle [value]="'orange_theme'">
<span class="theme-circle orange_theme" matTooltip="orange_theme" matTooltipClass="text-uppercase"
matTooltipPosition="above">
<i-tabler name="check" class="icon-16 theme-icon"></i-tabler>
</span>
</mat-button-toggle>
</mat-button-toggle-group>
</div>
<h6 class="f-s-16 f-w-600 f-s-16 m-b-16 m-t-24">
Theme Direction
</h6>
<mat-button-toggle-group #group="matButtonToggleGroup" [(ngModel)]="options.dir" (change)="setDir($event.value)"
class="customizer-button-group gap-16" [hideSingleSelectionIndicator]="hideSingleSelectionIndicator()">
<mat-button-toggle [value]="'ltr'">
<div class="d-flex align-items-center f-w-500">
<i-tabler name="text-direction-ltr" class="d-flex m-r-8 fill-icon"></i-tabler>
LTR
</div>
</mat-button-toggle>
<mat-button-toggle [value]="'rtl'">
<div class="d-flex align-items-center f-w-500">
<i-tabler name="text-direction-rtl" class="d-flex m-r-8 fill-icon"></i-tabler>
RTL
</div>
</mat-button-toggle>
</mat-button-toggle-group>
@if(!options.horizontal){
<div>
<h6 class="f-s-16 f-w-600 f-s-16 m-b-16 m-t-24 p-t-16">
Sidebar type
</h6>
<mat-button-toggle-group #group="matButtonToggleGroup" [(ngModel)]="options.sidenavCollapsed"
(change)="setSidebar($event.value)" class="customizer-button-group gap-16"
[hideSingleSelectionIndicator]="hideSingleSelectionIndicator()">
<mat-button-toggle [value]="false">
<div class="d-flex align-items-center f-w-500">
<i-tabler name="layout-sidebar-right" class="d-flex m-r-8 fill-icon"></i-tabler>
Full
</div>
</mat-button-toggle>
<mat-button-toggle [value]="true">
<div class="d-flex align-items-center f-w-500">
<i-tabler name="layout-sidebar" class="d-flex m-r-8 fill-icon"></i-tabler>
Minisidebar
</div>
</mat-button-toggle>
</mat-button-toggle-group>
</div>
}
<h6 class="f-s-16 f-w-600 f-s-16 m-b-16 m-t-24 p-t-16">
Layout type
</h6>
<mat-button-toggle-group #group="matButtonToggleGroup" [(ngModel)]="options.horizontal"
class="customizer-button-group gap-16" [hideSingleSelectionIndicator]="hideSingleSelectionIndicator()">
<mat-button-toggle [value]="false">
<div class="d-flex align-items-center f-w-500">
<i-tabler name="layout-distribute-vertical" class="d-flex m-r-8 fill-icon"></i-tabler>
Vertical
</div>
</mat-button-toggle>
<mat-button-toggle [value]="true">
<div class="d-flex align-items-center f-w-500">
<i-tabler name="layout-distribute-horizontal" class="d-flex m-r-8 fill-icon"></i-tabler>
Horizontal
</div>
</mat-button-toggle>
</mat-button-toggle-group>
<h6 class="f-s-16 f-w-600 f-s-16 m-b-16 m-t-24 p-t-16">
Card with
</h6>
<mat-button-toggle-group #group="matButtonToggleGroup" [(ngModel)]="options.cardBorder"
class="customizer-button-group gap-16" [hideSingleSelectionIndicator]="hideSingleSelectionIndicator()">
<mat-button-toggle [value]="false">
<div class="d-flex align-items-center f-w-500">
<i-tabler name="shadow" class="d-flex m-r-8 fill-icon"></i-tabler>
Shadow
</div>
</mat-button-toggle>
<mat-button-toggle [value]="true">
<div class="d-flex align-items-center f-w-500">
<i-tabler name="shadow-off" class="d-flex m-r-8 fill-icon"></i-tabler>
Border
</div>
</mat-button-toggle>
</mat-button-toggle-group>
<h6 class="f-s-16 f-w-600 f-s-16 m-b-16 m-t-24 p-t-16">
Container Option
</h6>
<mat-button-toggle-group #group="matButtonToggleGroup" [(ngModel)]="options.boxed"
class="customizer-button-group gap-16" [hideSingleSelectionIndicator]="hideSingleSelectionIndicator()">
<mat-button-toggle [value]="false">
<div class="d-flex align-items-center f-w-500">
<i-tabler name="layout-navbar" class="d-flex m-r-8 fill-icon"></i-tabler>
Full
</div>
</mat-button-toggle>
<mat-button-toggle [value]="true">
<div class="d-flex align-items-center f-w-500">
<i-tabler name="layout-sidebar" class="d-flex m-r-8 fill-icon"></i-tabler>
Boxed
</div>
</mat-button-toggle>
</mat-button-toggle-group>
</div>
</ng-scrollbar>
</div>

View File

@@ -0,0 +1,4 @@
.customizerNav {
width: 320px;
}

View File

@@ -0,0 +1,61 @@
import {
Component,
Output,
EventEmitter,
ViewEncapsulation,
signal,
} from '@angular/core';
import { AppSettings } from 'src/app/config';
import { CoreService } from 'src/app/services/core.service';
import { TablerIconsModule } from 'angular-tabler-icons';
import { MaterialModule } from 'src/app/material.module';
import { FormsModule } from '@angular/forms';
import { NgScrollbarModule } from 'ngx-scrollbar';
@Component({
selector: 'app-customizer',
imports: [
TablerIconsModule,
MaterialModule,
FormsModule,
NgScrollbarModule,
],
templateUrl: './customizer.component.html',
styleUrls: ['./customizer.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class CustomizerComponent {
options = this.settings.getOptions();
@Output() optionsChange = new EventEmitter<AppSettings>();
hideSingleSelectionIndicator = signal(true);
constructor(private settings: CoreService) { }
setDark() {
this.settings.setOptions({ theme: 'dark' });
this.emitOptions();
}
setColor(color: string) {
this.settings.setOptions({ activeTheme: color });
this.emitOptions();
}
setDir(dir: 'ltr' | 'rtl') {
this.settings.setOptions({ dir: dir });
this.emitOptions();
}
setSidebar(sidenavOpened: boolean) {
this.settings.setOptions({ sidenavOpened: sidenavOpened });
this.emitOptions();
}
private emitOptions() {
this.optionsChange.emit(this.options);
}
}

View File

@@ -0,0 +1,301 @@
<mat-toolbar class="topbar">
<!-- --------------------------------------------------------------- -->
<!-- Desktop Menu -->
@if(showToggle) {
<button
mat-icon-button
(click)="toggleCollapsed.emit()"
class="d-flex justify-content-center"
>
<i-tabler name="menu-2" class="icon-20 d-flex"></i-tabler>
</button>
}
<!-- Mobile Menu -->
@if(!showToggle) {
<button
mat-icon-button
(click)="toggleMobileNav.emit()"
class="d-flex justify-content-center"
>
<i-tabler name="menu-2" class="icon-20 d-flex"></i-tabler>
</button>
}
<!-- --------------------------------------------------------------- -->
<!-- --------------------------------------------------------------- -->
<!-- Search -->
<!-- --------------------------------------------------------------- -->
<button
mat-icon-button
(click)="openDialog()"
class="d-flex justify-content-center"
>
<i-tabler name="search" class="icon-20 d-flex"></i-tabler>
</button>
<div class="d-none d-lg-flex">
<!-- --------------------------------------------------------------- -->
<!-- Links -->
<!-- --------------------------------------------------------------- -->
<button
mat-button
[matMenuTriggerFor]="appsmenu"
aria-label="Notifications"
>
<div class="d-flex align-items-center">
Apps <i-tabler name="chevron-down" class="icon-16 m-l-4"></i-tabler>
</div>
</button>
<mat-menu #appsmenu="matMenu" class="apps-dd cardWithShadow">
<div class="row">
<div class="col-sm-8 b-r-1 p-r-0">
<div class="p-32 p-b-0">
<div class="row">
@for(appdd of apps; track appdd.title) {
<div class="col-sm-6 text-hover-primary">
<a
[routerLink]="[appdd.link]"
class="d-flex align-items-center text-decoration-none m-b-24"
>
<span
class="text-primary bg-light rounded icon-40 d-flex align-items-center justify-content-center"
>
<img [src]="appdd.img" width="20" />
</span>
<div class="m-l-16">
<h5
class="f-s-14 f-w-600 m-0 textprimary hover-text"
>
{{ appdd.title }}
</h5>
<span class="f-s-12 text-body">{{ appdd.subtitle }}</span>
</div>
</a>
</div>
}
</div>
</div>
<div
class="b-t-1 p-24 d-none d-lg-flex align-items-center justify-content-between"
>
<span
class="d-flex align-items-center f-s-16 f-w-500"
>
<i-tabler name="help" class="icon-20 m-r-8"></i-tabler>Frequently
Asked Questions
</span>
<a
[routerLink]="['/theme-pages/faq']"
mat-flat-button
color="primary"
>Check</a
>
</div>
</div>
<div class="col-sm-4">
<div class="p-x-16 p-y-32">
<h4 class="f-s-18 f-w-600 m-b-16">Quick Links</h4>
@for(quicklink of quicklinks; track quicklink.title) {
<div class="text-hover-primary">
<a
[routerLink]="[quicklink.link]"
class="hover-text text-decoration-none f-s-14 f-w-600 d-block p-y-8"
>{{ quicklink.title }}</a
>
</div>
}
</div>
</div>
</div>
</mat-menu>
<a mat-button [routerLink]="['/apps/chat']">Chat</a>
<a mat-button [routerLink]="['/apps/calendar']">Calendar</a>
<a mat-button [routerLink]="['/apps/email/inbox']">Email</a>
</div>
<span class="flex-1-auto"></span>
<!-- Mobile Menu -->
<button
mat-icon-button
(click)="toggleMobileFilterNav.emit()"
class="d-flex d-lg-none justify-content-center"
>
<i-tabler name="grid-dots" class="icon-20 d-flex"></i-tabler>
</button>
<!-- --------------------------------------------------------------- -->
<!-- langugage Dropdown -->
<!-- --------------------------------------------------------------- -->
<button [matMenuTriggerFor]="flags" mat-icon-button class="m-r-5">
<img
[src]="selectedLanguage.icon"
class="rounded-circle object-cover icon-20"
/>
</button>
<mat-menu #flags="matMenu" class="cardWithShadow">
@for(lang of languages; track lang.icon) {
<button mat-menu-item (click)="changeLanguage(lang)">
<div class="d-flex align-items-center">
<img
[src]="lang.icon"
class="rounded-circle object-cover m-r-8 icon-20"
/>
<span class=" f-s-14">{{ lang.language }}</span>
</div>
</button>
}
</mat-menu>
@if(options.theme=='light'){
<button mat-icon-button aria-label="lightdark" class="d-flex justify-content-center" (click)="setlightDark('dark')" >
<i-tabler class="d-flex icon-22" [name]="'moon'"></i-tabler>
</button>
}@else{
<button mat-icon-button aria-label="lightdark" class="d-flex justify-content-center" (click)="setlightDark('light')">
<i-tabler class="d-flex icon-22" [name]="'sun'"></i-tabler>
</button>
}
<!-- --------------------------------------------------------------- -->
<!-- Notification Dropdown -->
<!-- --------------------------------------------------------------- -->
<button
mat-icon-button matBadge="5"
[matMenuTriggerFor]="notificationmenu"
aria-label="Notifications" class="m-x-5 notification-badge"
>
<i-tabler
class="d-flex"
name="bell"
></i-tabler>
</button>
<mat-menu #notificationmenu="matMenu" class="topbar-dd cardWithShadow">
<div class="d-flex align-items-center p-x-32 p-y-16">
<h6 class="f-s-16 f-w-600 m-0 ">Notifications</h6>
<span class="m-l-auto">
<span class="bg-primary text-white p-x-8 p-y-4 f-w-500 rounded f-s-12"
>5 new</span
>
</span>
</div>
@for(notification of notifications; track notification.title) {
<button mat-menu-item class="p-x-32 p-y-16">
<div class="d-flex align-items-center">
<img [src]="notification.img" class="rounded-circle" width="48" />
<div class="m-l-16">
<h5 class="f-s-14 f-w-600 m-0 ">
{{ notification.title }}
</h5>
<span>{{ notification.subtitle }}</span>
</div>
</div>
</button>
}
<div class="p-y-12 p-x-32">
<button mat-stroked-button color="primary" class="w-100">
See all notifications
</button>
</div>
</mat-menu>
<!-- --------------------------------------------------------------- -->
<!-- profile Dropdown -->
<!-- --------------------------------------------------------------- -->
<button
mat-icon-button
[matMenuTriggerFor]="profilemenu"
aria-label="Notifications" class="m-l-8"
>
<img
src="/assets/images/profile/user-1.jpg"
class="rounded-circle object-cover icon-35 profile-dd"
width="35"
/>
</button>
<mat-menu #profilemenu="matMenu" class="topbar-dd cardWithShadow">
<ng-scrollbar class="position-relative" style="height: 647px">
<div class="p-x-32 p-y-16">
<h6 class="f-s-16 f-w-600 m-0 ">User Profile</h6>
<div class="d-flex align-items-center p-b-24 b-b-1 m-t-16">
<img
src="/assets/images/profile/user-1.jpg"
class="rounded-circle"
width="95"
/>
<div class="m-l-16">
<h6 class="f-s-14 f-w-600 m-0 ">Mathew Anderson</h6>
<span class="f-s-14 d-block m-b-4">Designer</span>
<span class="d-flex align-items-center">
<i-tabler name="mail" class="icon-15 m-r-4"></i-tabler>
info&#64;modernize.com
</span>
</div>
</div>
</div>
<div class="p-x-32">
@for(profile of profiledd; track profile.title) {
<a
class="p-y-16 text-decoration-none d-block text-hover-primary"
[routerLink]="[profile.link]"
>
<div class="d-flex align-items-center">
<button
mat-mini-fab
class="text-primary bg-light shadow-none rounded"
>
<img [src]="profile.img" width="20" />
</button>
<div class="m-l-16">
<h5
class="f-s-14 f-w-600 m-0 textprimary hover-text"
>
{{ profile.title }}
</h5>
<span class="f-s-14 text-body">{{ profile.subtitle }}</span>
</div>
</div>
</a>
}
<!-- upgrade -->
<div
class="p-24 overflow-hidden bg-light-primary rounded position-relative m-y-16"
>
<div class="d-flex align-items-center">
<div>
<h5 class="f-s-18 m-0 f-w-600 m-b-12 ">
Unlimited <br />
Access
</h5>
<button mat-flat-button color="primary">Upgrade</button>
</div>
<div class="m-l-auto">
<img
src="/assets/images/backgrounds/unlimited-bg.png"
alt="upgrade-bg"
class="upgrade-bg"
/>
</div>
</div>
</div>
</div>
<div class="p-y-12 p-x-32">
<a
[routerLink]="['/authentication/login']"
mat-stroked-button
color="primary"
class="w-100"
>Logout</a
>
</div>
</ng-scrollbar>
</mat-menu>
</mat-toolbar>

View File

@@ -0,0 +1,310 @@
import {
Component,
Output,
EventEmitter,
Input,
ViewEncapsulation,
} from '@angular/core';
import { CoreService } from 'src/app/services/core.service';
import { MatDialog } from '@angular/material/dialog';
import { navItems } from '../sidebar/sidebar-data';
import { TranslateService } from '@ngx-translate/core';
import { TablerIconsModule } from 'angular-tabler-icons';
import { MaterialModule } from 'src/app/material.module';
import { RouterModule } from '@angular/router';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { NgScrollbarModule } from 'ngx-scrollbar';
import { AppSettings } from 'src/app/config';
interface notifications {
id: number;
img: string;
title: string;
subtitle: string;
}
interface profiledd {
id: number;
img: string;
title: string;
subtitle: string;
link: string;
}
interface apps {
id: number;
img: string;
title: string;
subtitle: string;
link: string;
}
interface quicklinks {
id: number;
title: string;
link: string;
}
@Component({
selector: 'app-header',
imports: [
RouterModule,
CommonModule,
NgScrollbarModule,
TablerIconsModule,
MaterialModule,
],
templateUrl: './header.component.html',
encapsulation: ViewEncapsulation.None
})
export class HeaderComponent {
@Input() showToggle = true;
@Input() toggleChecked = false;
@Output() toggleMobileNav = new EventEmitter<void>();
@Output() toggleMobileFilterNav = new EventEmitter<void>();
@Output() toggleCollapsed = new EventEmitter<void>();
showFiller = false;
public selectedLanguage: any = {
language: 'English',
code: 'en',
type: 'US',
icon: '/assets/images/flag/icon-flag-en.svg',
};
public languages: any[] = [
{
language: 'English',
code: 'en',
type: 'US',
icon: '/assets/images/flag/icon-flag-en.svg',
},
{
language: 'Español',
code: 'es',
icon: '/assets/images/flag/icon-flag-es.svg',
},
{
language: 'Français',
code: 'fr',
icon: '/assets/images/flag/icon-flag-fr.svg',
},
{
language: 'German',
code: 'de',
icon: '/assets/images/flag/icon-flag-de.svg',
},
];
@Output() optionsChange = new EventEmitter<AppSettings>();
constructor(
private settings: CoreService,
private vsidenav: CoreService,
public dialog: MatDialog,
private translate: TranslateService
) {
translate.setDefaultLang('en');
}
options = this.settings.getOptions();
openDialog() {
const dialogRef = this.dialog.open(AppSearchDialogComponent);
dialogRef.afterClosed().subscribe((result) => {
console.log(`Dialog result: ${result}`);
});
}
private emitOptions() {
this.optionsChange.emit(this.options);
}
setlightDark(theme: string) {
this.options.theme = theme;
this.emitOptions();
}
changeLanguage(lang: any): void {
this.translate.use(lang.code);
this.selectedLanguage = lang;
}
notifications: notifications[] = [
{
id: 1,
img: '/assets/images/profile/user-1.jpg',
title: 'Roman Joined thes Team!',
subtitle: 'Congratulate him',
},
{
id: 2,
img: '/assets/images/profile/user-2.jpg',
title: 'New message received',
subtitle: 'Salma sent you new message',
},
{
id: 3,
img: '/assets/images/profile/user-3.jpg',
title: 'New Payment received',
subtitle: 'Check your earnings',
},
{
id: 4,
img: '/assets/images/profile/user-4.jpg',
title: 'Jolly completed tasks',
subtitle: 'Assign her new tasks',
},
{
id: 5,
img: '/assets/images/profile/user-5.jpg',
title: 'Roman Joined the Team!',
subtitle: 'Congratulatse him',
},
];
profiledd: profiledd[] = [
{
id: 1,
img: '/assets/images/svgs/icon-account.svg',
title: 'My Profile',
subtitle: 'Account Settings',
link: '/',
},
{
id: 2,
img: '/assets/images/svgs/icon-inbox.svg',
title: 'My Inbox',
subtitle: 'Messages & Email',
link: '/apps/email/inbox',
},
{
id: 3,
img: '/assets/images/svgs/icon-tasks.svg',
title: 'My Tasks',
subtitle: 'To-do and Daily Tasks',
link: '/apps/taskboard',
},
];
apps: apps[] = [
{
id: 1,
img: '/assets/images/svgs/icon-dd-chat.svg',
title: 'Chat Application',
subtitle: 'Messages & Emails',
link: '/apps/chat',
},
{
id: 2,
img: '/assets/images/svgs/icon-dd-cart.svg',
title: 'Todo App',
subtitle: 'Completed task',
link: '/apps/todo',
},
{
id: 3,
img: '/assets/images/svgs/icon-dd-invoice.svg',
title: 'Invoice App',
subtitle: 'Get latest invoice',
link: '/apps/invoice',
},
{
id: 4,
img: '/assets/images/svgs/icon-dd-date.svg',
title: 'Calendar App',
subtitle: 'Get Dates',
link: '/apps/calendar',
},
{
id: 5,
img: '/assets/images/svgs/icon-dd-mobile.svg',
title: 'Contact Application',
subtitle: '2 Unsaved Contacts',
link: '/apps/contacts',
},
{
id: 6,
img: '/assets/images/svgs/icon-dd-lifebuoy.svg',
title: 'Tickets App',
subtitle: 'Create new ticket',
link: '/apps/tickets',
},
{
id: 7,
img: '/assets/images/svgs/icon-dd-message-box.svg',
title: 'Email App',
subtitle: 'Get new emails',
link: '/apps/email/inbox',
},
{
id: 8,
img: '/assets/images/svgs/icon-dd-application.svg',
title: 'Conatct List',
subtitle: 'Create new contact',
link: '/apps/contact-list',
},
];
quicklinks: quicklinks[] = [
{
id: 1,
title: 'Pricing Page',
link: '/theme-pages/pricing',
},
{
id: 2,
title: 'Authentication Design',
link: '/authentication/login',
},
{
id: 3,
title: 'Register Now',
link: '/authentication/side-register',
},
{
id: 4,
title: '404 Error Page',
link: '/authentication/error',
},
{
id: 5,
title: 'Notes App',
link: '/apps/notes',
},
{
id: 6,
title: 'Employee App',
link: '/apps/employee',
},
{
id: 7,
title: 'Todo Application',
link: '/apps/todo',
},
{
id: 8,
title: 'Treeview',
link: '/theme-pages/treeview',
},
];
}
@Component({
selector: 'search-dialog',
imports: [RouterModule, MaterialModule, TablerIconsModule, FormsModule],
templateUrl: 'search-dialog.component.html'
})
export class AppSearchDialogComponent {
searchText: string = '';
navItems = navItems;
navItemsData = navItems.filter((navitem) => navitem.displayName);
// filtered = this.navItemsData.find((obj) => {
// return obj.displayName == this.searchinput;
// });
}

View File

@@ -0,0 +1,39 @@
<div class="p-24 p-b-0">
<div class="row">
<div class="col-10">
<mat-form-field
appearance="outline"
color="primary"
class="hide-hint w-100"
>
<input matInput placeholder="Search here" [(ngModel)]="searchText" />
</mat-form-field>
</div>
<div class="col-2 d-flex justify-content-end">
<button
mat-icon-button
mat-dialog-close
class="d-flex justify-content-center"
>
<i-tabler name="x" class="icon-18 d-flex"></i-tabler>
</button>
</div>
</div>
</div>
<mat-divider></mat-divider>
<mat-dialog-content class="mat-typography search-dialog">
<h4 class="f-s-18 f-w-600 m-b-16">Quick Page Links</h4>
@for(item of navItemsData; track item.displayName) {
<a
[routerLink]="[item.route]"
mat-dialog-close
class="p-y-12 text-decoration-none d-block"
>
<h5 class="f-s-14 f-w-500 d-block m-0">
{{ item.displayName }}
</h5>
<span class="f-s-12 f-s-16">{{ item.route }}</span>
</a>
}
</mat-dialog-content>

View File

@@ -0,0 +1,28 @@
import { Component } from '@angular/core';
import { CoreService } from 'src/app/services/core.service';
@Component({
selector: 'app-branding',
imports: [],
template: `
<a href="/" class="logodark">
<img
src="./assets/images/logos/dark-logo.svg"
class="align-middle m-2"
alt="logo"
/>
</a>
<a href="/" class="logolight">
<img
src="./assets/images/logos/light-logo.svg"
class="align-middle m-2"
alt="logo"
/>
</a>
`,
})
export class BrandingComponent {
options = this.settings.getOptions();
constructor(private settings: CoreService) {}
}

View File

@@ -0,0 +1,51 @@
@if(item.navCap){
<div mat-subheader class="nav-caption">
{{ item.navCap }}
</div>
} @if(!item.navCap && !item.external && !item.twoLines) {
<a mat-list-item (click)="onItemSelected(item)" [ngClass]="{
'mat-toolbar mat-primary activeMenu': item.route
? router.isActive(item.route, true)
: false,
expanded: expanded, activemenu: isChildActive(item),
disabled: item.disabled
}" class="menu-list-item">
<i-tabler class="routeIcon" name="{{ item.iconName }}" matListItemIcon></i-tabler>
<span class="hide-menu">{{ item.displayName | translate }}</span>
<div class="d-flex align-items-center gap-4">
@if(item.children && item.children.length) {
@if(item.chip) {
<span>
<span class="{{ item.chipClass }} p-x-8 p-y-4 item-chip f-w-500 rounded-pill ">{{ item.chipContent }}</span>
</span>
}
<span class="arrow-icon" fxFlex>
<span fxFlex></span>
<mat-icon [@indicatorRotate]="expanded ? 'expanded' : 'collapsed'">
expand_more
</mat-icon>
</span>
}
</div>
@if(item.chip && !item.children ) {
<span>
<span class="{{ item.chipClass }} p-x-8 p-y-4 item-chip f-w-500 rounded-pill ">{{ item.chipContent }}</span>
</span>
}
</a>
}
<!-- external Link -->
@if(!item.navCap && item.external) {
<mat-list-item onClick="window.open('//google.com')" class="menu-list-item" target="_blank">
<i-tabler class="routeIcon" name="{{ item.iconName }}" matListItemIcon></i-tabler>
<span class="hide-menu">{{ item.displayName | translate }}</span>
</mat-list-item>
}
<!-- children -->
@if(expanded) { @for(child of item.children; track child) {
<app-nav-item [item]="child" (click)="onSubItemSelected(child)" [depth]="depth + 1">
</app-nav-item>
} }

View File

@@ -0,0 +1,103 @@
import {
Component,
HostBinding,
Input,
OnInit,
OnChanges,
Output,
EventEmitter,
} from '@angular/core';
import { NavItem } from './nav-item';
import { Router } from '@angular/router';
import { NavService } from '../../../../../services/nav.service';
import {
animate,
state,
style,
transition,
trigger,
} from '@angular/animations';
import { TranslateModule } from '@ngx-translate/core';
import { TablerIconsModule } from 'angular-tabler-icons';
import { MaterialModule } from 'src/app/material.module';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-nav-item',
imports: [TranslateModule, TablerIconsModule, MaterialModule, CommonModule],
templateUrl: './nav-item.component.html',
styleUrls: [],
animations: [
trigger('indicatorRotate', [
state('collapsed', style({ transform: 'rotate(0deg)' })),
state('expanded', style({ transform: 'rotate(180deg)' })),
transition('expanded <=> collapsed', animate('225ms cubic-bezier(0.4,0.0,0.2,1)')),
]),
]
})
export class AppNavItemComponent implements OnChanges {
@Output() toggleMobileLink: any = new EventEmitter<void>();
@Output() notify: EventEmitter<boolean> = new EventEmitter<boolean>();
expanded: any = false;
disabled: any = false;
twoLines: any = false;
@HostBinding('attr.aria-expanded') ariaExpanded = this.expanded;
@Input() item: NavItem | any;
@Input() depth: any;
constructor(public navService: NavService, public router: Router) {
if (this.depth === undefined) {
this.depth = 0;
}
}
ngOnChanges() {
const url = this.navService.currentUrl();
if (this.item.route && url) {
this.expanded = url.indexOf(`/${this.item.route}`) === 0;
this.ariaExpanded = this.expanded;
}
}
onItemSelected(item: NavItem) {
if (!item.children || !item.children.length) {
this.router.navigate([item.route]);
}
if (item.children && item.children.length) {
this.expanded = !this.expanded;
}
//scroll
window.scroll({
top: 0,
left: 0,
behavior: 'smooth',
});
if (!this.expanded) {
if (window.innerWidth < 1024) {
this.notify.emit();
}
}
}
onSubItemSelected(item: NavItem) {
if (!item.children || !item.children.length) {
if (this.expanded && window.innerWidth < 1024) {
this.notify.emit();
}
}
}
isDirectlyActive(item: NavItem): boolean {
return !!item.route && this.router.isActive(item.route, true);
}
isChildActive(item: NavItem): boolean {
if (!item.children) return false;
return item.children.some(
(child) => this.isDirectlyActive(child) || this.isChildActive(child)
);
}
}

View File

@@ -0,0 +1,15 @@
export interface NavItem {
displayName?: string;
disabled?: boolean;
external?: boolean;
twoLines?: boolean;
chip?: boolean;
iconName?: string;
navCap?: string;
chipContent?: string;
chipClass?: string;
subtext?: string;
route?: string;
children?: NavItem[];
ddType?: string;
}

View File

@@ -0,0 +1,705 @@
import { NavItem } from './nav-item/nav-item';
export const navItems: NavItem[] = [
{
navCap: 'Home',
},
{
displayName: 'Analytical',
iconName: 'aperture',
route: '/dashboards/dashboard1',
},
{
displayName: 'eCommerce',
iconName: 'shopping-cart',
route: '/dashboards/dashboard2',
},
{
displayName: 'Frontend pages',
iconName: 'app-window',
route: 'front-pages',
children: [
{
displayName: 'Home Page',
iconName: 'point',
route: 'front-pages/homepage',
} ,
{
displayName: 'About Us',
iconName: 'point',
route: 'front-pages/about',
} ,
{
displayName: 'Blog',
iconName: 'point',
route: 'front-pages/blog',
} ,
{
displayName: 'Blog Details',
iconName: 'point',
route: 'front-pages/blog-details',
} ,
{
displayName: 'Portfolio',
iconName: 'point',
route: 'front-pages/portfolio',
},
{
displayName: 'Pricing',
iconName: 'point',
route: 'front-pages/pricing',
},
{
displayName: 'Contact',
iconName: 'point',
route: 'front-pages/contact',
}
]
},
{
navCap: 'Apps',
},
{
displayName: 'Chat',
iconName: 'message-2',
route: 'apps/chat',
},
{
displayName: 'Calendar',
iconName: 'calendar-event',
route: 'apps/calendar',
},
{
displayName: 'Email',
iconName: 'mail',
route: 'apps/email/inbox',
},
{
displayName: 'Kanban',
iconName: 'checklist',
route: 'apps/kanban',
},
{
displayName: 'User Profile',
iconName: 'user-circle',
route: 'apps/profile-details',
chip: true,
chipClass: 'bg-error text-white',
chipContent: 'New',
children: [
{
displayName: 'Profile',
iconName: 'point',
route: 'apps/profile-details/profile',
},
{
displayName: 'Followers',
iconName: 'point',
route: 'apps/profile-details/followers',
},
{
displayName: 'Friends',
iconName: 'point',
route: 'apps/profile-details/friends',
},
{
displayName: 'Gellary',
iconName: 'point',
route: 'apps/profile-details/gallery',
},
],
},
{
displayName: 'Ecommerce',
iconName: 'basket',
route: 'apps/product',
chip: true,
chipClass: 'border-error text-error',
chipContent: 'New',
children: [
{
displayName: 'Product List',
iconName: 'point',
route: 'apps/product/product-list',
},
{
displayName: 'Add Product',
iconName: 'point',
route: 'apps/product/add-product',
},
{
displayName: 'Edit Product',
iconName: 'point',
route: 'apps/product/edit-product',
},
{
displayName: 'Shop',
iconName: 'point',
route: 'apps/product/shop',
},
],
},
{
displayName: 'Contacts',
iconName: 'phone',
route: 'apps/contacts',
},
{
displayName: 'Courses',
iconName: 'certificate',
route: 'apps/courses',
},
{
displayName: 'Employee',
iconName: 'brand-ctemplar',
route: 'apps/employee',
},
{
displayName: 'Notes',
iconName: 'note',
route: 'apps/notes',
},
{
displayName: 'Tickets',
iconName: 'ticket',
route: 'apps/tickets',
},
{
displayName: 'Contact List',
iconName: 'phone',
route: 'apps/contact-list',
},
{
displayName: 'Invoice',
iconName: 'file-invoice',
route: 'apps/invoice',
children: [
{
displayName: 'List',
iconName: 'point',
route: 'apps/invoice/list',
},
{
displayName: 'Detail',
iconName: 'point',
route: 'apps/invoice/viewInvoice/101',
},
{
displayName: 'Create',
iconName: 'point',
route: 'apps/invoice/addInvoice',
},
{
displayName: 'Edit',
iconName: 'point',
route: 'apps/invoice/editinvoice/101',
},
],
},
{
displayName: 'ToDo',
iconName: 'edit',
route: 'apps/todo',
},
{
displayName: 'Blog',
iconName: 'chart-donut-3',
route: 'apps/blog',
children: [
{
displayName: 'Post',
iconName: 'point',
route: 'apps/blog/post',
},
{
displayName: 'Detail',
iconName: 'point',
route: 'apps/blog/detail/Early Black Friday Amazon deals: cheap TVs, headphones, laptops',
},
],
},
{
navCap: 'Pages',
},
{
displayName: 'Roll Base Access',
iconName: 'lock-access',
route: 'apps/permission',
},
{
displayName: 'Treeview',
iconName: 'git-merge',
route: 'theme-pages/treeview',
},
{
displayName: 'Pricing',
iconName: 'currency-dollar',
route: 'theme-pages/pricing',
},
{
displayName: 'Account Setting',
iconName: 'user-circle',
route: 'theme-pages/account-setting',
},
{
displayName: 'FAQ',
iconName: 'help',
route: 'theme-pages/faq',
},
{
displayName: 'Landingpage',
iconName: 'app-window',
route: 'landingpage',
},
{
displayName: 'Widgets',
iconName: 'layout',
route: 'widgets',
children: [
{
displayName: 'Cards',
iconName: 'point',
route: 'widgets/cards',
},
{
displayName: 'Banners',
iconName: 'point',
route: 'widgets/banners',
},
{
displayName: 'Charts',
iconName: 'point',
route: 'widgets/charts',
},
],
},
{
navCap: 'Forms',
},
{
displayName: 'Form elements',
iconName: 'apps',
route: 'forms/forms-elements',
children: [
{
displayName: 'Autocomplete',
iconName: 'point',
route: 'forms/forms-elements/autocomplete',
},
{
displayName: 'Button',
iconName: 'point',
route: 'forms/forms-elements/button',
},
{
displayName: 'Checkbox',
iconName: 'point',
route: 'forms/forms-elements/checkbox',
},
{
displayName: 'Radio',
iconName: 'point',
route: 'forms/forms-elements/radio',
},
{
displayName: 'Datepicker',
iconName: 'point',
route: 'forms/forms-elements/datepicker',
},
],
},
{
displayName: 'Form Layouts',
iconName: 'file-description',
route: '/forms/form-layouts',
},
{
displayName: 'Form Horizontal',
iconName: 'box-align-bottom',
route: '/forms/form-horizontal',
},
{
displayName: 'Form Vertical',
iconName: 'box-align-left',
route: '/forms/form-vertical',
},
{
displayName: 'Form Wizard',
iconName: 'files',
route: '/forms/form-wizard',
},
{
displayName: 'Toastr',
iconName: 'notification',
route: '/forms/form-toastr',
},
{
displayName: 'Editor',
iconName: 'edit',
route: '/forms/form-editor',
chip: true,
chipClass: 'bg-error text-white',
chipContent: 'New',
},
{
navCap: 'Tables',
},
{
displayName: 'Tables',
iconName: 'layout',
route: 'tables',
children: [
{
displayName: 'Basic Table',
iconName: 'point',
route: 'tables/basic-table',
},
{
displayName: 'Dynamic Table',
iconName: 'point',
route: 'tables/dynamic-table',
},
{
displayName: 'Expand Table',
iconName: 'point',
route: 'tables/expand-table',
},
{
displayName: 'Filterable Table',
iconName: 'point',
route: 'tables/filterable-table',
},
{
displayName: 'Footer Row Table',
iconName: 'point',
route: 'tables/footer-row-table',
},
{
displayName: 'HTTP Table',
iconName: 'point',
route: 'tables/http-table',
},
{
displayName: 'Mix Table',
iconName: 'point',
route: 'tables/mix-table',
},
{
displayName: 'Multi Header Footer',
iconName: 'point',
route: 'tables/multi-header-footer-table',
},
{
displayName: 'Pagination Table',
iconName: 'point',
route: 'tables/pagination-table',
},
{
displayName: 'Row Context Table',
iconName: 'point',
route: 'tables/row-context-table',
},
{
displayName: 'Selection Table',
iconName: 'point',
route: 'tables/selection-table',
},
{
displayName: 'Sortable Table',
iconName: 'point',
route: 'tables/sortable-table',
},
{
displayName: 'Sticky Column',
iconName: 'point',
route: 'tables/sticky-column-table',
},
{
displayName: 'Sticky Header Footer',
iconName: 'point',
route: 'tables/sticky-header-footer-table',
},
],
},
{
displayName: 'Data table',
iconName: 'border-outer',
route: '/datatable/kichen-sink',
},
{
navCap: 'Chart',
},
{
displayName: 'Line',
iconName: 'chart-line',
route: '/charts/line',
},
{
displayName: 'Gredient',
iconName: 'chart-arcs',
route: '/charts/gredient',
},
{
displayName: 'Area',
iconName: 'chart-area',
route: '/charts/area',
},
{
displayName: 'Candlestick',
iconName: 'chart-candle',
route: '/charts/candlestick',
},
{
displayName: 'Column',
iconName: 'chart-dots',
route: '/charts/column',
},
{
displayName: 'Doughnut & Pie',
iconName: 'chart-donut-3',
route: '/charts/doughnut-pie',
},
{
displayName: 'Radialbar & Radar',
iconName: 'chart-radar',
route: '/charts/radial-radar',
},
{
navCap: 'UI',
},
{
displayName: 'Ui Components',
iconName: 'box',
route: 'ui-components',
children: [
{
displayName: 'Badge',
iconName: 'point',
route: 'ui-components/badge',
},
{
displayName: 'Expansion Panel',
iconName: 'point',
route: 'ui-components/expansion',
},
{
displayName: 'Chips',
iconName: 'point',
route: 'ui-components/chips',
},
{
displayName: 'Dialog',
iconName: 'point',
route: 'ui-components/dialog',
},
{
displayName: 'Lists',
iconName: 'point',
route: 'ui-components/lists',
},
{
displayName: 'Divider',
iconName: 'point',
route: 'ui-components/divider',
},
{
displayName: 'Menu',
iconName: 'point',
route: 'ui-components/menu',
},
{
displayName: 'Paginator',
iconName: 'point',
route: 'ui-components/paginator',
},
{
displayName: 'Progress Bar',
iconName: 'point',
route: 'ui-components/progress',
},
{
displayName: 'Progress Spinner',
iconName: 'point',
route: 'ui-components/progress-spinner',
},
{
displayName: 'Ripples',
iconName: 'point',
route: 'ui-components/ripples',
},
{
displayName: 'Slide Toggle',
iconName: 'point',
route: 'ui-components/slide-toggle',
},
{
displayName: 'Slider',
iconName: 'point',
route: 'ui-components/slider',
},
{
displayName: 'Snackbar',
iconName: 'point',
route: 'ui-components/snackbar',
},
{
displayName: 'Tabs',
iconName: 'point',
route: 'ui-components/tabs',
},
{
displayName: 'Toolbar',
iconName: 'point',
route: 'ui-components/toolbar',
},
{
displayName: 'Tooltips',
iconName: 'point',
route: 'ui-components/tooltips',
},
],
},
{
navCap: 'Auth',
},
{
displayName: 'Login',
iconName: 'login',
route: '/authentication',
children: [
{
displayName: 'Login 1',
iconName: 'point',
route: '/authentication/login',
},
{
displayName: 'Boxed Login',
iconName: 'point',
route: '/authentication/boxed-login',
},
],
},
{
displayName: 'Register',
iconName: 'user-plus',
route: '/authentication',
children: [
{
displayName: 'Side Register',
iconName: 'point',
route: '/authentication/side-register',
},
{
displayName: 'Boxed Register',
iconName: 'point',
route: '/authentication/boxed-register',
},
],
},
{
displayName: 'Forgot Password',
iconName: 'rotate',
route: '/authentication',
children: [
{
displayName: 'Side Forgot Password',
iconName: 'point',
route: '/authentication/side-forgot-pwd',
},
{
displayName: 'Boxed Forgot Password',
iconName: 'point',
route: '/authentication/boxed-forgot-pwd',
},
],
},
{
displayName: 'Two Steps',
iconName: 'zoom-code',
route: '/authentication',
children: [
{
displayName: 'Side Two Steps',
iconName: 'point',
route: '/authentication/side-two-steps',
},
{
displayName: 'Boxed Two Steps',
iconName: 'point',
route: '/authentication/boxed-two-steps',
},
],
},
{
displayName: 'Error',
iconName: 'alert-circle',
route: '/authentication/error',
},
{
displayName: 'Maintenance',
iconName: 'settings',
route: '/authentication/maintenance',
},
{
navCap: 'Other',
},
{
displayName: 'Menu Level',
iconName: 'box-multiple',
route: '/menu-level',
children: [
{
displayName: 'Menu 1',
iconName: 'point',
route: '/menu-1',
children: [
{
displayName: 'Menu 1',
iconName: 'point',
route: '/menu-1',
},
{
displayName: 'Menu 2',
iconName: 'point',
route: '/menu-2',
},
],
},
{
displayName: 'Menu 2',
iconName: 'point',
route: '/menu-2',
},
],
},
{
displayName: 'Disabled',
iconName: 'ban',
route: '/disabled',
disabled: true,
},
{
displayName: 'Chip',
iconName: 'mood-smile',
route: '/',
chip: true,
chipClass: 'bg-primary text-white',
chipContent: '9',
},
{
displayName: 'Outlined',
iconName: 'mood-smile',
route: '/',
chip: true,
chipClass: 'bg-error text-white',
chipContent: 'outlined',
},
{
displayName: 'External Link',
iconName: 'star',
route: 'https://www.google.com/',
external: true,
},
];

View File

@@ -0,0 +1,15 @@
<div class="d-flex align-items-center justify-content-between">
<div class="branding">
<app-branding></app-branding>
</div>
@if(showToggle) {
<a
href="javascript:void(0)"
(click)="toggleMobileNav.emit()"
class="d-flex justify-content-center ng-star-inserted icon-40 align-items-center f-s-14"
>
<i-tabler name="x" class="icon-20 d-flex"></i-tabler>
</a>
}
</div>

View File

@@ -0,0 +1,25 @@
import {
Component,
EventEmitter,
Input,
OnInit,
Output,
ViewChild,
} from '@angular/core';
import { BrandingComponent } from './branding.component';
import { TablerIconsModule } from 'angular-tabler-icons';
import { MaterialModule } from 'src/app/material.module';
@Component({
selector: 'app-sidebar',
imports: [BrandingComponent, TablerIconsModule, MaterialModule],
templateUrl: './sidebar.component.html'
})
export class SidebarComponent implements OnInit {
constructor() { }
@Input() showToggle = true;
@Output() toggleMobileNav = new EventEmitter<void>();
@Output() toggleCollapsed = new EventEmitter<void>();
ngOnInit(): void { }
}

View File

@@ -0,0 +1,89 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
// Material Form Controls
import { MatAutocompleteModule } from '@angular/material/autocomplete';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatRadioModule } from '@angular/material/radio';
import { MatSelectModule } from '@angular/material/select';
import { MatSliderModule } from '@angular/material/slider';
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
// Material Navigation
import { MatMenuModule } from '@angular/material/menu';
import { MatSidenavModule } from '@angular/material/sidenav';
import { MatToolbarModule } from '@angular/material/toolbar';
// Material Layout
import { MatCardModule } from '@angular/material/card';
import { MatDividerModule } from '@angular/material/divider';
import { MatExpansionModule } from '@angular/material/expansion';
import { MatGridListModule } from '@angular/material/grid-list';
import { MatListModule } from '@angular/material/list';
import { MatStepperModule } from '@angular/material/stepper';
import { MatTabsModule } from '@angular/material/tabs';
import { MatTreeModule } from '@angular/material/tree';
// Material Buttons & Indicators
import { MatButtonModule } from '@angular/material/button';
import { MatButtonToggleModule } from '@angular/material/button-toggle';
import { MatBadgeModule } from '@angular/material/badge';
import { MatChipsModule } from '@angular/material/chips';
import { MatIconModule } from '@angular/material/icon';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatProgressBarModule } from '@angular/material/progress-bar';
import { MatRippleModule } from '@angular/material/core';
// Material Popups & Modals
import { MatBottomSheetModule } from '@angular/material/bottom-sheet';
import { MatDialogModule } from '@angular/material/dialog';
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { MatTooltipModule } from '@angular/material/tooltip';
// Material Data tables
import { MatPaginatorModule } from '@angular/material/paginator';
import { MatSortModule } from '@angular/material/sort';
import { MatTableModule } from '@angular/material/table';
@NgModule({
declarations: [],
imports: [
],
exports: [
MatAutocompleteModule,
MatCheckboxModule,
MatDatepickerModule,
MatFormFieldModule,
MatInputModule,
MatRadioModule,
MatSelectModule,
MatSliderModule,
MatSlideToggleModule,
MatMenuModule,
MatSidenavModule,
MatToolbarModule,
MatCardModule,
MatDividerModule,
MatExpansionModule,
MatGridListModule,
MatListModule,
MatStepperModule,
MatTabsModule,
MatTreeModule,
MatButtonModule,
MatButtonToggleModule,
MatBadgeModule,
MatChipsModule,
MatIconModule,
MatProgressSpinnerModule,
MatProgressBarModule,
MatRippleModule,
MatBottomSheetModule,
MatDialogModule,
MatSnackBarModule,
MatTooltipModule,
MatPaginatorModule,
MatSortModule,
MatTableModule,
],
})
export class MaterialModule {}

View File

@@ -0,0 +1,361 @@
import { Routes } from '@angular/router';
import { AppChatComponent } from './chat/chat.component';
import { AppEmailComponent } from './email/email.component';
import { DetailComponent } from './email/detail/detail.component';
import { AppCoursesComponent } from './courses/courses.component';
import { AppCourseDetailComponent } from './courses/course-detail/course-detail.component';
import { AppEmployeeComponent } from './employee/employee.component';
import { AppBlogsComponent } from './blogs/blogs.component';
import { AppBlogDetailsComponent } from './blogs/details/details.component';
import { AppContactComponent } from './contact/contact.component';
import { AppNotesComponent } from './notes/notes.component';
import { AppTodoComponent } from './todo/todo.component';
import { AppPermissionComponent } from './permission/permission.component';
import { AppKanbanComponent } from './kanban/kanban.component';
import { AppFullcalendarComponent } from './fullcalendar/fullcalendar.component';
import { AppTicketlistComponent } from './tickets/tickets.component';
import { AppInvoiceListComponent } from './invoice/invoice-list/invoice-list.component';
import { AppAddInvoiceComponent } from './invoice/add-invoice/add-invoice.component';
import { AppInvoiceViewComponent } from './invoice/invoice-view/invoice-view.component';
import { AppEditInvoiceComponent } from './invoice/edit-invoice/edit-invoice.component';
import { AppContactListComponent } from './contact-list/contact-list.component';
import { ProfileContentComponent } from './profile-content/profile-content.component';
import { FollowersComponent } from './profile-content/followers/followers.component';
import { GalleryComponent } from './profile-content/gallery/gallery.component';
import { FriendsComponent } from './profile-content/friends/friends.component';
import { ProductComponent } from './ecommerce/ecommerce.component';
import { AddProductComponent } from './ecommerce/add-product/add-product.component';
import { ProductDetailsComponent } from './ecommerce/product-details/product-details.component';
import { ShopComponent } from './ecommerce/shop/shop.component';
export const AppsRoutes: Routes = [
{
path: '',
children: [
{
path: 'chat',
component: AppChatComponent,
data: {
title: 'Chat',
urls: [
{ title: 'Dashboard', url: '/dashboards/dashboard1' },
{ title: 'Chat' },
],
},
},
{
path: 'calendar',
component: AppFullcalendarComponent,
data: {
title: 'Calendar',
urls: [
{ title: 'Dashboard', url: '/dashboards/dashboard1' },
{ title: 'Calendar' },
],
},
},
{
path: 'notes',
component: AppNotesComponent,
data: {
title: 'Notes',
urls: [
{ title: 'Dashboard', url: '/dashboards/dashboard1' },
{ title: 'Notes' },
],
},
},
{ path: 'email', redirectTo: 'email/inbox', pathMatch: 'full' },
{
path: 'email/:type',
component: AppEmailComponent,
data: {
title: 'Email',
urls: [
{ title: 'Dashboard', url: '/dashboards/dashboard1' },
{ title: 'Email' },
],
},
children: [
{
path: ':id',
component: DetailComponent,
data: {
title: 'Email Detail',
urls: [
{ title: 'Dashboard', url: '/dashboards/dashboard1' },
{ title: 'Email Detail' },
],
},
},
],
},
{
path: 'permission',
component: AppPermissionComponent,
data: {
title: 'Roll Base Access',
urls: [
{ title: 'Dashboard', url: '/dashboards/dashboard1' },
{ title: 'Roll Base Access' },
],
},
},
{
path: 'todo',
component: AppTodoComponent,
data: {
title: 'Todo App',
urls: [
{ title: 'Dashboard', url: '/dashboards/dashboard1' },
{ title: 'Todo App' },
],
},
},
{
path: 'kanban',
component: AppKanbanComponent,
data: {
title: 'Kanban',
urls: [
{ title: 'Dashboard', url: '/dashboards/dashboard1' },
{ title: 'Kanban' },
],
},
},
{
path: 'tickets',
component: AppTicketlistComponent,
data: {
title: 'Tickets',
urls: [
{ title: 'Dashboard', url: '/dashboards/dashboard1' },
{ title: 'Tickets' },
],
},
},
{
path: 'contacts',
component: AppContactComponent,
data: {
title: 'Contacts',
urls: [
{ title: 'Dashboard', url: '/dashboards/dashboard1' },
{ title: 'Contacts' },
],
},
},
{
path: 'courses',
component: AppCoursesComponent,
data: {
title: 'Courses',
urls: [
{ title: 'Dashboard', url: '/dashboards/dashboard1' },
{ title: 'Courses' },
],
},
},
{
path: 'contact-list',
component: AppContactListComponent,
data: {
title: 'Contact List',
urls: [
{ title: 'Dashboard', url: '/dashboards/dashboard1' },
{ title: 'Contact List' },
],
},
},
{
path: 'courses/coursesdetail/:id',
component: AppCourseDetailComponent,
data: {
title: 'Course Detail',
urls: [
{ title: 'Dashboard', url: '/dashboards/dashboard1' },
{ title: 'Course Detail' },
],
},
},
{
path: 'blog/post',
component: AppBlogsComponent,
data: {
title: 'Posts',
urls: [
{ title: 'Dashboard', url: '/dashboards/dashboard1' },
{ title: 'Posts' },
],
},
},
{
path: 'blog/detail/:id',
component: AppBlogDetailsComponent,
data: {
title: 'Blog Detail',
urls: [
{ title: 'Dashboard', url: '/dashboards/dashboard1' },
{ title: 'Blog Detail' },
],
},
},
{
path: 'employee',
component: AppEmployeeComponent,
data: {
title: 'Employee',
urls: [
{ title: 'Dashboard', url: '/dashboards/dashboard1' },
{ title: 'Employee' },
],
},
},
{
path: 'invoice/list',
component: AppInvoiceListComponent,
data: {
title: 'Invoice',
urls: [
{ title: 'Dashboard', url: '/dashboards/dashboard1' },
{ title: 'Invoice' },
],
},
},
{
path: 'invoice/addInvoice',
component: AppAddInvoiceComponent,
data: {
title: 'Add Invoice',
urls: [
{ title: 'Dashboard', url: '/dashboards/dashboard1' },
{ title: 'Add Invoice' },
],
},
},
{
path: 'invoice/viewInvoice/:id',
component: AppInvoiceViewComponent,
data: {
title: 'View Invoice',
urls: [
{ title: 'Dashboard', url: '/dashboards/dashboard1' },
{ title: 'View Invoice' },
],
},
},
{
path: 'invoice/editinvoice/:id',
component: AppEditInvoiceComponent,
data: {
title: 'Edit Invoice',
urls: [
{ title: 'Dashboard', url: '/dashboards/dashboard1' },
{ title: 'Edit Invoice' },
],
},
},
{
path: 'profile-details/profile',
component: ProfileContentComponent,
data: {
title: 'User Details',
urls: [
{ title: 'Dashboard', url: '/dashboards/dashboard1' },
{ title: 'User Details' },
],
},
},
{
path: 'profile-details/followers',
component: FollowersComponent,
data: {
title: 'Followers',
urls: [
{ title: 'Dashboard', url: '/dashboards/dashboard1' },
{ title: 'Followers' },
],
},
},
{
path: 'profile-details/friends',
component: FriendsComponent,
data: {
title: 'Friends',
urls: [
{ title: 'Dashboard', url: '/dashboards/dashboard1' },
{ title: 'Friends' },
],
},
},
{
path: 'profile-details/gallery',
component: GalleryComponent,
data: {
title: 'Gellary',
urls: [
{ title: 'Dashboard', url: '/dashboards/dashboard1' },
{ title: 'Gellary' },
],
},
},
{
path: 'product/product-list',
component: ProductComponent,
data: {
title: 'Product List',
urls: [
{ title: 'Dashboard', url: '/dashboards/dashboard1' },
{ title: 'Product List' },
],
},
},
{
path: 'product/add-product',
component: AddProductComponent,
data: {
title: 'Add Product',
urls: [
{ title: 'Dashboard', url: '/dashboards/dashboard1' },
{ title: 'Add Product' },
],
},
},
{
path: 'product/product-details',
component: ProductDetailsComponent,
data: {
title: 'Product Details',
urls: [
{ title: 'Dashboard', url: '/dashboards/dashboard1' },
{ title: 'Product Details' },
],
},
},
{
path: 'product/edit-product',
component: AddProductComponent,
data: {
title: 'Edit Product',
urls: [
{ title: 'Dashboard', url: '/dashboards/dashboard1' },
{ title: 'Edit Product' },
],
},
},
{
path: 'product/shop',
component: ShopComponent,
data: {
title: 'Shop',
urls: [
{ title: 'Dashboard', url: '/dashboards/dashboard1' },
{ title: 'Shop' },
],
},
},
],
},
];

View File

@@ -0,0 +1,139 @@
interface blogPosts {
id: number;
time: string;
imgSrc: string;
user: string;
title: string;
views: string;
category: string;
comments: number;
featuredPost: boolean;
date: string;
}
export const blogPosts: blogPosts[] = [
{
id: 1,
time: '2 mins Read',
imgSrc: '/assets/images/blog/blog-img1.jpg',
user: '/assets/images/profile/user-1.jpg',
title: 'Early Black Friday Amazon deals: cheap TVs, headphones, laptops',
views: '9,125',
category: 'Gadget',
comments: 3,
featuredPost: true,
date: 'Mon, Dec 25',
},
{
id: 2,
time: '2 mins Read',
imgSrc: '/assets/images/blog/blog-img2.jpg',
user: '/assets/images/profile/user-2.jpg',
title: 'Presented by Max Rushden with Barry Glendenning, Philippe Auclair',
views: '9,125',
category: 'Health',
comments: 3,
featuredPost: false,
date: 'Sun, Dec 25',
},
{
id: 3,
time: '2 mins Read',
imgSrc: '/assets/images/blog/blog-img3.jpg',
user: '/assets/images/profile/user-3.jpg',
title: 'As yen tumbles, gadget-loving Japan goes for secondhand iPhones',
views: '9,125',
category: 'Gadget',
comments: 12,
featuredPost: false,
date: 'Sat, Dec 25',
},
{
id: 4,
time: '2 mins Read',
imgSrc: '/assets/images/blog/blog-img4.jpg',
user: '/assets/images/profile/user-4.jpg',
title:
'Intel loses bid to revive antitrust case against patent foe Fortress',
views: '9,125',
category: 'Social',
comments: 12,
featuredPost: false,
date: 'Sat, Dec 25',
},
{
id: 5,
time: '2 mins Read',
imgSrc: '/assets/images/blog/blog-img5.jpg',
user: '/assets/images/profile/user-1.jpg',
title: 'COVID outbreak deepens as more lockdowns loom in China',
views: '9,125',
category: 'Lifestyle',
comments: 3,
featuredPost: false,
date: 'Mon, Dec 25',
},
{
id: 6,
time: '2 mins Read',
imgSrc: '/assets/images/blog/blog-img6.jpg',
user: '/assets/images/profile/user-2.jpg',
title: 'Streaming video way before it was cool, go dark tomorrow',
views: '9,125',
category: 'Health',
comments: 3,
featuredPost: false,
date: 'Sun, Dec 25',
},
{
id: 7,
time: '2 mins Read',
imgSrc: '/assets/images/blog/blog-img8.jpg',
user: '/assets/images/profile/user-3.jpg',
title:
'Apple is apparently working on a new streamlined accessibility iOS',
views: '9,125',
category: 'Design',
comments: 12,
featuredPost: false,
date: 'Sat, Dec 25',
},
{
id: 8,
time: '2 mins Read',
imgSrc: '/assets/images/blog/blog-img9.jpg',
user: '/assets/images/profile/user-4.jpg',
title: 'After Twitter Staff Cuts, Survivors Face Radio Silence',
views: '9,125',
category: 'Lifestyle',
comments: 12,
featuredPost: false,
date: 'Sat, Dec 25',
},
{
id: 9,
time: '2 mins Read',
imgSrc: '/assets/images/blog/blog-img10.jpg',
user: '/assets/images/profile/user-1.jpg',
title: 'Why Figma is selling to Adobe for $20 billion',
views: '9,125',
category: 'Design',
comments: 3,
featuredPost: false,
date: 'Mon, Dec 25',
},
{
id: 10,
time: '2 mins Read',
imgSrc: '/assets/images/blog/blog-img11.jpg',
user: '/assets/images/profile/user-2.jpg',
title: 'Garmins Instinct Crossover is a rugged hybrid smartwatch',
views: '9,125',
category: 'Gadget',
comments: 3,
featuredPost: false,
date: 'Sun, Dec 25',
},
];

View File

@@ -0,0 +1,110 @@
<div class="row">
@for(blogPost of blogService.getBlog(); track blogPost.user) {
<!-- ----------------------------------------------------------------- -->
<!-- If Feature Blog is available -->
<!-- ----------------------------------------------------------------- -->
@if(blogPost.featuredPost) {
<div
class="col-12 col-lg-4 col-xl-8"
[class.col-lg-8]="blogPost.featuredPost"
>
<mat-card
class="cardWithShadow position-relative card-hover featured-card overflow-hidden cursor-pointer"
(click)="selectBlog(blogPost.title)"
>
<img
mat-card-image
src="{{ blogPost.imgSrc }}"
alt="Photo of a Shiba Inu"
/>
<div
class="featured-overlay p-24 d-flex flex-col align-items-end justify-content-start"
>
<div class="d-flex align-items-center justify-content-between w-100">
<img src="{{ blogPost.user }}" class="rounded-circle" width="40" />
<span
class="f-s-12 f-w-600 bg-primary text-white rounded p-x-8 p-y-4"
>{{ blogPost.category }}</span
>
</div>
<div class="m-t-auto w-100">
<mat-card-title class="f-s-24 text-white">{{
blogPost.title
}}</mat-card-title>
<div
class="d-flex align-items-center justify-content-center m-t-24 text-white"
>
<div class="d-flex align-items-center gap-12">
<span class="f-s-14 d-flex align-items-center gap-4"
><i-tabler name="eye" class="icon-18"></i-tabler
>{{ blogPost.views }}</span
>
<span class="f-s-14 d-flex align-items-center gap-4"
><i-tabler name="message-2" class="icon-18"></i-tabler
>{{ blogPost.comments }}</span
>
</div>
<span class="m-l-auto f-s-14 d-flex align-items-center gap-4">
<i-tabler name="point" class="icon-14"></i-tabler>
{{ blogPost.date }}
</span>
</div>
</div>
</div>
</mat-card>
</div>
}
<!-- ----------------------------------------------------------------- -->
<!-- Else Simple Blog is available -->
<!-- ----------------------------------------------------------------- -->
@else {
<div class="col-sm-6 col-lg-4">
<mat-card
class="cardWithShadow position-relative card-hover cursor-pointer"
(click)="selectBlog(blogPost.title)"
>
<img
mat-card-image
src="{{ blogPost.imgSrc }}"
alt="Photo of a Shiba Inu"
/>
<div
class="card-overlay h-100 d-flex p-16 p-y-0 align-items-end justify-content-between"
>
<span class="f-s-12 m-y-16 f-w-600 bg-white rounded-pill p-x-8">{{
blogPost.category
}}</span>
<span class="f-s-12 f-w-600 m-y-16 bg-white rounded-pill p-x-8">{{
blogPost.time
}}</span>
</div>
<mat-card-content>
<div class="user-category">
<img src="{{ blogPost.user }}" class="rounded-circle" width="40" />
</div>
<mat-card-title class="mat-headline-6 m-t-15">{{
blogPost.title
}}</mat-card-title>
<div class="d-flex align-items-center justify-content-center m-t-24">
<div class="d-flex align-items-center gap-12">
<span class="f-s-14 d-flex align-items-center gap-4"
><i-tabler name="eye" class="icon-18"></i-tabler
>{{ blogPost.views }}</span
>
<span class="f-s-14 d-flex align-items-center gap-4"
><i-tabler name="message-2" class="icon-18"></i-tabler
>{{ blogPost.comments }}</span
>
</div>
<span class="m-l-auto f-s-14 d-flex align-items-center gap-4">
<i-tabler name="point" class="icon-14"></i-tabler>
{{ blogPost.date }}
</span>
</div>
</mat-card-content>
</mat-card>
</div>
} }
</div>

View File

@@ -0,0 +1,25 @@
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { blogService } from 'src/app/services/apps/blog/blog.service';
import { MatCardModule } from '@angular/material/card';
import { TablerIconsModule } from 'angular-tabler-icons';
import { MatChipsModule } from '@angular/material/chips';
@Component({
selector: 'app-blogs',
imports: [MatCardModule, TablerIconsModule, MatChipsModule],
templateUrl: './blogs.component.html'
})
export class AppBlogsComponent implements OnInit {
posts = this.blogService.getBlog();
constructor(public router: Router, public blogService: blogService) {}
selectBlog(title: string) {
this.blogService.selectBlogPost(title);
this.router.navigate(['apps/blog/detail', title]);
}
ngOnInit(): void {
console.log('Blog posts loaded:', this.posts);
}
}

View File

@@ -0,0 +1,226 @@
<!-- ----------------------------------------------------------------- -->
<!-- If Blog is available -->
<!-- ----------------------------------------------------------------- -->
@if(blogDetail()) {
<mat-card class="cardWithShadow">
<img
mat-card-image
src="{{ blogDetail()?.imgSrc }}"
alt="Photo of a Shiba Inu"
height="440"
/>
<div class="detail-card-overlay h-100 d-flex align-items-end justify-content-end">
<span
class="f-s-12 m-y-16 f-w-600 bg-white rounded-pill p-x-8 m-r-16"
>2 mins Read</span
>
</div>
<mat-card-content class="p-24 b-b-1">
<div class="user-category">
<div>
<img src="{{ blogDetail()?.user }}" class="rounded-circle" width="40" />
</div>
<span
class="f-s-12 m-y-16 f-w-600 rounded-pill p-x-8 p-y-4 d-inline-block bg-primary text-white"
>{{ blogDetail()?.category }}</span
>
</div>
<mat-card-title class="m-t-16 m-b-24 blog-title"
>{{ blogDetail()?.title }}
</mat-card-title>
<div class="d-flex align-items-center justify-content-center m-t-24">
<div class="d-flex align-items-center">
<span class="m-r-12 f-s-14 d-flex align-items-center"
><i-tabler name="eye" class="icon-18 m-r-4"></i-tabler
>{{ blogDetail()?.views }}</span
>
<span class="f-s-14 d-flex align-items-center"
><i-tabler name="message-2" class="icon-18 m-r-4"></i-tabler>4</span
>
</div>
<span class="m-l-auto f-s-14 d-flex align-items-center">
<i-tabler name="point" class="icon-14 m-r-4"></i-tabler>
{{ blogDetail()?.date }}
</span>
</div>
</mat-card-content>
<mat-card-content>
<h2 class="f-s-24 f-w-600 f-s-30">Title of the paragraph</h2>
<p class="f-s-14 m-t-16">
But you cannot figure out what it is or what it can do. MTA web directory
is the simplest way in which one can bid on a link, or a few links if they
wish to do so. The link directory on MTA displays all of the links it
currently has, and does so in alphabetical order, which makes it much
easier for someone to find what they are looking for if it is something
specific and they do not want to go through all the other sites and links
as well. It allows you to start your bid at the bottom and slowly work
your way to the top of the list.
</p>
<p class="f-s-14 m-t-16">
Gigure out what it is or what it can do. MTA web directory is the simplest
way in which one can bid on a link, or a few links if they wish to do so.
The link directory on MTA displays all of the links it currently has, and
does so in alphabetical order, which makes it much easier for someone to
find what they are looking for if it is something specific and they do not
want to go through all the other sites and links as well. It allows you to
start your bid at the bottom and slowly work your way to the top of the
</p>
<p class="f-s-14 m-t-16 f-w-600">This is strong text.</p>
<p class="f-s-14 m-t-4 f-w-500"><i>This is italic text.</i></p>
<mat-divider class="m-y-32"></mat-divider>
<h2 class="f-s-24 f-w-600">Unorder list.</h2>
<ul>
<li>Gigure out what it is or</li>
<li>The links it currently</li>
<li>It allows you to start your bid</li>
<li>Gigure out what it is or</li>
<li>The links it currently</li>
<li>It allows you to start your bid</li>
</ul>
<mat-divider class="m-y-32"></mat-divider>
<h2 class="f-s-24 f-w-600">Order list.</h2>
<ol>
<li>Gigure out what it is or</li>
<li>The links it currently</li>
<li>It allows you to start your bid</li>
<li>Gigure out what it is or</li>
<li>The links it currently</li>
<li>It allows you to start your bid</li>
</ol>
<mat-divider class="m-y-32"></mat-divider>
<h2 class="f-s-24 f-w-600">Quotes</h2>
<div class="p-24">
<h6 class="f-s-16 f-w-600">
<i-tabler name="quote" class="icon-24"></i-tabler> Life is short, Smile
while you still have teeth!
</h6>
</div>
</mat-card-content>
</mat-card>
}
<!-- ----------------------------------------------------------------- -->
<!-- If Blog isn't available -->
<!-- ----------------------------------------------------------------- -->
@if (!blogDetail() || blogDetail().length === 0) {
<mat-card class="cardWithShadow">
<mat-card-content>
<p>No blog post available.</p>
</mat-card-content>
</mat-card>
}
<mat-card class="cardWithShadow">
<mat-card-content>
<mat-card-title class="m-b-24 f-s-21">Post Comments</mat-card-title>
<form>
<mat-form-field appearance="outline" class="w-100">
<textarea matInput rows="5"></textarea>
</mat-form-field>
<button mat-flat-button color="primary">Post Button</button>
</form>
<mat-card-title class="m-t-30 f-s-21 p-t-24 d-flex align-items-center"
>Comments
<span
class="text-primary p-x-12 p-y-4 rounded bg-light-primary f-w-600 m-l-8 f-s-18"
>4</span
></mat-card-title
>
<!-- ----------------------------------------------------------------- -->
<!-- comment -->
<!-- ----------------------------------------------------------------- -->
<div class="bg-light rounded p-24 m-t-24">
<div class="d-flex align-items-center">
<img
src="/assets/images/profile/user-2.jpg"
alt="user"
width="35"
class="rounded-circle"
/>
<span class="f-s-16 f-w-600 m-l-12">Charlie Hamilton</span>
<span class="m-l-12 f-s-12 d-flex align-items-center">
<i-tabler
class="icon-7 op-5 d-flex m-r-4"
name="circle-filled"
></i-tabler>
now
</span>
</div>
<p class="f-s-14 m-t-16">
Jigho tabkubho nira carudi ganlac milza dekpo putog iptodok tuhral canse
mi rega ujnuf kukfag osailu bis oca. Gegeholo hata sogi kod bihdelsa
nege evinog mes loz perdutace kehlondip im fep wiven fefu fi tigfiso.
</p>
<button
mat-mini-fab
class="bg-primary text-white icon-30 m-t-16"
matTooltip="Reply"
(click)="toggleReply()"
>
<i-tabler name="arrow-back-up" class="icon-18 d-flex"></i-tabler>
</button>
</div>
<!-- ----------------------------------------------------------------- -->
<!-- add comment -->
<!-- ----------------------------------------------------------------- -->
<div [hidden]="istoggleReply()">
<form class="d-flex align-items-center m-y-24">
<img
src="/assets/images/profile/user-1.jpg"
alt="user"
width="35"
class="rounded-circle"
/>
<mat-form-field appearance="outline" class="w-100 hide-hint m-l-16">
<input matInput placeholder="Reply" />
</mat-form-field>
<button mat-flat-button color="primary" class="m-l-16">Reply</button>
</form>
</div>
<!-- ----------------------------------------------------------------- -->
<!-- comment -->
<!-- ----------------------------------------------------------------- -->
<div class="bg-light rounded p-24 m-t-24 m-l-24">
<div class="d-flex align-items-center">
<img
src="/assets/images/profile/user-3.jpg"
alt="user"
width="35"
class="rounded-circle"
/>
<span class="f-s-16 f-w-600 m-l-12">Ethan Gordon</span>
<span class="m-l-12 f-s-12 d-flex align-items-center">
<i-tabler
class="icon-7 op-5 d-flex m-r-4"
name="circle-filled"
></i-tabler>
now
</span>
</div>
<p class="f-s-14 m-t-16">
Diprow wir hilohi ilmi fumow oc co cop iv gi ize tamiv kulok. Bam ci
urkati ul negu ovga hivwe toubugof gok imro ale sujoh saput.
</p>
<button
mat-mini-fab
class="bg-primary text-white icon-30 m-t-16"
matTooltip="Reply"
(click)="toggleReply()"
>
<i-tabler name="arrow-back-up" class="icon-18 d-flex"></i-tabler>
</button>
</div>
</mat-card-content>
</mat-card>

View File

@@ -0,0 +1,48 @@
import { Component, OnInit, signal } from '@angular/core';
import { blogService } from 'src/app/services/apps/blog/blog.service';
import { ActivatedRoute, Router } from '@angular/router';
import { MatCardModule } from '@angular/material/card';
import { MatChipsModule } from '@angular/material/chips';
import { TablerIconsModule } from 'angular-tabler-icons';
import { MatDividerModule } from '@angular/material/divider';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatButtonModule } from '@angular/material/button';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-blog-details',
imports: [
MatCardModule,
MatChipsModule,
TablerIconsModule,
MatDividerModule,
MatFormFieldModule,
MatInputModule,
MatButtonModule,
CommonModule,
],
templateUrl: './details.component.html',
})
export class AppBlogDetailsComponent implements OnInit {
title = signal<string | any>(null);
blogDetail = signal<any>(null);
istoggleReply = signal<boolean>(true);
activeRoute: any = this.router.url.split('/').pop();
constructor(
public router: Router,
activatedRouter: ActivatedRoute,
public blogService: blogService
) {
this.title.set(activatedRouter.snapshot.paramMap.get('id'));
}
ngOnInit(): void {
const posts = this.blogService.getBlog();
this.blogDetail.set(posts.find((post) => post.title === this.title()));
}
toggleReply() {
this.istoggleReply.set(!this.istoggleReply());
}
}

View File

@@ -0,0 +1,123 @@
<mat-card class="chat-app cardWithShadow">
<mat-sidenav-container [ngClass]="{
'side-panel-opened': sidePanelOpened,
'side-panel-closed': !sidePanelOpened
}">
<!-- ---------------------------------------------------- -->
<!-- sidebar -->
<!-- ---------------------------------------------------- -->
<mat-sidenav [mode]="isOver() ? 'over' : 'side'" [opened]="sidePanelOpened" (open)="sidePanelOpened = true"
(close)="sidePanelOpened = false">
<ng-scrollbar class="position-relative" style="height: 100%">
<div class="d-flex align-items-center p-24 gap-16">
<img src="assets/images/profile/user-1.jpg" class="rounded-circle" width="54" />
<div>
<h4 class="f-s-16 f-w-600">Mathew Anderson</h4>
<span class="f-s-12">info&#64;modernize.com</span>
</div>
</div>
<div class="p-x-24">
<!-- search -->
<mat-form-field appearance="outline" class="w-100">
<input matInput placeholder="Search Contacts" [(ngModel)]="searchTerm" (input)="searchMessages()" />
<mat-icon matSuffix>
<i-tabler name="search" class="icon-20 d-flex align-items-end m-t-2"></i-tabler>
</mat-icon>
</mat-form-field>
</div>
@if (filteredMessages() && filteredMessages().length > 0) {
<div class="m-x-24">
<mat-nav-list class="chat-listing">
@for(message of filteredMessages(); track message.from) {
<mat-list-item role="listitem" (click)="selectMessage(message)"
[class.bg-light-primary]="message === selectedMessage()" class="m-b-2 gap-12">
<span matListItemIcon>
<img src="{{ message.photo }}" alt="" width="42" class="rounded-circle" />
</span>
<h3 class="f-w-600 f-s-16" matListItemTitle>
{{ message.from }}
</h3>
<p class="f-s-14 m-t-4" matListItemLine>
{{ message.subject }}
</p>
</mat-list-item>
}
</mat-nav-list>
</div>
} @else {
<div class="p-15 bg-light-primary text-primary rounded m-x-20 m-t-20 text-center">
<span class="f-s-14">No messages found.</span>
</div>
}
</ng-scrollbar>
</mat-sidenav>
<mat-sidenav-content>
<!-- ------------------------------------------- -->
<!-- chat details -->
<!-- ------------------------------------------- -->
<mat-toolbar class="chat-right-panel d-flex align-items-center b-b-1 gap-8">
<button (click)="sidePanelOpened = !sidePanelOpened" mat-icon-button>
<mat-icon>short_text</mat-icon>
</button>
<div class="d-flex align-items-center gap-16">
<img src="{{ selectedMessage()?.photo }}" width="40" class="rounded-circle" />
<div class="f-s-16 f-w-600">
{{ selectedMessage()?.from }}
</div>
</div>
<button [matMenuTriggerFor]="moredd" class="m-l-auto" mat-icon-button>
<mat-icon>more_vert</mat-icon>
</button>
<mat-menu #moredd="matMenu" x-position="before">
<button mat-menu-item>Contact info</button>
<button mat-menu-item>Mute</button>
<button mat-menu-item>Delete chat</button>
</mat-menu>
</mat-toolbar>
<!-- ------------------------------------------- -->
<!-- chat content -->
<!-- ------------------------------------------- -->
<ng-scrollbar style="height: calc(100vh - 442px)" class="position-relative">
<mat-card-content class="chat-middle-box p-24">
@for(c of selectedMessage()?.chat; track c) { @if(c.type === 'odd') {
<div class="chat-list odd">
<div class="m-b-15">
<div class="bg-light-primary p-10 rounded d-flex align-items-center gap-16">
<img src="{{ selectedMessage()?.photo }}" class="rounded-circle" width="40" />
<span class="f-s-14">{{ c.msg }}</span>
</div>
<span class="f-s-12">
{{ c.date | date }}
</span>
</div>
</div>
} @else {
<div class="chat-list even">
<div class="m-b-15">
<div class="bg-light-secondary p-10 rounded d-flex align-items-center f-s-14">
{{ c.msg }}
</div>
<span class="f-s-12">
{{ c.date | date }}
</span>
</div>
</div>
} }
</mat-card-content>
</ng-scrollbar>
<mat-divider></mat-divider>
<div class="p-t-20 p-x-24">
<mat-form-field appearance="outline" class="w-100">
<input matInput placeholder="Send message" [ngModel]="msg()" (ngModelChange)="msg.set($event)"
(keydown.enter)="sendMessage()" />
<button mat-icon-button matSuffix (click)="sendMessage()" [disabled]="!msg">
<mat-icon>send</mat-icon>
</button>
</mat-form-field>
</div>
</mat-sidenav-content>
</mat-sidenav-container>
</mat-card>

View File

@@ -0,0 +1,85 @@
import { Component, signal, ViewChild } from '@angular/core';
import { CommonModule } from '@angular/common';
import { NgScrollbarModule } from 'ngx-scrollbar';
import { TablerIconsModule } from 'angular-tabler-icons';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MaterialModule } from 'src/app/material.module';
import { ChatService } from 'src/app/services/apps/chat/chat.service';
import { Message } from 'src/app/pages/apps/chat/chat';
@Component({
selector: 'app-chat',
imports: [
CommonModule,
NgScrollbarModule,
TablerIconsModule,
FormsModule,
ReactiveFormsModule,
MaterialModule,
],
templateUrl: './chat.component.html',
})
export class AppChatComponent {
sidePanelOpened = true;
//input feild for new msg
msg = signal('');
// MESSAGE
selectedMessage = signal<Message | null>(null);
messages = signal<Message[]>([]);
filteredMessages = signal<Message[]>([]);
searchTerm = signal('');
// tslint:disable-next-line - Disables all
constructor(private chatService: ChatService) {}
isOver(): boolean {
return window.matchMedia(`(max-width: 960px)`).matches;
}
ngOnInit() {
this.messages.set(this.chatService.messages());
this.filteredMessages.set(this.messages());
this.selectedMessage.set(this.chatService.selectedMessage());
if (this.isOver()) {
// Check if the screen is small
this.sidePanelOpened = false; // Close the sidebar
}
}
// tslint:disable-next-line - Disables all
selectMessage(message: Message): void {
this.selectedMessage.set(message);
if (this.isOver()) {
// Check if the screen is small
this.sidePanelOpened = false; // Close the sidebar
}
}
sendMessage(): void {
const currentSelectedMessage = this.selectedMessage();
if (currentSelectedMessage) {
this.chatService.sendMessage(currentSelectedMessage, this.msg());
this.msg.set('');
}
}
searchMessages(): void {
this.filteredMessages.set(
this.searchTerm().trim()
? this.messages().filter((message) =>
message.from.toLowerCase().includes(this.searchTerm().toLowerCase())
)
: this.messages()
);
}
}

View File

@@ -0,0 +1,7 @@
export interface Message {
id: string;
from: string;
subject: string;
photo: string;
chat: { type: string; msg: string; date: Date }[];
}

View File

@@ -0,0 +1,263 @@
export const messages = [
{
id: '1',
from: 'James Johnson',
photo: 'assets/images/profile/user-2.jpg',
subject: 'Hey, how are you?',
chat: [
{
type: 'odd',
msg: 'Hi Luke.',
date: new Date('2025-01-05'),
},
{
type: 'odd',
msg: 'How are you my friend?',
date: new Date('2025-01-06'),
},
{
type: 'even',
msg: 'I am good and what about you?',
date: new Date('2025-01-07'),
},
{
type: 'odd',
msg: 'Lorem Ipsum is simply dummy text of the printing & type setting industry.',
date: new Date('2025-01-08'),
},
{
type: 'even',
msg: 'I would love to join the team.',
date: new Date('2025-01-09'),
},
{
type: 'odd',
msg: 'Well we have good budget for the project.',
date: new Date('2025-01-10'),
},
],
},
{
id: '2',
from: 'Maria Hernandez',
photo: 'assets/images/profile/user-3.jpg',
subject: 'Lorem ipsum done',
chat: [
{
type: 'odd',
msg: 'this is odd2',
date: new Date('2025-01-10'),
},
{
type: 'even',
msg: 'this is even2',
date: new Date('2025-01-10'),
},
{
type: 'odd',
msg: 'Simply dummy text of the printing & type setting industry.',
date: new Date('2025-01-08'),
},
{
type: 'even',
msg: 'Love to join the team.',
date: new Date('2025-01-09'),
},
{
type: 'odd',
msg: 'Have good budget for the project.',
date: new Date('2025-01-10'),
},
],
},
{
id: '3',
from: 'David Smith',
photo: 'assets/images/profile/user-4.jpg',
subject: 'Thanks mate',
chat: [
{
type: 'odd',
msg: 'Hi Luke.',
date: new Date('2025-01-05'),
},
{
type: 'odd',
msg: 'How are you my friend?',
date: new Date('2025-01-06'),
},
{
type: 'even',
msg: 'I am good and what about you?',
date: new Date('2025-01-07'),
},
{
type: 'odd',
msg: 'Lorem Ipsum is simply dummy text of the printing & type setting industry.',
date: new Date('2025-01-08'),
},
{
type: 'even',
msg: 'I would love to join the team.',
date: new Date('2025-01-09'),
},
{
type: 'odd',
msg: 'Well we have good budget for the project.',
date: new Date('2025-01-10'),
},
],
},
{
id: '4',
from: 'Maria Rodriguez',
photo: 'assets/images/profile/user-5.jpg',
subject: 'This is my shot',
chat: [
{
type: 'odd',
msg: 'this is odd',
date: new Date('2025-01-10'),
},
{
type: 'even',
msg: 'this is even',
date: new Date('2025-01-10'),
},
{
type: 'odd',
msg: 'this is odd',
date: new Date('2025-01-10'),
},
{
type: 'even',
msg: 'this is even',
date: new Date('2025-01-10'),
},
{
type: 'odd',
msg: 'this is odd',
date: new Date('2025-01-10'),
},
{
type: 'even',
msg: 'this is even',
date: new Date('2025-01-10'),
},
],
},
{
id: '5',
from: 'Robert Smith',
photo: 'assets/images/profile/user-6.jpg',
subject: 'You have to do it..',
chat: [
{
type: 'odd',
msg: 'this is odd',
date: new Date('2025-01-10'),
},
{
type: 'even',
msg: 'this is even',
date: new Date('2025-01-10'),
},
{
type: 'odd',
msg: 'this is odd',
date: new Date('2025-01-10'),
},
{
type: 'even',
msg: 'this is even',
date: new Date('2025-01-10'),
},
{
type: 'odd',
msg: 'this is odd',
date: new Date('2025-01-10'),
},
{
type: 'even',
msg: 'this is even',
date: new Date('2025-01-10'),
},
],
},
{
id: '6',
from: 'Joseph Sarah',
photo: 'assets/images/profile/user-7.jpg',
subject: 'No mate this is not',
chat: [
{
type: 'odd',
msg: 'this is odd',
date: new Date('2025-01-10'),
},
{
type: 'even',
msg: 'this is even',
date: new Date('2025-01-10'),
},
{
type: 'odd',
msg: 'this is odd',
date: new Date('2025-01-10'),
},
{
type: 'even',
msg: 'this is even',
date: new Date('2025-01-10'),
},
{
type: 'odd',
msg: 'this is odd',
date: new Date('2025-01-10'),
},
{
type: 'even',
msg: 'this is even',
date: new Date('2025-01-10'),
},
],
},
{
id: '7',
from: 'Thomas Smith',
photo: 'assets/images/profile/user-8.jpg',
subject: 'How are you my friend?',
chat: [
{
type: 'odd',
msg: 'this is odd',
date: new Date('2025-01-10'),
},
{
type: 'even',
msg: 'this is even',
date: new Date('2025-01-10'),
},
{
type: 'odd',
msg: 'this is odd',
date: new Date('2025-01-10'),
},
{
type: 'even',
msg: 'this is even',
date: new Date('2025-01-10'),
},
{
type: 'odd',
msg: 'this is odd',
date: new Date('2025-01-10'),
},
{
type: 'even',
msg: 'this is even',
date: new Date('2025-01-10'),
},
],
},
];

View File

@@ -0,0 +1,133 @@
<!-- ------------------------------------------------------------------ -->
<!-- Add new contact -->
<!-- ------------------------------------------------------------------ -->
<mat-dialog-content class="mat-typography">
<div class="d-flex align-items-center justify-content-between m-b-16">
<h4 class="f-s-16 f-w-600 m-b-16">Add New Contact</h4>
<button
mat-icon-button
mat-dialog-close
class="d-flex justify-content-center"
>
<i-tabler name="x" class="icon-20 d-flex"></i-tabler>
</button>
</div>
<form>
<div class="file-input-container m-b-24 position-relative uploader">
@if(imageUrl){
<img
[src]="imageUrl"
alt="Selected Image"
width="100"
class="rounded upload-image"
/>
}
<input type="file" (change)="onFileSelected($event)" accept="image/*" />
</div>
<div class="row">
<div class="col-md-6">
<mat-label class="f-s-14 f-w-600 m-b-8 d-block">First Name</mat-label>
<mat-form-field appearance="outline" class="w-100">
<input
matInput
[(ngModel)]="contact.firstname"
name="firstname"
placeholder="First Name"
/>
</mat-form-field>
</div>
<div class="col-md-6">
<mat-label class="f-s-14 f-w-600 m-b-8 d-block">Last Name</mat-label>
<mat-form-field appearance="outline" class="w-100">
<input
matInput
[(ngModel)]="contact.lastname"
name="lastname"
placeholder="Last Name"
/>
</mat-form-field>
</div>
<div class="col-md-6">
<mat-label class="f-s-14 f-w-600 m-b-8 d-block">Company Name</mat-label>
<mat-form-field appearance="outline" class="w-100">
<input
matInput
[(ngModel)]="contact.company"
name="company"
placeholder="Company Name"
/>
</mat-form-field>
</div>
<div class="col-md-6">
<mat-label class="f-s-14 f-w-600 m-b-8 d-block">Phone Number</mat-label>
<mat-form-field appearance="outline" class="w-100">
<input
matInput
[(ngModel)]="contact.phone"
name="phone"
placeholder="Phone Number"
/>
</mat-form-field>
</div>
<div class="col-md-6">
<mat-label class="f-s-14 f-w-600 m-b-8 d-block">Email</mat-label>
<mat-form-field appearance="outline" class="w-100">
<input
matInput
[(ngModel)]="contact.email"
name="email"
type="email"
placeholder="Email"
/>
</mat-form-field>
</div>
<div class="col-md-6">
<mat-label class="f-s-14 f-w-600 m-b-8 d-block">Address</mat-label>
<mat-form-field appearance="outline" class="w-100">
<input
matInput
[(ngModel)]="contact.address"
name="address"
placeholder="Address"
/>
</mat-form-field>
</div>
<div class="col-12">
<mat-label class="f-s-14 f-w-600 m-b-8 d-block">Notes</mat-label>
<mat-form-field appearance="outline" class="w-100">
<textarea
matInput
[(ngModel)]="contact.notes"
name="notes"
placeholder="Notes"
></textarea>
</mat-form-field>
</div>
<div class="col-12">
<mat-label class="f-s-14 f-w-600 m-b-8 d-block">Department</mat-label>
<mat-form-field appearance="outline" class="w-100">
<mat-select [(ngModel)]="contact.department" name="department">
@for(dept of departments; track dept.id) {
<mat-option [value]="dept.name">{{ dept.name }}</mat-option>
}
</mat-select>
</mat-form-field>
</div>
</div>
</form>
</mat-dialog-content>
<div mat-dialog-actions>
<button
mat-flat-button
color="primary"
(click)="saveContact()"
[disabled]="!isFormValid()"
>
Add Contact
</button>
<button mat-flat-button class="bg-error text-white" (click)="cancel()">
Cancel
</button>
</div>

View File

@@ -0,0 +1,81 @@
import { Component } from '@angular/core';
import { MatDialogRef } from '@angular/material/dialog';
import { MaterialModule } from 'src/app/material.module';
import { FormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';
import { MatSnackBar } from '@angular/material/snack-bar';
import { TablerIconsModule } from 'angular-tabler-icons';
@Component({
selector: 'app-contact-form-dialog',
templateUrl: './contact-form-dialog.component.html',
imports: [MaterialModule, CommonModule, FormsModule, TablerIconsModule],
})
export class ContactFormDialogComponent {
contact = {
firstname: '',
lastname: '',
image: '',
company: '',
phone: '',
email: '',
address: '',
notes: '',
department: '',
};
departments = [
{ id: 1, name: 'Support' },
{ id: 2, name: 'Engineering' },
{ id: 3, name: 'Sales' },
];
defaultImageUrl = 'assets/images/profile/user-4.jpg';
imageUrl: string | ArrayBuffer | null = this.defaultImageUrl;
constructor(
public dialogRef: MatDialogRef<ContactFormDialogComponent>,
private snackBar: MatSnackBar
) {}
saveContact(): void {
this.contact.image = this.imageUrl as string;
this.dialogRef.close(this.contact);
this.snackBar.open(
`${this.contact.firstname} ${this.contact.lastname} added successfully!`,
'Close',
{
duration: 3000,
horizontalPosition: 'center',
verticalPosition: 'top',
}
);
}
cancel(): void {
this.dialogRef.close();
}
onFileSelected(event: Event): void {
const file = (event.target as HTMLInputElement).files?.[0];
if (file) {
const reader = new FileReader();
reader.onload = () => {
this.imageUrl = reader.result;
};
reader.readAsDataURL(file);
}
}
isFormValid(): any {
return (
this.contact.firstname &&
this.contact.lastname &&
this.contact.company &&
this.contact.phone &&
this.contact.email &&
this.contact.address &&
this.contact.department
);
}
}

View File

@@ -0,0 +1,3 @@
<div>
<app-listing></app-listing>
</div>

View File

@@ -0,0 +1,11 @@
import { Component } from '@angular/core';
import { AppListingComponent } from 'src/app/pages/apps/contact-list/listing/listing.component';
import { MaterialModule } from 'src/app/material.module';
import { TablerIconsModule } from 'angular-tabler-icons';
@Component({
selector: 'app-contact-list',
imports: [AppListingComponent, TablerIconsModule, MaterialModule],
templateUrl: './contact-list.component.html',
})
export class AppContactListComponent {}

View File

@@ -0,0 +1,17 @@
export class ContactBox {
constructor(
public id: number | string,
public firstname: string,
public lastname: string,
public image: string,
public department: string,
public company: string,
public phone: string,
public email: string,
public address: string,
public notes: string,
public frequentlycontacted: boolean,
public starred: boolean,
public deleted: boolean,
){}
}

View File

@@ -0,0 +1,471 @@
import { ContactBox } from './contact-list';
import { Chance } from 'chance';
const chance = new Chance();
export const ContactList: ContactBox[] = [
{
id: 1,
firstname: 'Georgeanna',
lastname: 'Ramero',
image: 'assets/images/profile/user-4.jpg',
department: 'Sales',
company: 'Muller Inc',
phone: '456-485-5623',
email: 'qq739v47ggn@claimab.com',
address: '19214 110th Rd, Saint Albans, NY, 1141',
notes: chance.paragraph({ sentences: 2 }),
frequentlycontacted: true,
starred: true,
deleted: false,
},
{
id: 2,
firstname: 'Cami',
lastname: 'Macha',
image: 'assets/images/profile/user-3.jpg',
department: 'Support',
company: 'Zboncak LLC',
phone: '999-895-9652',
email: 'Camisad@claimab.com',
address: '76 Hamilton Ave, Yonkers, NY, 10705',
notes: chance.paragraph({ sentences: 2 }),
frequentlycontacted: false,
starred: false,
deleted: false,
},
{
id: 3,
firstname: 'Alda',
lastname: 'Ziemer',
image: 'assets/images/profile/user-4.jpg',
department: 'Engineering',
company: 'Lehner-Jacobson',
phone: '789-854-8950',
email: 'Ziemer234@claimab.com',
address: '930 Fruit Ave, Farrell, PA, 16121',
notes: chance.paragraph({ sentences: 2 }),
frequentlycontacted: true,
starred: false,
deleted: false,
},
{
id: 4,
firstname: 'Luciano',
lastname: 'Macpherson',
image: 'assets/images/profile/user-5.jpg',
department: 'Support',
company: 'Champlin',
phone: '452-652-5230',
email: 'Macpherson34@claimab.com',
address: '19103 Stefani Ave, Cerritos, CA, 90703',
notes: chance.paragraph({ sentences: 2 }),
frequentlycontacted: false,
starred: true,
deleted: true,
},
{
id: 5,
firstname: 'Dalton',
lastname: 'Paden',
image: 'assets/images/profile/user-6.jpg',
department: 'Engineering',
company: 'Balistreri',
phone: '985-985-7850',
email: 'Dalton321@claimab.com',
address: '3059 Edgewood Park Ct, Commerce Township',
notes: chance.paragraph({ sentences: 2 }),
frequentlycontacted: false,
starred: false,
deleted: false,
},
{
id: 6,
firstname: 'Juan',
lastname: 'Granado',
image: 'assets/images/profile/user-7.jpg',
department: 'Support',
company: 'Bernier-Ankunding',
phone: '230-541-5231',
email: 'Granado567@claimab.com',
address: '1330 N Douglas Ave, Arlington Heights',
notes: chance.paragraph({ sentences: 2 }),
frequentlycontacted: true,
starred: false,
deleted: true,
},
{
id: 7,
firstname: 'Reva',
lastname: 'Allen',
image: 'assets/images/profile/user-8.jpg',
department: 'Support',
company: 'Rosenbaum Inc',
phone: '478-582-6520',
email: 'Allen326@claimab.com',
address: '180 Topp Ln, Tupelo, MS',
notes: chance.paragraph({ sentences: 2 }),
frequentlycontacted: false,
starred: false,
deleted: true,
},
{
id: 8,
firstname: 'Jule',
lastname: 'Huseman',
image: 'assets/images/profile/user-9.jpg',
department: 'Sales',
company: 'Smith-Romaguera',
phone: '123-652-2301',
email: 'Huseman458@claimab.com',
address: '33 Caraway Rd, Reisterstown, MD',
notes: chance.paragraph({ sentences: 2 }),
frequentlycontacted: true,
starred: true,
deleted: true,
},
{
id: 9,
firstname: 'Bridgette',
lastname: 'Phung',
image: 'assets/images/profile/user-10.jpg',
department: 'Engineering',
company: 'Corwin-Kassulke',
phone: '652-452-6521',
email: 'Bridgette890@claimab.com',
address: '#RR, Bruceton Mills, WV',
notes: chance.paragraph({ sentences: 2 }),
frequentlycontacted: false,
starred: true,
deleted: true,
},
{
id: 10,
firstname: 'Ernest',
lastname: 'Cousins',
image: 'assets/images/profile/user-2.jpg',
department: 'Support',
company: 'Homenick-Hartmann',
phone: '785-985-6541',
email: 'Ernest6543@claimab.com',
address: 'Michael I. Days 3756 Preston Street Wichita',
notes: chance.paragraph({ sentences: 2 }),
frequentlycontacted: false,
starred: false,
deleted: true,
},
{
id: 11,
firstname: 'Nicolette',
lastname: 'Trapani',
image: 'assets/images/profile/user-3.jpg',
department: 'Engineering',
company: 'Gleason',
phone: '652-632-6520',
email: 'Nicoletteesdasd4@claimab.com',
address: 'Carol J. Stephens 1635 Franklin Street Montgomery',
notes: chance.paragraph({ sentences: 2 }),
frequentlycontacted: false,
starred: false,
deleted: true,
},
{
id: 12,
firstname: 'Virginia',
lastname: 'Bourdeau',
image: 'assets/images/profile/user-4.jpg',
department: 'Support',
company: 'McKenzie and Sons',
phone: '125-985-3210',
email: 'Bourdeauerwe@claimab.com',
address: 'Donald M. Palmer 2595 Pearlman Avenue',
notes: chance.paragraph({ sentences: 2 }),
frequentlycontacted: true,
starred: false,
deleted: false,
},
{
id: 13,
firstname: 'Janita',
lastname: 'Vogl',
image: 'assets/images/profile/user-5.jpg',
department: 'Sales',
company: 'Erdman-Moen',
phone: '541-521-6320',
email: 'Janitafdaa@claimab.com',
address: 'Micheal R. Porterfield 508 Virginia Street',
notes: chance.paragraph({ sentences: 2 }),
frequentlycontacted: true,
starred: true,
deleted: false,
},
{
id: 14,
firstname: 'Jeneva',
lastname: 'Bridgeforth',
image: 'assets/images/profile/user-6.jpg',
department: 'Engineering',
company: 'Fay LLC',
phone: '975-895-5240',
email: 'Bridgeforth564@claimab.com',
address: 'Nathan K. Flores 1516 Holt Street West Palm',
notes: chance.paragraph({ sentences: 2 }),
frequentlycontacted: true,
starred: true,
deleted: false,
},
{
id: 15,
firstname: 'Roselia',
lastname: 'Principe',
image: 'assets/images/profile/user-8.jpg',
department: 'Sales',
company: 'Bode-Oberbrunner',
phone: '874-546-6521',
email: 'Principe326@claimab.com',
address: '2915 Auburn Creek LnLeague City',
notes: chance.paragraph({ sentences: 2 }),
frequentlycontacted: false,
starred: true,
deleted: false,
},
{
id: 16,
firstname: 'Elvira',
lastname: 'Hylton',
image: 'assets/images/profile/user-7.jpg',
department: 'Support',
company: 'Pagac Group',
phone: '652-542-5200',
email: 'Elviraoknsss@claimab.com',
address: '2725 Cottage Rd Alpine',
notes: chance.paragraph({ sentences: 2 }),
frequentlycontacted: false,
starred: false,
deleted: false,
},
{
id: 17,
firstname: 'Maragaret',
lastname: 'Pecor',
image: 'assets/images/profile/user-10.jpg',
department: 'Sales',
company: 'Predovic and Sons',
phone: '326-984-1200',
email: 'Maragaret4352@mediafire.com',
address: '307 Hardy St Aberdeen',
notes: chance.paragraph({ sentences: 2 }),
frequentlycontacted: true,
starred: true,
deleted: false,
},
{
id: 18,
firstname: 'Willena',
lastname: 'Sugrue',
image: 'assets/images/profile/user-2.jpg',
department: 'Support',
company: 'Graham Group',
phone: '265-632-4521',
email: 'Willena75637@claimab.com',
address: '15919 Golf Club Dr Crosby',
notes: chance.paragraph({ sentences: 2 }),
frequentlycontacted: true,
starred: true,
deleted: false,
},
{
id: 19,
firstname: 'Eura',
lastname: 'Solley',
image: 'assets/images/profile/user-3.jpg',
department: 'Sales',
company: 'Toy-Ryan',
phone: '645-647-4800',
email: 'Solley6472@claimab.com',
address: 'Po Box 144 Rhome',
notes: chance.paragraph({ sentences: 2 }),
frequentlycontacted: false,
starred: false,
deleted: true,
},
{
id: 20,
firstname: 'Velva',
lastname: 'Brockett',
image: 'assets/images/profile/user-4.jpg',
department: 'Support',
company: 'Walsh Ltd',
phone: '654-985-6520',
email: 'Brocketterewgdb@claimab.com',
address: '34 Fairview Ln Palm Coast',
notes: chance.paragraph({ sentences: 2 }),
frequentlycontacted: false,
starred: true,
deleted: true,
},
{
id: 21,
firstname: 'Anya',
lastname: 'Snapp',
image: 'assets/images/profile/user-5.jpg',
department: 'Support',
company: 'Romaguera Inc',
phone: '456-652-3210',
email: 'Snapp76848@claimab.com',
address: '17919 Barney Dr Accokeek',
notes: chance.paragraph({ sentences: 2 }),
frequentlycontacted: true,
starred: false,
deleted: false,
},
{
id: 22,
firstname: 'Latoria',
lastname: 'Penaloza',
image: 'assets/images/profile/user-6.jpg',
department: 'Engineering',
company: 'Leuschke',
phone: '459-985-4520',
email: 'Penaloza3546@claimab.com',
address: '14 Huntington Dr Greenbrier',
notes: chance.paragraph({ sentences: 2 }),
frequentlycontacted: true,
starred: false,
deleted: true,
},
{
id: 23,
firstname: 'Tamika',
lastname: 'Inman',
image: 'assets/images/profile/user-7.jpg',
department: 'Sales',
company: 'Schumm',
phone: '645-978-4150',
email: 'Tamikadfdf45@claimab.com',
address: '1341 Mentionville Rd Darien',
notes: chance.paragraph({ sentences: 2 }),
frequentlycontacted: true,
starred: false,
deleted: true,
},
{
id: 24,
firstname: 'Erich',
lastname: 'Aragon',
image: 'assets/images/profile/user-8.jpg',
department: 'Business Development',
company: 'Brakus',
phone: '450-980-6520',
email: 'Aragondfdf4567@claimab.com',
address: '13 Pent Rd Branford',
notes: chance.paragraph({ sentences: 2 }),
frequentlycontacted: false,
starred: false,
deleted: true,
},
{
id: 25,
firstname: 'Johanna',
lastname: 'Randel',
image: 'assets/images/profile/user-9.jpg',
department: 'Sales',
company: 'Goyette',
phone: '120-320-4520',
email: 'Johanna456@claimab.com',
address: '5791 S Staghorn Cholla Ct Apache Junction',
notes: chance.paragraph({ sentences: 2 }),
frequentlycontacted: true,
starred: true,
deleted: true,
},
{
id: 26,
firstname: 'Victorina',
lastname: 'Heinze',
image: 'assets/images/profile/user-10.jpg',
department: 'Business Development',
company: 'Fritsch',
phone: '452-521-1230',
email: 'Victorina4545@claimab.com',
address: '69 El Molino Dr Clayton',
notes: chance.paragraph({ sentences: 2 }),
frequentlycontacted: false,
starred: false,
deleted: true,
},
{
id: 27,
firstname: 'Kiley',
lastname: 'Light',
image: 'assets/images/profile/user-8.jpg',
department: 'Sales',
company: 'Langosh',
phone: '652-452-1230',
email: 'Kileydfdfd45@claimab.com',
address: '215 Waterfront Ct Noblesville',
notes: chance.paragraph({ sentences: 2 }),
frequentlycontacted: false,
starred: true,
deleted: false,
},
{
id: 28,
firstname: 'Sanford',
lastname: 'Delorenzo',
image: 'assets/images/profile/user-3.jpg',
department: 'Engineering',
company: 'Huels',
phone: '963-652-1230',
email: 'Delorenzo3456@claimab.com',
address: '11212 Amber Rd Manistee',
notes: chance.paragraph({ sentences: 2 }),
frequentlycontacted: true,
starred: true,
deleted: false,
},
{
id: 29,
firstname: 'Hans',
lastname: 'Strebel',
image: 'assets/images/profile/user-4.jpg',
department: 'Sales',
company: 'Kohler',
phone: '546-654-1230',
email: 'Strebel345@claimab.com',
address: '2009 W Azalea Ave Baker',
notes: chance.paragraph({ sentences: 2 }),
frequentlycontacted: false,
starred: false,
deleted: false,
},
{
id: 30,
firstname: 'Roger',
lastname: 'Trinidad',
image: 'assets/images/profile/user-5.jpg',
department: 'Sales',
company: 'Kling-Hintz',
phone: '123-456-7890',
email: '3mcrz8gmymd@claimab.com',
address: '203 Dawn Dr, Mount Holly, NC, 28120',
notes: chance.paragraph({ sentences: 2 }),
frequentlycontacted: false,
starred: true,
deleted: true,
},
];
export default ContactList;
export function getUser(id: string): ContactBox | null {
// tslint:disable-next-line: no-shadowed-variable
const u = ContactList.find((u) => {
return u.id === id;
});
if (u === undefined) {
return null;
}
return u;
}

View File

@@ -0,0 +1,17 @@
<!-- ------------------------------------------------------------------ -->
<!-- Delete contact -->
<!-- ------------------------------------------------------------------ -->
<h4 mat-dialog-title>Confirmation</h4>
<div mat-dialog-content>
<p>{{ data.message }}</p>
</div>
<div mat-dialog-actions>
<button mat-flat-button color="warn" (click)="onConfirm()">Yes</button>
<button
mat-stroked-button
class="bg-error text-white"
(click)="onCancel()"
>
Cancel
</button>
</div>

Some files were not shown because too many files have changed in this diff Show More