8 Commits

Author SHA1 Message Date
Marek Lesko
2d1982d010 Merge branch 'dev' into 'main'
fix: UPDATED build configuration

See merge request marek/centrum!6
2025-07-14 19:01:31 +00:00
Marek Lesko
65d5e4b46a fix: UPDATED build configuration 2025-07-14 19:01:31 +00:00
Marek Lesko
329f4a2acb fix: UPDATED .gitlab-ci.yml file 2025-07-14 18:43:42 +00:00
Marek Lesko
8b6149595a fix: UPDATED .gitlab-ci.yml file 2025-07-14 18:43:27 +00:00
Marek Lesko
41c5b18f6f fix: .gitlab-ci.yml file 2025-07-14 18:30:37 +00:00
Marek Lesko
8728d7caf0 fix: .gitlab-ci.yml file 2025-07-14 18:28:40 +00:00
Marek Lesko
d307c04e7f fix: .releaserc.json 2025-07-14 18:24:43 +00:00
Marek Lesko
209460b582 fix: .gitlab-ci.yml file 2025-07-14 18:23:28 +00:00
333 changed files with 35275 additions and 3 deletions

View File

@@ -19,7 +19,8 @@ semantic-release:
image: node:24 image: node:24
stage: release stage: release
script: script:
- echo $GL_TOKEN - apt update && apt install zip -y
- zip -r dist.zip Web/dist/Web/browser
- npm install --save-dev @semantic-release/gitlab - npm install --save-dev @semantic-release/gitlab
- npx semantic-release --debug - npx semantic-release --debug
only: only:

View File

@@ -11,7 +11,7 @@
"@semantic-release/gitlab" "@semantic-release/gitlab"
], ],
"assets": [ "assets": [
{ "path": "Web/dist/Web/browser/*", "label": "bundle" }, { "path": "dist.zip", "label": "bundle" },
{ "url": "https://gitlab.lesko.me/marek/centrum/-/blob/main/README.md", "label": "README.md" } { "url": "https://gitlab.lesko.me/marek/centrum/-/blob/main/README.md", "label": "README.md" }
] ]
} }

View File

@@ -4,7 +4,7 @@
"scripts": { "scripts": {
"ng": "ng", "ng": "ng",
"start": "ng serve --host 0.0.0.0", "start": "ng serve --host 0.0.0.0",
"build": "ng build", "build": "ng build --configuration=production",
"watch": "ng build --watch --configuration development", "watch": "ng build --watch --configuration development",
"test": "ng test" "test": "ng test"
}, },

View File

@@ -0,0 +1,16 @@
# Editor configuration, see https://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true
[*.ts]
quote_type = single
[*.md]
max_line_length = off
trim_trailing_whitespace = false

42
Web/themes/modernize/.gitignore vendored Normal file
View File

@@ -0,0 +1,42 @@
# See http://help.github.com/ignore-files/ for more about ignoring files.
# Compiled output
/dist
/tmp
/out-tsc
/bazel-out
# Node
/node_modules
npm-debug.log
yarn-error.log
# IDEs and editors
.idea/
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace
# Visual Studio Code
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
.history/*
# Miscellaneous
/.angular/cache
.sass-cache/
/connect.lock
/coverage
/libpeerconnection.log
testem.log
/typings
# System files
.DS_Store
Thumbs.db

View File

@@ -0,0 +1 @@
legacy-peer-deps=true

View File

@@ -0,0 +1,2 @@
# Modernize-Angular-pro
Modernize Angular Admin Dashboard

View File

@@ -0,0 +1,96 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"Modernize": {
"projectType": "application",
"schematics": {
"@schematics/angular:component": {
"style": "scss"
}
},
"root": "",
"sourceRoot": "src",
"prefix": "app",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"allowedCommonJsDependencies": ["apexcharts", "bezier-easing", "moment"],
"outputPath": "dist/Modernize",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": ["zone.js"],
"tsConfig": "tsconfig.app.json",
"inlineStyleLanguage": "scss",
"assets": ["src/favicon.ico", "src/assets"],
"styles": ["src/styles.scss", "src/assets/scss/style.scss"],
"scripts": []
},
"configurations": {
"production": {
"budgets": [
{
"type": "initial",
"maximumWarning": "12mb",
"maximumError": "12mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "12mb",
"maximumError": "12mb"
}
],
"outputHashing": "all"
},
"development": {
"buildOptimizer": false,
"optimization": false,
"vendorChunk": true,
"extractLicenses": false,
"sourceMap": true,
"namedChunks": true
}
},
"defaultConfiguration": "production"
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"configurations": {
"production": {
"buildTarget": "Modernize:build:production"
},
"hmr": {
"hmr": true
},
"development": {
"buildTarget": "Modernize:build:development"
}
},
"defaultConfiguration": "development"
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"buildTarget": "Modernize:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"polyfills": ["zone.js", "zone.js/testing"],
"tsConfig": "tsconfig.spec.json",
"inlineStyleLanguage": "scss",
"assets": ["src/favicon.ico", "src/assets"],
"styles": ["src/styles.scss"],
"scripts": []
}
}
}
}
},
"cli": {
"analytics": false
}
}

View File

@@ -0,0 +1,4 @@
[[redirects]]
from = "/*"
to = "/index.html"
status = 200

13801
Web/themes/modernize/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,48 @@
{
"name": "modernize",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"watch": "ng build --watch --configuration development",
"test": "ng test"
},
"private": true,
"dependencies": {
"@angular/animations": "^19.0.0",
"@angular/cdk": "^19.0.0",
"@angular/common": "^19.0.0",
"@angular/compiler": "^19.0.0",
"@angular/core": "^19.0.0",
"@angular/forms": "^19.0.0",
"@angular/material": "^19.0.0",
"@angular/platform-browser": "^19.0.0",
"@angular/platform-browser-dynamic": "^19.0.0",
"@angular/router": "^19.0.0",
"@ngx-translate/core": "^14.0.0",
"@ngx-translate/http-loader": "^7.0.0",
"angular-tabler-icons": "^2.7.0",
"apexcharts": "^3.49.0",
"ng-apexcharts": "1.7.6",
"ngx-scrollbar": "^11.0.0",
"rxjs": "~7.5.0",
"sass": "1.81.0",
"tslib": "^2.3.0",
"zone.js": "~0.15.0"
},
"devDependencies": {
"@angular-devkit/build-angular": "^19.0.1",
"@angular/cli": "~19.0.1",
"@angular/compiler-cli": "^19.0.0",
"@types/date-fns": "^2.6.0",
"@types/jasmine": "~4.3.0",
"jasmine-core": "~4.5.0",
"karma": "~6.4.0",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage": "~2.2.0",
"karma-jasmine": "~5.1.0",
"karma-jasmine-html-reporter": "~2.0.0",
"typescript": "~5.6.3"
}
}

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 Template';
}

View File

@@ -0,0 +1,55 @@
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';
// icons
import { TablerIconsModule } from 'angular-tabler-icons';
import * as TablerIcons from 'angular-tabler-icons/icons';
// perfect scrollbar
import { NgScrollbarModule } from 'ngx-scrollbar';
//Import all material modules
import { MaterialModule } from './material.module';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
export const appConfig: ApplicationConfig = {
providers: [
provideZoneChangeDetection({ eventCoalescing: true }),
provideRouter(
routes,
withInMemoryScrolling({
scrollPositionRestoration: 'enabled',
anchorScrolling: 'enabled',
}),
withComponentInputBinding()
),
provideHttpClient(withInterceptorsFromDi()),
provideClientHydration(),
provideAnimationsAsync(),
importProvidersFrom(
FormsModule,
ReactiveFormsModule,
MaterialModule,
TablerIconsModule.pick(TablerIcons),
NgScrollbarModule,
),
],
};

View File

@@ -0,0 +1,51 @@
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: '/dashboard',
pathMatch: 'full',
},
{
path: 'dashboard',
loadChildren: () =>
import('./pages/pages.routes').then((m) => m.PagesRoutes),
},
{
path: 'ui-components',
loadChildren: () =>
import('./pages/ui-components/ui-components.routes').then(
(m) => m.UiComponentsRoutes
),
},
{
path: 'extra',
loadChildren: () =>
import('./pages/extra/extra.routes').then((m) => m.ExtraRoutes),
},
],
},
{
path: '',
component: BlankComponent,
children: [
{
path: 'authentication',
loadChildren: () =>
import('./pages/authentication/authentication.routes').then(
(m) => m.AuthenticationRoutes
),
},
],
},
{
path: '**',
redirectTo: 'authentication/error',
},
];

View File

@@ -0,0 +1,32 @@
<div class="row">
@for(productcard of productcards; track productcards) {
<div class="col-sm-6 col-lg-3">
<mat-card class="cardWithShadow productcard overflow-hidden">
<a routerLink="/widgets/cards">
<img src="{{ productcard.imgSrc }}" alt="imgSrc" class="w-100" mat-card-image />
</a>
<mat-card-content class="p-b-24 p-t-12 position-relative">
<button mat-mini-fab class="icon-30 cart-btn bg-primary text-white d-block" matTooltip="Add to Cart">
<i-tabler name="basket" class="icon-16"></i-tabler>
</button>
<mat-card-title class="mat-headline-2 f-s-16 m-b-4">{{
productcard.title
}}</mat-card-title>
<div class="d-flex align-items-center justify-content-between">
<div class="d-flex align-items-center">
<h6 class="f-w-600 f-s-16">${{ productcard.price }}</h6>
<span class="f-s-14 m-l-4 text-decoration-line-through">${{ productcard.rprice }}</span>
</div>
<div class="m-l-auto d-flex gap-4">
<span><i-tabler name="star" class="fill-warning icon-18"></i-tabler></span>
<span><i-tabler name="star" class="fill-warning icon-18"></i-tabler></span>
<span><i-tabler name="star" class="fill-warning icon-18"></i-tabler></span>
<span><i-tabler name="star" class="fill-warning icon-18"></i-tabler></span>
<span><i-tabler name="star" class="fill-warning icon-18"></i-tabler></span>
</div>
</div>
</mat-card-content>
</mat-card>
</div>
}
</div>

View File

@@ -0,0 +1,53 @@
import { Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card';
import { TablerIconsModule } from 'angular-tabler-icons';
// ecommerce card
interface productCards {
id: number;
imgSrc: string;
title: string;
price: string;
rprice: string;
}
@Component({
selector: 'app-blog-card',
imports: [MatCardModule, TablerIconsModule, MatButtonModule],
templateUrl: './blog-card.component.html',
})
export class AppBlogCardsComponent {
constructor() { }
productcards: productCards[] = [
{
id: 1,
imgSrc: '/assets/images/products/s4.jpg',
title: 'Boat Headphone',
price: '285',
rprice: '375',
},
{
id: 2,
imgSrc: '/assets/images/products/s5.jpg',
title: 'MacBook Air Pro',
price: '285',
rprice: '375',
},
{
id: 3,
imgSrc: '/assets/images/products/s7.jpg',
title: 'Red Valvet Dress',
price: '285',
rprice: '375',
},
{
id: 4,
imgSrc: '/assets/images/products/s11.jpg',
title: 'Cute Soft Teddybear',
price: '285',
rprice: '375',
},
];
}

View File

@@ -0,0 +1,24 @@
<mat-card class="cardWithShadow overflow-hidden">
<mat-card-content class="p-b-0">
<div class="d-flex align-items-center m-b-8">
<mat-card-title>Monthly Earnings</mat-card-title>
<div class="m-l-auto">
<button mat-fab class="icon-48 bg-secondary ">
<i-tabler name="currency-dollar" class="text-white d-flex"></i-tabler>
</button>
</div>
</div>
<h4 class="f-s-24 m-b-6">$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 p-0 d-flex align-items-center justify-content-center">
<i-tabler name="arrow-down-right" class="icon-20 d-flex align-items-center"></i-tabler>
</button>
<div class="f-s-14 f-w-600 m-l-12">+9%</div>
<div class="f-s-14 m-l-4">last year</div>
</div>
</mat-card-content>
<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,81 @@
import { Component, ViewChild } from '@angular/core';
import {
ApexChart,
ChartComponent,
ApexDataLabels,
ApexLegend,
ApexStroke,
ApexTooltip,
ApexAxisChartSeries,
ApexPlotOptions,
ApexResponsive,
NgApexchartsModule,
} from 'ng-apexcharts';
import { TablerIconsModule } from 'angular-tabler-icons';
import { MaterialModule } from 'src/app/material.module';
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: 85,
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,98 @@
<mat-card class="cardWithShadow">
<mat-card-content>
<div 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>
</div>
<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-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">
{{ 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">
${{ 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 { TablerIconsModule } from 'angular-tabler-icons';
import { CommonModule } from '@angular/common';
import { MaterialModule } from 'src/app/material.module';
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-product-performance',
imports: [
NgApexchartsModule,
MaterialModule,
TablerIconsModule,
CommonModule,
],
templateUrl: './product-performance.component.html',
})
export class AppProductPerformanceComponent {
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,33 @@
<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">#ML-3467</a>
}
</div>
</div>
}
</div>
</mat-card-content>
</mat-card>

View File

@@ -0,0 +1,62 @@
import { Component } from '@angular/core';
import { NgApexchartsModule } from 'ng-apexcharts';
import { MaterialModule } from 'src/app/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,22 @@
<mat-card class="cardWithShadow">
<mat-card-content>
<div class="d-flex w-100">
<mat-card-title>Sales Overview</mat-card-title>
<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>
<apx-chart [series]="salesOverviewChart.series" [dataLabels]="salesOverviewChart.dataLabels"
[chart]="salesOverviewChart.chart" [legend]="salesOverviewChart.legend" [xaxis]="salesOverviewChart.xaxis"
[yaxis]="salesOverviewChart.yaxis" [grid]="salesOverviewChart.grid" [stroke]="salesOverviewChart.stroke"
[tooltip]="salesOverviewChart.tooltip" [plotOptions]="salesOverviewChart.plotOptions"></apx-chart>
</mat-card-content>
</mat-card>

View File

@@ -0,0 +1,153 @@
import { Component, ViewChild } from '@angular/core';
import { TablerIconsModule } from 'angular-tabler-icons';
import { MaterialModule } from 'src/app/material.module';
import {
ApexChart,
ChartComponent,
ApexDataLabels,
ApexLegend,
ApexStroke,
ApexTooltip,
ApexAxisChartSeries,
ApexXAxis,
ApexYAxis,
ApexGrid,
ApexPlotOptions,
ApexFill,
ApexMarkers,
ApexResponsive,
NgApexchartsModule,
} from 'ng-apexcharts';
import { MatButtonModule } from '@angular/material/button';
interface month {
value: string;
viewValue: string;
}
export interface salesOverviewChart {
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-sales-overview',
imports: [MaterialModule, TablerIconsModule, NgApexchartsModule, MatButtonModule],
templateUrl: './sales-overview.component.html',
})
export class AppSalesOverviewComponent {
@ViewChild('chart') chart: ChartComponent = Object.create(null);
public salesOverviewChart!: Partial<salesOverviewChart> | any;
months: month[] = [
{ value: 'mar', viewValue: 'Sep 2025' },
{ value: 'apr', viewValue: 'Oct 2025' },
{ value: 'june', viewValue: 'Nov 2025' },
];
constructor() {
// sales overview chart
this.salesOverviewChart = {
series: [
{
name: 'Eanings this month',
data: [355, 390, 300, 350, 390, 180, 355, 390],
color: '#5D87FF',
},
{
name: 'Expense this month',
data: [280, 250, 325, 215, 250, 310, 280, 250],
color: '#49BEFF',
},
],
grid: {
borderColor: 'rgba(0,0,0,0.1)',
strokeDashArray: 3,
xaxis: {
lines: {
show: false,
},
},
},
plotOptions: {
bar: { horizontal: false, columnWidth: '35%', borderRadius: [4] },
},
chart: {
type: 'bar',
height: 390,
offsetX: -15,
toolbar: { show: false },
foreColor: '#adb0bb',
fontFamily: 'inherit',
sparkline: { enabled: false },
},
dataLabels: { enabled: false },
markers: { size: 0 },
legend: { show: false },
xaxis: {
type: 'category',
categories: [
'16/08',
'17/08',
'18/08',
'19/08',
'20/08',
'21/08',
'22/08',
'23/08',
],
labels: {
style: { cssClass: 'grey--text lighten-2--text fill-color' },
},
},
yaxis: {
show: true,
min: 0,
max: 400,
tickAmount: 4,
labels: {
style: {
cssClass: 'grey--text lighten-2--text fill-color',
},
},
},
stroke: {
show: true,
width: 3,
lineCap: 'butt',
colors: ['transparent'],
},
tooltip: { theme: 'light' },
responsive: [
{
breakpoint: 600,
options: {
plotOptions: {
bar: {
borderRadius: 3,
},
},
},
},
],
};
}
}

View File

@@ -0,0 +1,34 @@
<mat-card class="cardWithShadow">
<mat-card-content>
<mat-card-title>Yearly Breakup</mat-card-title>
<div class="row m-t-24">
<div class="col-7">
<h4 class="f-s-24">$36,358</h4>
<div class="d-flex align-items-center m-t-16">
<button mat-icon-button class="bg-light-success text-success shadow-none icon-27 p-0 d-flex align-items-center justify-content-center">
<i-tabler name="arrow-up-right" class="icon-20 d-flex align-items-center"></i-tabler>
</button>
<div class="f-w-600 m-l-12 f-s-14">+9%</div>
<div class="m-l-4 f-s-14">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="m-l-12 f-s-14">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="m-l-12 f-s-14">2024</div>
</div>
</div>
</div>
<div class="col-5 d-flex align-items-start">
<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,101 @@
import { Component, ViewEncapsulation, ViewChild } from '@angular/core';
import { TablerIconsModule } from 'angular-tabler-icons';
import {
ApexChart,
ChartComponent,
ApexDataLabels,
ApexLegend,
ApexStroke,
ApexTooltip,
ApexAxisChartSeries,
ApexXAxis,
ApexYAxis,
ApexGrid,
ApexPlotOptions,
ApexFill,
ApexMarkers,
ApexResponsive,
NgApexchartsModule,
} from 'ng-apexcharts';
import { MaterialModule } from 'src/app/material.module';
export interface yearlyChart {
series: ApexAxisChartSeries;
chart: ApexChart;
dataLabels: ApexDataLabels;
plotOptions: ApexPlotOptions;
tooltip: ApexTooltip;
stroke: ApexStroke;
legend: ApexLegend;
responsive: ApexResponsive;
}
@Component({
selector: 'app-yearly-breakup',
templateUrl: './yearly-breakup.component.html',
imports: [MaterialModule, NgApexchartsModule, TablerIconsModule],
encapsulation: ViewEncapsulation.None,
})
export class AppYearlyBreakupComponent {
@ViewChild('chart') chart: ChartComponent = Object.create(null);
public yearlyChart!: Partial<yearlyChart> | any;
constructor() {
this.yearlyChart = {
color: "#adb5bd",
series: [38, 40, 25],
labels: ["2025", "2024", "2023"],
chart: {
width: 125,
type: "donut",
fontFamily: "inherit",
foreColor: "#adb0bb",
},
plotOptions: {
pie: {
startAngle: 0,
endAngle: 360,
donut: {
size: "75%",
},
},
},
stroke: {
show: false,
},
dataLabels: {
enabled: false,
},
legend: {
show: false,
},
colors: ['#5D87FF', '#ECF2FF', '#F9F9FD'],
responsive: [
{
breakpoint: 991,
options: {
chart: {
width: 120,
},
},
},
],
tooltip: {
theme: "dark",
fillSeriesColor: false,
},
};
}
}

View File

@@ -0,0 +1,11 @@
export interface AppSettings {
sidenavOpened: boolean;
sidenavCollapsed: boolean;
}
export const defaults: AppSettings = {
sidenavOpened: false,
sidenavCollapsed: false,
};

View File

@@ -0,0 +1,6 @@
<!-- ============================================================== -->
<!-- Only router without any element -->
<!-- ============================================================== -->
<mat-sidenav-container dir="ltr" class="light-theme">
<router-outlet></router-outlet>
</mat-sidenav-container>

View File

@@ -0,0 +1,23 @@
import { Component } from '@angular/core';
import { CoreService } from 'src/app/services/core.service';
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')!;
}
}

View File

@@ -0,0 +1,59 @@
<app-topstrip></app-topstrip>
<mat-sidenav-container class="mainWrapper blue_theme light-theme" autosize autoFocus dir="ltr">
<!-- ============================================================== -->
<!-- Vertical Sidebar -->
<!-- ============================================================== -->
<mat-sidenav #leftsidenav [mode]="isOver ? 'over' : 'side'" [opened]="!isOver"
(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()">
</app-nav-item>
}
</mat-nav-list>
</ng-scrollbar>
<div class="p-24">
<div class="bg-light-secondary d-flex align-items-center gap-4 rounded p-20 m-t-20">
<div>
<h5 class="f-s-16 f-w-600 m-b-8">
Check Pro <br> Version
</h5>
<a mat-flat-button
href="https://adminmart.com/product/modernize-angular-material-dashboard/?ref=56#product-demo-section" target="_blank"
class="d-flex justify-content-center bg-secondary">
Check
</a>
</div>
<img src="/assets/images/backgrounds/rocket.png" alt="imgae" class="side-img m-t--48 m-r--8" />
</div>
</div>
</div>
</mat-sidenav>
<!-- ============================================================== -->
<!-- Main Content -->
<!-- ============================================================== -->
<mat-sidenav-content class="contentWrapper" #content>
<!-- ============================================================== -->
<!-- VerticalHeader -->
<!-- ============================================================== -->
<app-header [showToggle]="!isOver" (toggleMobileNav)="sidenav.toggle()"></app-header>
<main class="pageWrapper maxWidth">
<!-- ============================================================== -->
<!-- Outlet -->
<!-- ============================================================== -->
<router-outlet></router-outlet>
</main>
<div class="p-16 p-b-30 text-center">
Design & Developed by <a class="text-decoration-none" href="https://adminmart.com/" target="_blank">AdminMart.com</a>
</div>
</mat-sidenav-content>
</mat-sidenav-container>

View File

@@ -0,0 +1,117 @@
import { BreakpointObserver, MediaMatcher } from '@angular/cdk/layout';
import { 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 { filter } from 'rxjs/operators';
import { NavigationEnd, Router } from '@angular/router';
import { NavService } from '../../services/nav.service';
import { RouterModule } from '@angular/router';
import { MaterialModule } from 'src/app/material.module';
import { CommonModule } from '@angular/common';
import { NgScrollbarModule } from 'ngx-scrollbar';
import { TablerIconsModule } from 'angular-tabler-icons';
import { HeaderComponent } from './header/header.component';
import { SidebarComponent } from './sidebar/sidebar.component';
import { AppNavItemComponent } from './sidebar/nav-item/nav-item.component';
import { navItems } from './sidebar/sidebar-data';
import { AppTopstripComponent } from './top-strip/topstrip.component';
const MOBILE_VIEW = 'screen and (max-width: 768px)';
const TABLET_VIEW = 'screen and (min-width: 769px) and (max-width: 1024px)';
@Component({
selector: 'app-full',
imports: [
RouterModule,
AppNavItemComponent,
MaterialModule,
CommonModule,
SidebarComponent,
NgScrollbarModule,
TablerIconsModule,
HeaderComponent,
AppTopstripComponent
],
templateUrl: './full.component.html',
styleUrls: [],
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;
}
constructor(
private settings: CoreService,
private router: Router,
private breakpointObserver: BreakpointObserver,
) {
this.htmlElement = document.querySelector('html')!;
this.layoutChangesSubscription = this.breakpointObserver
.observe([MOBILE_VIEW, TABLET_VIEW])
.subscribe((state) => {
// SidenavOpened must be reset true when layout changes
this.options.sidenavOpened = true;
this.isMobileScreen = state.breakpoints[MOBILE_VIEW];
if (this.options.sidenavCollapsed == false) {
this.options.sidenavCollapsed = state.breakpoints[TABLET_VIEW];
}
});
// Initialize project theme with options
// This is for scroll to top
this.router.events
.pipe(filter((event) => event instanceof NavigationEnd))
.subscribe((e) => {
this.content.scrollTo({ top: 0 });
});
}
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);
}
}

View File

@@ -0,0 +1,48 @@
<mat-toolbar class="topbar gap-10">
<!-- Mobile Menu -->
<button mat-icon-button (click)="toggleMobileNav.emit()" class="d-flex d-lg-none justify-content-center">
<i-tabler name="menu-2" class="icon-20 d-flex"></i-tabler>
</button>
<button mat-icon-button [matMenuTriggerFor]="menu" aria-label="Notifications">
<i-tabler class="d-flex" name="bell" matBadge="1" matBadgeColor="primary"></i-tabler>
</button>
<mat-menu #menu="matMenu">
<button mat-menu-item>Item 1</button>
<button mat-menu-item>Item 2</button>
</mat-menu>
<span class="flex-1-auto"></span>
<!-- --------------------------------------------------------------- -->
<!-- profile Dropdown -->
<!-- --------------------------------------------------------------- -->
<a mat-flat-button href="https://adminmart.com/product/modernize-angular-admin-dashboard/?ref=56#product-demo-section"
target="_blank" class="d-flex justify-content-center bg-success">
Check Pro Template
</a>
<button mat-mini-fab [matMenuTriggerFor]="profilemenu" aria-label="Notifications">
<img src="/assets/images/profile/user-1.jpg" class="rounded-circle object-cover d-block" width="35" />
</button>
<mat-menu #profilemenu="matMenu" class="cardWithShadow topbar-dd">
<button mat-menu-item>
<mat-icon class="d-flex align-items-center"><i-tabler name="user" class="icon-18 d-flex"></i-tabler></mat-icon>My
Profile
</button>
<button mat-menu-item>
<mat-icon class="d-flex align-items-center"><i-tabler name="mail" class="icon-18 d-flex"></i-tabler></mat-icon>My
Account
</button>
<button mat-menu-item>
<mat-icon class="d-flex align-items-center"><i-tabler name="list-check"
class="icon-18 d-flex"></i-tabler></mat-icon>My Task
</button>
<div class="p-x-12 m-t-12">
<a [routerLink]="['/authentication/login']" mat-stroked-button class="w-100">Logout</a>
</div>
</mat-menu>
</mat-toolbar>

View File

@@ -0,0 +1,30 @@
import {
Component,
Output,
EventEmitter,
Input,
ViewEncapsulation,
} from '@angular/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 { NgScrollbarModule } from 'ngx-scrollbar';
@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>();
}

View File

@@ -0,0 +1,20 @@
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>
`,
})
export class BrandingComponent {
options = this.settings.getOptions();
constructor(private settings: CoreService) {}
}

View File

@@ -0,0 +1,48 @@
@if(item.navCap){
<div mat-subheader class="nav-caption">
{{ item.navCap }}
</div>
} @if(!item.navCap && !item.external) {
<a mat-list-item (click)="onItemSelected(item)" [ngClass]="{
activeMenu: item.route ? router.isActive(item.route, true) : false,
expanded: expanded,
disabled: item.disabled
}" class="menu-list-item">
<i-tabler class="routeIcon" name="{{ item.iconName }}" matListItemIcon></i-tabler>
<span class="hide-menu">{{ item.displayName }}</span>
@if(item.children && item.children.length) {
<span class="arrow-icon" fxFlex>
<span fxFlex></span>
@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>
}
<mat-icon [@indicatorRotate]="expanded ? 'expanded' : 'collapsed'">
expand_more
</mat-icon>
</span>
}
</a>
}
<!-- external Link -->
@if(!item.navCap && item.external) {
<mat-list-item (click)="openExternalLink(item.route)" class="menu-list-item" target="_blank">
<i-tabler class="routeIcon" name="{{ item.iconName }}" matListItemIcon></i-tabler>
<span class="hide-menu">{{ item.displayName }} </span>
@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>
}
</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,77 @@
import {
Component,
HostBinding,
Input,
OnChanges,
Output,
EventEmitter,
} from '@angular/core';
import { NavItem } from './nav-item';
import { Router } from '@angular/router';
import { NavService } from '../../../../services/nav.service';
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: [],
})
export class AppNavItemComponent implements OnChanges {
@Output() notify: EventEmitter<boolean> = new EventEmitter<boolean>();
@Input() item: NavItem | any;
expanded: any = false;
@HostBinding('attr.aria-expanded') ariaExpanded = this.expanded;
@Input() depth: any;
constructor(public navService: NavService, public router: Router) {}
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();
}
}
}
openExternalLink(url: string): void {
if (url) {
window.open(url, '_blank');
}
}
onSubItemSelected(item: NavItem) {
if (!item.children || !item.children.length) {
if (this.expanded && window.innerWidth < 1024) {
this.notify.emit();
}
}
}
}

View File

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

View File

@@ -0,0 +1,914 @@
import { NavItem } from './nav-item/nav-item';
export const navItems: NavItem[] = [
{
navCap: 'Home',
},
{
displayName: 'Dashboard',
iconName: 'layout-grid-add',
route: '/dashboard',
},
{
displayName: 'Analytical',
iconName: 'aperture',
route: 'https://modernize-angular-main.netlify.app/dashboards/dashboard1',
chip: true,
external: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'eCommerce',
iconName: 'shopping-cart',
route: 'https://modernize-angular-main.netlify.app/dashboards/dashboard2',
chip: true,
external: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
navCap: 'Apps',
},
{
displayName: 'Chat',
iconName: 'message-dots',
route: 'https://modernize-angular-main.netlify.app/apps/chat',
chip: true,
external: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Calendar',
iconName: 'calendar',
route: 'https://modernize-angular-main.netlify.app/apps/calendar',
chip: true,
external: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Email',
iconName: 'mail',
route: 'https://modernize-angular-main.netlify.app/apps/email/inbox',
chip: true,
external: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Kanban',
iconName: 'checklist',
route: 'https://modernize-angular-main.netlify.app/apps/kanban',
chip: true,
external: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Contacts',
iconName: 'phone',
route: 'https://modernize-angular-main.netlify.app/apps/contacts',
chip: true,
external: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Contact List',
iconName: 'list-details',
route: 'https://modernize-angular-main.netlify.app/apps/contact-list',
chip: true,
external: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Courses',
iconName: 'certificate',
route: 'https://modernize-angular-main.netlify.app/apps/courses',
chip: true,
external: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Employee',
iconName: 'brand-ctemplar',
route: 'https://modernize-angular-main.netlify.app/apps/employee',
chip: true,
external: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Notes',
iconName: 'note',
route: 'https://modernize-angular-main.netlify.app/apps/notes',
chip: true,
external: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Tickets',
iconName: 'ticket',
route: 'https://modernize-angular-main.netlify.app/apps/tickets',
chip: true,
external: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'ToDo',
iconName: 'edit',
route: 'https://modernize-angular-main.netlify.app/apps/todo',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Invoice',
iconName: 'file-invoice',
chip: true,
route: '',
children: [
{
displayName: 'List',
iconName: 'point',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
route: '/https://modernize-angular-main.netlify.app/apps/invoice',
},
{
displayName: 'Detail',
iconName: 'point',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
route:
'/https://modernize-angular-main.netlify.app/apps/viewInvoice/101',
},
{
displayName: 'Create',
iconName: 'point',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
route: '/https://modernize-angular-main.netlify.app/apps/addInvoice',
},
{
displayName: 'Edit',
iconName: 'point',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
route:
'/https://modernize-angular-main.netlify.app/apps/editinvoice/101',
},
],
},
{
displayName: 'Blog',
iconName: 'chart-donut-3',
chip: true,
route: 'apps/blog',
children: [
{
displayName: 'Post',
iconName: 'point',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
route: 'https://modernize-angular-main.netlify.app/apps/blog/post',
},
{
displayName: 'Detail',
iconName: 'point',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
route:
'https://modernize-angular-main.netlify.app/apps/blog/detail/Early Black Friday Amazon deals: cheap TVs, headphones, laptops',
},
],
},
{
navCap: 'Ui Components',
},
{
displayName: 'Badge',
iconName: 'archive',
route: '/ui-components/badge',
},
{
displayName: 'Chips',
iconName: 'info-circle',
route: '/ui-components/chips',
},
{
displayName: 'Lists',
iconName: 'list-details',
route: '/ui-components/lists',
},
{
displayName: 'Menu',
iconName: 'file-text',
route: '/ui-components/menu',
},
{
displayName: 'Tooltips',
iconName: 'file-text-ai',
route: '/ui-components/tooltips',
},
{
displayName: 'Forms',
iconName: 'clipboard-text',
route: '/ui-components/forms',
},
{
displayName: 'Tables',
iconName: 'table',
route: '/ui-components/tables',
},
{
displayName: 'Expansion Panel',
iconName: 'layout-bottombar-inactive',
route: 'https://modernize-angular-main.netlify.app/ui-components/expansion',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Dialog',
iconName: 'diabolo',
route: 'https://modernize-angular-main.netlify.app/ui-components/dialog',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Divider',
iconName: 'separator',
route: 'https://modernize-angular-main.netlify.app/ui-components/divider',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Paginator',
iconName: 'text-wrap',
route: 'https://modernize-angular-main.netlify.app/ui-components/paginator',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Progress Bar',
iconName: 'progress',
route: 'https://modernize-angular-main.netlify.app/ui-components/progress',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Progress Spinner',
iconName: 'rotate-2',
route: 'https://modernize-angular-main.netlify.app/ui-components/progress-spinner',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Ripples',
iconName: 'ripple',
route: 'https://modernize-angular-main.netlify.app/ui-components/ripples',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Slide Toggle',
iconName: 'toggle-left',
route: 'https://modernize-angular-main.netlify.app/ui-components/slide-toggle',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Slider',
iconName: 'adjustments-alt',
route: 'https://modernize-angular-main.netlify.app/ui-components/slider',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Snackbar',
iconName: 'stack-backward',
route: 'https://modernize-angular-main.netlify.app/ui-components/snackbar',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Tabs',
iconName: 'border-all',
route: 'https://modernize-angular-main.netlify.app/ui-components/tabs',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Toolbar',
iconName: 'tools-kitchen',
route: 'https://modernize-angular-main.netlify.app/ui-components/toolbar',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Tooltips',
iconName: 'tooltip',
route: 'https://modernize-angular-main.netlify.app/ui-components/tooltips',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
navCap: 'Pages',
},
{
displayName: 'Roll Base Access',
iconName: 'lock-access',
route: 'https://modernize-angular-main.netlify.app/apps/permission',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Treeview',
iconName: 'git-merge',
route: 'https://modernize-angular-main.netlify.app/theme-pages/treeview',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Pricing',
iconName: 'currency-dollar',
route: 'https://modernize-angular-main.netlify.app/theme-pages/pricing',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Account Setting',
iconName: 'user-circle',
route:
'https://modernize-angular-main.netlify.app/theme-pages/account-setting',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'FAQ',
iconName: 'help',
route: 'https://modernize-angular-main.netlify.app/theme-pages/faq',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Landingpage',
iconName: 'app-window',
route: 'https://modernize-angular-main.netlify.app/landingpage',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Widgets',
iconName: 'layout',
route: 'widgets',
chip: true,
children: [
{
displayName: 'Cards',
iconName: 'point',
route: 'https://modernize-angular-main.netlify.app/widgets/cards',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Banners',
iconName: 'point',
route: 'https://modernize-angular-main.netlify.app/widgets/banners',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Charts',
iconName: 'point',
route: 'https://modernize-angular-main.netlify.app/widgets/charts',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
],
},
{
navCap: 'Extra',
},
{
displayName: 'Icons',
iconName: 'mood-smile',
route: '/extra/icons',
},
{
displayName: 'Sample Page',
iconName: 'brand-dribbble',
route: '/extra/sample-page',
},
{
navCap: 'Forms',
},
{
displayName: 'Elements',
iconName: 'apps',
chip: true,
route: 'forms/forms-elements',
children: [
{
displayName: 'Autocomplete',
iconName: 'point',
route:
'https://modernize-angular-main.netlify.app/forms/forms-elements/autocomplete',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Button',
iconName: 'point',
route:
'https://modernize-angular-main.netlify.app/forms/forms-elements/button',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Checkbox',
iconName: 'point',
route:
'https://modernize-angular-main.netlify.app/forms/forms-elements/checkbox',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Radio',
iconName: 'point',
route:
'https://modernize-angular-main.netlify.app/forms/forms-elements/radio',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Datepicker',
iconName: 'point',
route:
'https://modernize-angular-main.netlify.app/forms/forms-elements/datepicker',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
],
},
{
displayName: 'Form Layouts',
iconName: 'file-description',
route: 'https://modernize-angular-main.netlify.app/forms/form-layouts',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Form Horizontal',
iconName: 'box-align-bottom',
route: 'https://modernize-angular-main.netlify.app/forms/form-horizontal',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Form Vertical',
iconName: 'box-align-left',
route: 'https://modernize-angular-main.netlify.app/forms/form-vertical',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Form Wizard',
iconName: 'files',
route: 'https://modernize-angular-main.netlify.app/forms/form-wizard',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Toastr',
iconName: 'notification',
route: 'https://modernize-angular-main.netlify.app/forms/form-toastr',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
navCap: 'Tables',
},
{
displayName: 'Tables',
iconName: 'layout',
route: 'tables',
chip: true,
children: [
{
displayName: 'Basic Table',
iconName: 'point',
route: 'https://modernize-angular-main.netlify.app/tables/basic-table',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Dynamic Table',
iconName: 'point',
route: 'https://modernize-angular-main.netlify.app/tables/dynamic-table',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Expand Table',
iconName: 'point',
route: 'https://modernize-angular-main.netlify.app/tables/expand-table',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Filterable Table',
iconName: 'point',
route:
'https://modernize-angular-main.netlify.app/tables/filterable-table',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Footer Row Table',
iconName: 'point',
route:
'https://modernize-angular-main.netlify.app/tables/footer-row-table',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'HTTP Table',
iconName: 'point',
route: 'https://modernize-angular-main.netlify.app/tables/http-table',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Mix Table',
iconName: 'point',
route: 'https://modernize-angular-main.netlify.app/tables/mix-table',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Multi Header Footer',
iconName: 'point',
route:
'https://modernize-angular-main.netlify.app/tables/multi-header-footer-table',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Pagination Table',
iconName: 'point',
route:
'https://modernize-angular-main.netlify.app/tables/pagination-table',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Row Context Table',
iconName: 'point',
route:
'https://modernize-angular-main.netlify.app/tables/row-context-table',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Selection Table',
iconName: 'point',
route:
'https://modernize-angular-main.netlify.app/tables/selection-table',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Sortable Table',
iconName: 'point',
route:
'https://modernize-angular-main.netlify.app/tables/sortable-table',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Sticky Column',
iconName: 'point',
route:
'https://modernize-angular-main.netlify.app/tables/sticky-column-table',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Sticky Header Footer',
iconName: 'point',
route:
'https://modernize-angular-main.netlify.app/tables/sticky-header-footer-table',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
],
},
{
displayName: 'Data table',
iconName: 'border-outer',
route: 'https://modernize-angular-main.netlify.app/datatable/kichen-sink',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
navCap: 'Chart',
},
{
displayName: 'Line',
iconName: 'chart-line',
route: 'https://modernize-angular-main.netlify.app/charts/line',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Gredient',
iconName: 'chart-arcs',
route: 'https://modernize-angular-main.netlify.app/charts/gredient',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Area',
iconName: 'chart-area',
route: 'https://modernize-angular-main.netlify.app/charts/area',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Candlestick',
iconName: 'chart-candle',
route: 'https://modernize-angular-main.netlify.app/charts/candlestick',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Column',
iconName: 'chart-dots',
route: 'https://modernize-angular-main.netlify.app/charts/column',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Doughnut & Pie',
iconName: 'chart-donut-3',
route: 'https://modernize-angular-main.netlify.app/charts/doughnut-pie',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Radialbar & Radar',
iconName: 'chart-radar',
route: 'https://modernize-angular-main.netlify.app/charts/radial-radar',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
navCap: 'Auth',
},
{
displayName: 'Login',
iconName: 'login',
route: '/authentication',
children: [
{
displayName: 'Login',
iconName: 'point',
route: '/authentication/login',
},
{
displayName: 'Side Login',
iconName: 'point',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
route: 'https://modernize-angular-main.netlify.app/authentication/login',
},
],
},
{
displayName: 'Register',
iconName: 'user-plus',
route: '/authentication',
children: [
{
displayName: 'Register',
iconName: 'point',
route: '/authentication/register',
},
{
displayName: 'Side Register',
iconName: 'point',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
route: 'https://modernize-angular-main.netlify.app/authentication/side-register',
},
],
},
{
displayName: 'Forgot Pwd',
iconName: 'rotate',
chip: true,
route: '/authentication',
children: [
{
displayName: 'Side Forgot Pwd',
iconName: 'point',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
route: 'https://modernize-angular-main.netlify.app/authentication/side-forgot-pwd',
},
{
displayName: 'Boxed Forgot Pwd',
iconName: 'point',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
route: 'https://modernize-angular-main.netlify.app/authentication/boxed-forgot-pwd',
},
],
},
{
displayName: 'Two Steps',
iconName: 'zoom-code',
chip: true,
route: '/authentication',
children: [
{
displayName: 'Side Two Steps',
iconName: 'point',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
route: 'https://modernize-angular-main.netlify.app/authentication/side-two-steps',
},
{
displayName: 'Boxed Two Steps',
iconName: 'point',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
route: 'https://modernize-angular-main.netlify.app/authentication/boxed-two-steps',
},
],
},
{
displayName: 'Error',
iconName: 'alert-circle',
route: 'https://modernize-angular-main.netlify.app//authentication/error',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
{
displayName: 'Maintenance',
iconName: 'settings',
route: 'https://modernize-angular-main.netlify.app//authentication/maintenance',
external: true,
chip: true,
chipClass: 'bg-light-secondary text-secondary',
chipContent: 'PRO',
},
];

View File

@@ -0,0 +1,10 @@
<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">
<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,121 @@
<div class="app-topstrip bg-dark text-white p-y-16 p-x-24 w-100 d-flex align-items-center justify-content-between">
<div class="d-none d-sm-flex align-items-center justify-content-center gap-20">
<a class="d-flex align-items-center" href="https://adminmart.com/" target="_blank">
<img src="/assets/images/logos/logo-adminmart.svg" alt="" width="150">
</a>
<div class="linkbar d-none d-lg-flex align-items-center justify-content-center gap-16">
<!-- Templates -->
<a mat-button class="link-hover p-x-0 text-white d-flex" href="https://adminmart.com/templates/angular/"
target="_blank">
<div class="d-flex align-items-center gap-8 f-s-16 f-w-400">
<i class="iconify icon-20 d-flex" data-icon="solar:window-frame-linear"></i>
Templates
</div>
</a>
<!-- Support -->
<a mat-button class="link-hover p-x-0 text-white d-flex" href="https://adminmart.com/support/"
target="_blank">
<div class="d-flex align-items-center gap-8 f-s-16 f-w-400">
<i class="iconify icon-20 d-flex" data-icon="solar:question-circle-linear"></i>
Help
</div>
</a>
<!-- Hire Us -->
<a mat-button class="link-hover p-x-0 text-white d-flex" href="https://adminmart.com/hire-us/"
target="_blank">
<div class="d-flex align-items-center gap-8 f-s-16 f-w-400">
<i class="iconify icon-20 d-flex" data-icon="solar:case-round-linear"></i>
Hire Us
</div>
</a>
</div>
</div>
<div class="topstrip-right d-flex align-items-center justify-content-center gap-16">
<h6 class="text-linear-gradient f-s-14 text-uppercase text-lg-left text-center">Checkout Pro Version</h6>
<div class="topstrip-right-inner d-flex justify-content-center align-items-center gap-10">
<div class="d-flex justify-content-center align-items-center gap-10">
<!-- Live Preview -->
<button class="live-preview-drop d-flex align-items-center gap-4 text-white f-s-16 p-x-16" mat-button
[matMenuTriggerFor]="beforeMenu">
<div class="d-flex align-items-center gap-6">
Live Preview
<i class="iconify icon-20 d-flex" data-icon="solar:alt-arrow-down-linear"></i>
</div>
</button>
<mat-menu class="p-x-16 p-y-8 rounded-7" #beforeMenu="matMenu" xPosition="before">
<a mat-menu-item class="rounded-7"
href="https://adminmart.com/product/modernize-angular-material-dashboard/?ref=56#product-demo-section"
target="_blank">
<div class="d-flex align-items-center gap-12 f-s-16">
<img src="/assets/images/svgs/angular-cat-icon.svg" width="18" alt="angular">
Angular Version
</div>
</a>
<a mat-menu-item class="rounded-7"
href="https://adminmart.com/product/modernize-react-mui-dashboard-theme/?ref=56#product-demo-section"
target="_blank">
<div class="d-flex align-items-center gap-12 f-s-16">
<img src="/assets/images/svgs/react-cat-icon.svg" width="18" alt="react">
React Version
</div>
</a>
<a mat-menu-item class="rounded-7"
href="https://adminmart.com/product/modernize-vuetify-vue-admin-dashboard/?ref=56#product-demo-section"
target="_blank">
<div class="d-flex align-items-center gap-12 f-s-16">
<img src="/assets/images/svgs/vue-cat-icon.svg" width="18" alt="vueJs">
VueJs Version
</div>
</a>
<a mat-menu-item class="rounded-7"
href="https://adminmart.com/product/modernize-next-js-admin-dashboard/?ref=56#product-demo-section"
target="_blank">
<div class="d-flex align-items-center gap-12 f-s-16">
<img src="/assets/images/svgs/next-cat-icon.svg" width="18" alt="nextJs">
NextJs Version
</div>
</a>
<a mat-menu-item class="rounded-7"
href="https://adminmart.com/product/modernize-nuxt-js-admin-dashboard/?ref=56#product-demo-section"
target="_blank">
<div class="d-flex align-items-center gap-12 f-s-16">
<img src="/assets/images/svgs/nuxt-cat-icon.svg" width="18" alt="nuxtJs">
NuxtJs Version
</div>
</a>
<a mat-menu-item class="rounded-7"
href="https://adminmart.com/product/modernize-tailwind-nextjs-dashboard-template/?ref=56#product-demo-section"
target="_blank">
<div class="d-flex align-items-center gap-12 f-s-16">
<img src="/assets/images/svgs/tailwindcss.svg" width="20" alt="tailwind">
Tailwind Version
</div>
</a>
<a mat-menu-item class="rounded-7"
href="https://adminmart.com/product/modernize-bootstrap-5-admin-template/?ref=56#product-demo-section"
target="_blank">
<div class="d-flex align-items-center gap-12 f-s-16">
<img src="/assets/images/svgs/bt-cat-icon.svg" width="20" alt="bootstrap">
Bootstrap Version
</div>
</a>
</mat-menu>
<!-- Get Pro -->
<a mat-button class="get-pro-btn text-white p-x-16"
href="https://adminmart.com/product/modernize-angular-material-dashboard/?ref=56" target="_blank">
<div class="d-flex align-items-center gap-8 f-s-16 f-w-400">
<i class="iconify icon-18 d-flex" data-icon="solar:crown-linear"></i>
Get Pro
</div>
</a>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,15 @@
import { Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatMenuModule } from '@angular/material/menu';
import { TablerIconsModule } from 'angular-tabler-icons';
@Component({
selector: 'app-topstrip',
imports: [TablerIconsModule, MatButtonModule, MatMenuModule],
templateUrl: './topstrip.component.html',
})
export class AppTopstripComponent {
constructor() { }
}

View File

@@ -0,0 +1,85 @@
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: [],
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,20 @@
import { Routes } from '@angular/router';
import { AppSideLoginComponent } from './side-login/side-login.component';
import { AppSideRegisterComponent } from './side-register/side-register.component';
export const AuthenticationRoutes: Routes = [
{
path: '',
children: [
{
path: 'login',
component: AppSideLoginComponent,
},
{
path: 'register',
component: AppSideRegisterComponent,
},
],
},
];

View File

@@ -0,0 +1,64 @@
<div class="blank-layout-container justify-content-center align-items-center bg-light">
<div class="position-relative row w-100 h-100 bg-gredient justify-content-center">
<div class="col-lg-4 d-flex align-items-center">
<mat-card class="cardWithShadow boxed-auth">
<mat-card-content class="p-32">
<div class="text-center">
<a [routerLink]="['/dashboard']">
<img src="./assets/images/logos/dark-logo.svg" class="align-middle m-2" alt="logo" />
</a>
</div>
<div class="row m-t-24 custom-row">
<div class="col-12 col-sm-6">
<button mat-stroked-button class="w-100">
<div class="d-flex align-items-center">
<img src="/assets/images/svgs/google-icon.svg" alt="google" width="16" class="m-r-8" />
<span>
Sign in with Google
</span>
</div>
</button>
</div>
<div class="col-12 col-sm-6">
<button mat-stroked-button class="w-100 d-flex align-items-center">
<div class="d-flex align-items-center">
<img src="/assets/images/svgs/facebook-icon.svg" alt="facebook" width="40" class="m-r-4" />
Sign in with FB
</div>
</button>
</div>
</div>
<div class="or-border m-t-30">or sign in with</div>
<form class="m-t-30">
<mat-label class="f-s-14 f-w-600 m-b-12 d-block">Username</mat-label>
<mat-form-field appearance="outline" class="w-100" color="primary">
<input matInput />
</mat-form-field>
<!-- password -->
<mat-label class="f-s-14 f-w-600 m-b-12 d-block">Password</mat-label>
<mat-form-field appearance="outline" class="w-100" color="primary">
<input matInput type="password" />
</mat-form-field>
<div class="d-flex align-items-center m-b-12">
<mat-checkbox color="primary">Remember this Device</mat-checkbox>
<a [routerLink]="['/']" class="text-primary f-w-600 text-decoration-none m-l-auto f-s-14">Forgot Password
?</a>
</div>
<a [routerLink]="['/']" mat-flat-button color="primary" class="w-100">
Sign In
</a>
<!-- input -->
</form>
<span class="d-block f-w-500 text-center m-t-24">New to Modernize?
<a [routerLink]="['/authentication/register']" class="text-decoration-none text-primary f-w-500 f-s-14">
Create an account</a>
</span>
</mat-card-content>
</mat-card>
</div>
</div>
</div>

View File

@@ -0,0 +1,31 @@
import { Component } from '@angular/core';
import { FormGroup, FormControl, Validators } from '@angular/forms';
import { Router } from '@angular/router';
import { RouterModule } from '@angular/router';
import { MaterialModule } from 'src/app/material.module';
import { FormsModule } from '@angular/forms';
import { ReactiveFormsModule } from '@angular/forms';
@Component({
selector: 'app-side-login',
imports: [RouterModule, MaterialModule, FormsModule, ReactiveFormsModule],
templateUrl: './side-login.component.html',
})
export class AppSideLoginComponent {
constructor( private router: Router) {}
form = new FormGroup({
uname: new FormControl('', [Validators.required, Validators.minLength(6)]),
password: new FormControl('', [Validators.required]),
});
get f() {
return this.form.controls;
}
submit() {
// console.log(this.form.value);
this.router.navigate(['/']);
}
}

View File

@@ -0,0 +1,62 @@
<div class="blank-layout-container justify-content-center align-items-center bg-light">
<div class="position-relative row w-100 h-100 bg-gredient justify-content-center">
<div class="col-lg-4 d-flex align-items-center">
<mat-card class="cardWithShadow boxed-auth">
<mat-card-content class="p-32">
<div class="text-center">
<a [routerLink]="['/dashboard']">
<img src="./assets/images/logos/dark-logo.svg" class="align-middle m-2" alt="logo" />
</a>
</div>
<div class="row m-t-24 custom-row">
<div class="col-12 col-sm-6">
<button mat-stroked-button class="w-100">
<div class="d-flex align-items-center">
<img src="/assets/images/svgs/google-icon.svg" alt="google" width="16" class="m-r-8" />
Sign in with Google
</div>
</button>
</div>
<div class="col-12 col-sm-6">
<button mat-stroked-button class="w-100 d-flex align-items-center">
<div class="d-flex align-items-center">
<img src="/assets/images/svgs/facebook-icon.svg" alt="facebook" width="40" class="m-r-4" />
Sign in with FB
</div>
</button>
</div>
</div>
<div class="or-border m-t-30">or sign up with</div>
<form class="m-t-30">
<mat-label class="f-s-14 f-w-600 m-b-12 d-block">Name</mat-label>
<mat-form-field appearance="outline" class="w-100" color="primary">
<input matInput />
</mat-form-field>
<mat-label class="f-s-14 f-w-600 m-b-12 d-block">Email Adddress</mat-label>
<mat-form-field appearance="outline" class="w-100" color="primary">
<input matInput type="email" />
</mat-form-field>
<!-- password -->
<mat-label class="f-s-14 f-w-600 m-b-12 d-block">Password</mat-label>
<mat-form-field appearance="outline" class="w-100" color="primary">
<input matInput type="password" />
</mat-form-field>
<a [routerLink]="['/']" mat-flat-button color="primary" class="w-100">
Sign Up
</a>
<!-- input -->
</form>
<span class="d-block f-w-500 text-center m-t-24">Already have an Account?
<a [routerLink]="['/authentication/login']" class="text-decoration-none text-primary f-w-500 f-s-14">
Sign In</a>
</span>
</mat-card-content>
</mat-card>
</div>
</div>
</div>

View File

@@ -0,0 +1,33 @@
import { Component } from '@angular/core';
import { CoreService } from 'src/app/services/core.service';
import { FormGroup, FormControl, Validators } from '@angular/forms';
import { Router } from '@angular/router';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
import { MaterialModule } from 'src/app/material.module';
@Component({
selector: 'app-side-register',
imports: [RouterModule, MaterialModule, FormsModule, ReactiveFormsModule],
templateUrl: './side-register.component.html',
})
export class AppSideRegisterComponent {
options = this.settings.getOptions();
constructor(private settings: CoreService, private router: Router) {}
form = new FormGroup({
uname: new FormControl('', [Validators.required, Validators.minLength(6)]),
email: new FormControl('', [Validators.required]),
password: new FormControl('', [Validators.required]),
});
get f() {
return this.form.controls;
}
submit() {
// console.log(this.form.value);
this.router.navigate(['/']);
}
}

View File

@@ -0,0 +1,22 @@
import { Routes } from '@angular/router';
// pages
import { AppIconsComponent } from './icons/icons.component';
import { AppSamplePageComponent } from './sample-page/sample-page.component';
export const ExtraRoutes: Routes = [
{
path: '',
children: [
{
path: 'icons',
component: AppIconsComponent,
},
{
path: 'sample-page',
component: AppSamplePageComponent,
},
],
},
];

View File

@@ -0,0 +1,12 @@
<!-- ============================================================== -->
<!-- Simple four boxes Row -->
<!-- ============================================================== -->
<mat-card class="cardWithShadow">
<mat-card-content>
<mat-card-title>Icons</mat-card-title>
<mat-card-subtitle class="m-b-24">Tabler Icons</mat-card-subtitle>
<iframe src="https://tabler.io/icons" title="Tabler Icons" width="100%" height="630px"
allowfullscreen frameBorder="0">
</iframe>
</mat-card-content>
</mat-card>

View File

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

View File

@@ -0,0 +1,9 @@
<!-- ============================================================== -->
<!-- Simple four boxes Row -->
<!-- ============================================================== -->
<mat-card class="cardWithShadow">
<mat-card-content>
<mat-card-title>Sample Page</mat-card-title>
<mat-card-subtitle>This is test page</mat-card-subtitle>
</mat-card-content>
</mat-card>

View File

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

View File

@@ -0,0 +1,16 @@
import { Routes } from '@angular/router';
import { StarterComponent } from './starter/starter.component';
export const PagesRoutes: Routes = [
{
path: '',
component: StarterComponent,
data: {
title: 'Starter Page',
urls: [
{ title: 'Dashboard', url: '/dashboards/dashboard1' },
{ title: 'Starter Page' },
],
},
},
];

View File

@@ -0,0 +1,24 @@
<div class="row">
<div class="col-lg-8">
<app-sales-overview></app-sales-overview>
</div>
<div class="col-lg-4">
<app-yearly-breakup></app-yearly-breakup>
<app-monthly-earnings></app-monthly-earnings>
</div>
</div>
<div class="row">
<div class="col-lg-4">
<app-recent-transactions></app-recent-transactions>
</div>
<div class="col-lg-8">
<app-product-performance></app-product-performance>
</div>
</div>
<div class="row">
<div class="col-12">
<app-blog-card></app-blog-card>
</div>
</div>

View File

@@ -0,0 +1,25 @@
import { Component, ViewEncapsulation } from '@angular/core';
import { MaterialModule } from '../../material.module';
import { AppSalesOverviewComponent } from 'src/app/components/sales-overview/sales-overview.component';
import { AppYearlyBreakupComponent } from 'src/app/components/yearly-breakup/yearly-breakup.component';
import { AppMonthlyEarningsComponent } from 'src/app/components/monthly-earnings/monthly-earnings.component';
import { AppRecentTransactionsComponent } from 'src/app/components/recent-transactions/recent-transactions.component';
import { AppProductPerformanceComponent } from 'src/app/components/product-performance/product-performance.component';
import { AppBlogCardsComponent } from 'src/app/components/blog-card/blog-card.component';
@Component({
selector: 'app-starter',
imports: [
MaterialModule,
AppSalesOverviewComponent,
AppYearlyBreakupComponent,
AppMonthlyEarningsComponent,
AppRecentTransactionsComponent,
AppProductPerformanceComponent,
AppBlogCardsComponent
],
templateUrl: './starter.component.html',
encapsulation: ViewEncapsulation.None,
})
export class StarterComponent { }

View File

@@ -0,0 +1,51 @@
<mat-card class="cardWithShadow theme-card">
<mat-card-header>
<mat-card-title class="m-b-0">Badges</mat-card-title>
</mat-card-header>
<mat-card-content class="b-t-1">
<mat-card class="b-1 shadow-none">
<mat-card-content>
<div matBadge="4" matBadgeOverlap="false" class="d-inline">Text with a badge</div>
</mat-card-content>
</mat-card>
<mat-card class="b-1 shadow-none">
<mat-card-content>
<div matBadge="1" matBadgeSize="small" class="d-inline">Text with small badge</div><br /><br />
<div matBadge="1" matBadgeSize="large" class="d-inline">Text with large badge</div>
</mat-card-content>
</mat-card>
<mat-card class="b-1 shadow-none">
<mat-card-content>
<p class="f-w-500 text-muted">
Button with a badge on the left
<button mat-flat-button color="primary" matBadge="8" matBadgePosition="before" matBadgeColor="accent">
Action
</button>
</p>
</mat-card-content>
</mat-card>
<mat-card class="b-1 shadow-none">
<mat-card-content>
<p class="f-w-500 text-muted">
Icon with a badge
<mat-icon matBadge="15" matBadgeColor="warn">home</mat-icon>
</p>
</mat-card-content>
</mat-card>
<mat-card class="b-1 shadow-none">
<mat-card-content>
<p>
Button toggles badge visibility
<button mat-flat-button color="primary" matBadge="7" [matBadgeHidden]="hidden"
(click)="toggleBadgeVisibility()">
Hide
</button>
</p>
</mat-card-content>
</mat-card>
</mat-card-content>
</mat-card>

View File

@@ -0,0 +1,22 @@
import { Component, OnInit } from '@angular/core';
import { MatIconModule } from '@angular/material/icon';
import { MatButtonModule } from '@angular/material/button';
import { MatBadgeModule } from '@angular/material/badge';
import { MatCardModule } from '@angular/material/card';
@Component({
selector: 'app-badge',
templateUrl: './badge.component.html',
imports: [MatBadgeModule, MatButtonModule, MatIconModule, MatCardModule],
})
export class AppBadgeComponent implements OnInit {
constructor() {}
ngOnInit(): void {}
hidden = false;
toggleBadgeVisibility() {
this.hidden = !this.hidden;
}
}

View File

@@ -0,0 +1,172 @@
<mat-card class="cardWithShadow theme-card">
<mat-card-header>
<mat-card-title class="m-b-0">Chips</mat-card-title>
</mat-card-header>
<mat-card-content class="b-t-1">
<div class="row">
<div class="col-lg-6">
<!-- ------------------------------------------------------------------------- -->
<!-- basic -->
<!-- ------------------------------------------------------------------------- -->
<mat-card class="b-1 shadow-none">
<mat-card-header>
<mat-card-title>Basic</mat-card-title>
</mat-card-header>
<mat-card-content class="b-t-1">
<mat-chip-listbox aria-label="Fish selection">
<mat-chip-option class="f-s-14" color="primary">One fish</mat-chip-option>
<mat-chip-option class="f-s-14">Two fish</mat-chip-option>
<mat-chip-option class="f-s-14" color="accent" selected>Accent fish</mat-chip-option>
<mat-chip-option class="f-s-14" color="warn">Warn fish</mat-chip-option>
</mat-chip-listbox>
</mat-card-content>
</mat-card>
</div>
<div class="col-lg-6">
<!-- ------------------------------------------------------------------------- -->
<!-- avatar -->
<!-- ------------------------------------------------------------------------- -->
<mat-card class="b-1 shadow-none">
<mat-card-header>
<mat-card-title>Avatar</mat-card-title>
</mat-card-header>
<mat-card-content class="b-t-1">
<mat-chip-set aria-label="Dog selection">
<mat-chip class="f-s-14">
<img matChipAvatar src="/assets/images/profile/user-1.jpg" alt="Photo of a Shiba Inu" />
Anderson
</mat-chip>
<mat-chip class="f-s-14" color="primary">
<img matChipAvatar src="/assets/images/profile/user-2.jpg" alt="Photo of a Shiba Inu" />
Monty
</mat-chip>
<mat-chip class="f-s-14" color="accent">
<img matChipAvatar src="/assets/images/profile/user-3.jpg" alt="Photo of a Shiba Inu" />
Mathew
</mat-chip>
</mat-chip-set>
</mat-card-content>
</mat-card>
</div>
<div class="col-lg-6">
<!-- ------------------------------------------------------------------------- -->
<!-- Drag n Drop -->
<!-- ------------------------------------------------------------------------- -->
<mat-card class="b-1 shadow-none">
<mat-card-header>
<mat-card-title>Drag n Drop</mat-card-title>
</mat-card-header>
<mat-card-content class="b-t-1">
<mat-chip-set class="example-chip" cdkDropList cdkDropListOrientation="horizontal"
(cdkDropListDropped)="drop($event)">
@for (vegetable of vegetables(); track vegetable.name) {
<mat-chip class="example-box" cdkDrag>{{
vegetable.name
}}</mat-chip>
}
</mat-chip-set>
</mat-card-content>
</mat-card>
</div>
<div class="col-lg-6">
<!-- ------------------------------------------------------------------------- -->
<!-- Stacked -->
<!-- ------------------------------------------------------------------------- -->
<mat-card class="b-1 shadow-none">
<mat-card-header>
<mat-card-title>Stacked </mat-card-title>
</mat-card-header>
<mat-card-content class="b-t-1">
<mat-chip-listbox class="mat-mdc-chip-set-stacked" aria-label="Color selection">
@for(chip of availableColors; track chip.color) {
<mat-chip-option selected [color]="chip.color">
{{ chip.name }}
</mat-chip-option>
}
</mat-chip-listbox>
</mat-card-content>
</mat-card>
</div>
<div class="col-12">
<!-- ------------------------------------------------------------------------- -->
<!-- Input -->
<!-- ------------------------------------------------------------------------- -->
<mat-card class="b-1 shadow-none">
<mat-card-header>
<mat-card-title>Input</mat-card-title>
</mat-card-header>
<mat-card-content class="b-t-1">
<mat-form-field appearance="outline" class="w-100">
<mat-label>Favorite Fruits</mat-label>
<mat-chip-grid #chipGrid aria-label="Enter fruits">
@for(fruit of fruits; track fruit.name) {
<mat-chip-row (removed)="remove(fruit)" [editable]="true" (edited)="edit(fruit, $event)"
[aria-description]="'press enter to edit ' + fruit.name" class="f-s-14">
{{ fruit.name }}
<button matChipRemove [attr.aria-label]="'remove ' + fruit.name">
<mat-icon>cancel</mat-icon>
</button>
</mat-chip-row>
}
<input placeholder="New fruit..." [matChipInputFor]="chipGrid"
[matChipInputSeparatorKeyCodes]="separatorKeysCodes" [matChipInputAddOnBlur]="addOnBlur"
(matChipInputTokenEnd)="add($event)" />
</mat-chip-grid>
</mat-form-field>
</mat-card-content>
</mat-card>
</div>
<div class="col-12">
<!-- ------------------------------------------------------------------------- -->
<!-- Form Control -->
<!-- ------------------------------------------------------------------------- -->
<mat-card class="b-1 shadow-none">
<mat-card-header>
<mat-card-title>Form Control</mat-card-title>
</mat-card-header>
<mat-card-content class="b-t-1">
<div class="d-flex gap-8">
<button mat-stroked-button color="primary" (click)="formControl.disable()">
Disable form control
</button>
<button mat-raised-button color="primary" (click)="formControl.enable()">
Enable form control
</button>
</div>
<mat-form-field appearance="outline" class="w-100 m-t-20">
<mat-label>Video keywords</mat-label>
<mat-chip-grid #formChip aria-label="Enter keywords" [formControl]="formControl">
@for (keyword of keywords(); track keyword) {
<mat-chip-row (removed)="removeKeyword(keyword)">
{{ keyword }}
<button matChipRemove aria-label="'remove ' + keyword">
<mat-icon>cancel</mat-icon>
</button>
</mat-chip-row>
}
</mat-chip-grid>
<input placeholder="New keyword..." [matChipInputFor]="formChip"
(matChipInputTokenEnd)="addForm($event)" />
</mat-form-field>
<p>
<span class="f-w-600">The following keywords are entered:</span>
{{ formControl.value }}
</p>
</mat-card-content>
</mat-card>
</div>
</div>
</mat-card-content>
</mat-card>

View File

@@ -0,0 +1,7 @@
.example-box.cdk-drag-animating {
transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
}
.example-chip .cdk-drop-list-dragging {
transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
}

View File

@@ -0,0 +1,161 @@
import { COMMA, ENTER } from '@angular/cdk/keycodes';
import { ThemePalette } from '@angular/material/core';
import {
ChangeDetectionStrategy,
Component,
inject,
signal,
} from '@angular/core';
import {
CdkDrag,
CdkDragDrop,
CdkDropList,
moveItemInArray,
} from '@angular/cdk/drag-drop';
import { MatCardModule } from '@angular/material/card';
import {
MatChipEditedEvent,
MatChipInputEvent,
MatChipsModule,
} from '@angular/material/chips';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatIconModule } from '@angular/material/icon';
import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { LiveAnnouncer } from '@angular/cdk/a11y';
import { MatButtonModule } from '@angular/material/button';
export interface ChipColor {
name: string;
color: ThemePalette;
}
export interface Fruit {
name: string;
}
export interface Vegetable {
name: string;
}
@Component({
selector: 'app-chips',
templateUrl: './chips.component.html',
styleUrls: ['./chips.component.scss'],
imports: [
MatFormFieldModule,
MatChipsModule,
MatIconModule,
MatCardModule,
CdkDropList,
CdkDrag,
FormsModule,
ReactiveFormsModule,
MatButtonModule
],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AppChipsComponent {
// drag n drop
readonly vegetables = signal<Vegetable[]>([
{ name: 'apple' },
{ name: 'banana' },
{ name: 'strawberry' },
{ name: 'orange' },
{ name: 'kiwi' },
{ name: 'cherry' },
]);
drop(event: CdkDragDrop<Vegetable[]>) {
this.vegetables.update((vegetables) => {
moveItemInArray(vegetables, event.previousIndex, event.currentIndex);
return [...vegetables];
});
}
//
// Stacked
//
availableColors: ChipColor[] = [
{ name: 'Primary', color: 'primary' },
{ name: 'Accent', color: 'accent' },
{ name: 'Warn', color: 'warn' },
];
//
// chips with input
//
addOnBlur = true;
readonly separatorKeysCodes = [ENTER, COMMA] as const;
fruits: Fruit[] = [{ name: 'Lemon' }, { name: 'Lime' }, { name: 'Apple' }];
add(event: MatChipInputEvent): void {
const value = (event.value || '').trim();
// Add our fruit
if (value) {
this.fruits.push({ name: value });
}
// Clear the input value
event.chipInput!.clear();
}
remove(fruit: Fruit): void {
const index = this.fruits.indexOf(fruit);
if (index >= 0) {
this.fruits.splice(index, 1);
}
}
edit(fruit: Fruit, event: MatChipEditedEvent) {
const value = event.value.trim();
// Remove fruit if it no longer has a name
if (!value) {
this.remove(fruit);
return;
}
// Edit existing fruit
const index = this.fruits.indexOf(fruit);
if (index >= 0) {
this.fruits[index].name = value;
}
}
// form control
readonly keywords = signal(['angular', 'how-to', 'tutorial', 'accessibility']);
readonly formControl = new FormControl(['angular']);
announcer = inject(LiveAnnouncer);
removeKeyword(keyword: string) {
this.keywords.update(keywords => {
const index = keywords.indexOf(keyword);
if (index < 0) {
return keywords;
}
keywords.splice(index, 1);
this.announcer.announce(`removed ${keyword}`);
return [...keywords];
});
}
addForm(event: MatChipInputEvent): void {
const value = (event.value || '').trim();
// Add our keyword
if (value) {
this.keywords.update(keywords => [...keywords, value]);
}
// Clear the input value
event.chipInput!.clear();
}
}
function isDragDrop(object: any): object is CdkDragDrop<string[]> {
return 'previousIndex' in object;
}

View File

@@ -0,0 +1,73 @@
<mat-card class="cardWithShadow theme-card">
<mat-card-header>
<mat-card-title class="m-b-0">Form</mat-card-title>
</mat-card-header>
<mat-card-content class="b-t-1">
<form>
<div class="row">
<div class="col-lg-6">
<!-- input -->
<mat-label class="f-w-600 m-b-8 d-block">Your Name</mat-label>
<mat-form-field appearance="outline" class="w-100" color="primary">
<input matInput placeholder="your name " />
</mat-form-field>
</div>
<div class="col-lg-6">
<mat-label class="f-w-600 m-b-8 d-block">Country</mat-label>
<mat-form-field appearance="outline" class="w-100">
<mat-select [(value)]="selectedCountry">
@for(option of country; track option.value) {
<mat-option [value]="option.value">{{
option.viewValue
}}</mat-option>
}
</mat-select>
</mat-form-field>
</div>
<div class="col-lg-6">
<!-- input -->
<mat-label class="f-w-600 m-b-8 d-block">Email</mat-label>
<mat-form-field appearance="outline" class="w-100" color="primary">
<input matInput type="email" placeholder="your email" />
</mat-form-field>
</div>
<div class="col-lg-6">
<mat-label class="f-w-600 m-b-8 d-block">State</mat-label>
<mat-form-field appearance="outline" class="w-100">
<mat-select [(value)]="selectedState">
@for(option of state; track option.value) {
<mat-option [value]="option.value">{{
option.viewValue
}}</mat-option>
}
</mat-select>
</mat-form-field>
</div>
<div class="col-lg-6">
<!-- input -->
<mat-label class="f-w-600 m-b-8 d-block">Password</mat-label>
<mat-form-field appearance="outline" class="w-100" color="primary">
<input matInput type="password" placeholder="your password" />
</mat-form-field>
</div>
<div class="col-lg-6">
<mat-label class="f-w-600 m-b-8 d-block">City</mat-label>
<mat-form-field appearance="outline" class="w-100">
<mat-select [(value)]="selectedCity">
@for(option of city; track option.value) {
<mat-option [value]="option.value">{{
option.viewValue
}}</mat-option>
}
</mat-select>
</mat-form-field>
</div>
</div>
<div class="m-t-12">
<button mat-flat-button color="primary" class="m-r-8">Submit</button>
<button mat-stroked-button color="warn">Cancel</button>
</div>
</form>
</mat-card-content>
</mat-card>

View File

@@ -0,0 +1,58 @@
import { Component } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';
import { MatSelectModule } from '@angular/material/select';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatCardModule } from '@angular/material/card';
import { MatInputModule } from '@angular/material/input';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatRadioModule } from '@angular/material/radio';
interface Food {
value: string;
viewValue: string;
}
@Component({
selector: 'app-forms',
imports: [
MatFormFieldModule,
MatSelectModule,
FormsModule,
ReactiveFormsModule,
MatRadioModule,
MatButtonModule,
MatCardModule,
MatInputModule,
MatCheckboxModule,
],
templateUrl: './forms.component.html',
})
export class AppFormsComponent {
country: Food[] = [
{ value: 'steak-0', viewValue: 'USA' },
{ value: 'pizza-1', viewValue: 'India' },
{ value: 'tacos-2', viewValue: 'France' },
{ value: 'tacos-3', viewValue: 'UK' },
];
selectedCountry = this.country[2].value;
city: Food[] = [
{ value: 'steak-0', viewValue: 'Mexico' },
{ value: 'pizza-1', viewValue: 'Mumbai' },
{ value: 'tacos-2', viewValue: 'Tokyo' },
{ value: 'tacos-3', viewValue: 'New York' },
];
selectedCity = this.city[1].value;
state: Food[] = [
{ value: 'steak-0', viewValue: 'Cuba' },
{ value: 'pizza-1', viewValue: 'Djibouti' },
{ value: 'tacos-2', viewValue: 'Bulgaria' },
{ value: 'tacos-3', viewValue: 'Cabo Verde' },
];
selectedState = this.state[3].value;
}

View File

@@ -0,0 +1,197 @@
<mat-card class="cardWithShadow theme-card">
<mat-card-header>
<mat-card-title class="m-b-0">Lists</mat-card-title>
</mat-card-header>
<mat-card-content class="b-t-1">
<div class="row">
<div class="col-lg-6">
<!-- --------------------------------------------------- -->
<!-- basic -->
<!-- --------------------------------------------------- -->
<mat-card class="b-1 shadow-none">
<mat-card-header>
<mat-card-title>Basic</mat-card-title>
</mat-card-header>
<mat-card-content class="b-t-1">
<mat-list role="list">
<mat-list-item role="listitem">Item 1</mat-list-item>
<mat-list-item role="listitem">Item 2</mat-list-item>
<mat-list-item role="listitem">Item 3</mat-list-item>
</mat-list>
</mat-card-content>
</mat-card>
</div>
<div class="col-lg-6">
<!-- --------------------------------------------------- -->
<!-- two line -->
<!-- --------------------------------------------------- -->
<mat-card class="b-1 shadow-none">
<mat-card-header>
<mat-card-title>Two Line</mat-card-title>
</mat-card-header>
<mat-card-content class="b-t-1">
<mat-list>
<mat-list-item>
<span matListItemTitle class="f-s-16 f-w-600">Title</span>
<span matListItemLine>Second line</span>
</mat-list-item>
<mat-list-item>
<span matListItemTitle class="f-s-16 f-w-600">Title</span>
<span matListItemLine>Second line</span>
</mat-list-item>
</mat-list>
</mat-card-content>
</mat-card>
</div>
<div class="col-lg-6">
<!-- --------------------------------------------------- -->
<!-- two line -->
<!-- --------------------------------------------------- -->
<mat-card class="b-1 shadow-none">
<mat-card-header>
<mat-card-title>Three Line</mat-card-title>
</mat-card-header>
<mat-card-content class="b-t-1">
<mat-list>
<mat-list-item>
<span matListItemTitle class="f-s-16 f-w-600">Title</span>
<span matListItemLine>Second line</span>
<span matListItemLine>Third line</span>
</mat-list-item>
<mat-list-item>
<span matListItemTitle class="f-s-16 f-w-600">Title</span>
<span matListItemLine>Second line. This line will truncate.</span>
<span>Third line</span>
</mat-list-item>
</mat-list>
</mat-card-content>
</mat-card>
</div>
<div class="col-lg-6">
<!-- --------------------------------------------------- -->
<!-- two line -->
<!-- --------------------------------------------------- -->
<mat-card class="b-1 shadow-none">
<mat-card-header>
<mat-card-title>Three Line with Text wrapping</mat-card-title>
</mat-card-header>
<mat-card-content class="b-t-1">
<mat-list style="max-width: 500px">
<mat-list-item lines="3">
<span matListItemTitle class="f-s-16 f-w-600">Title</span>
<span>Secondary line that will wrap because the list lines is
explicitly set to 3 lines. Text inside of a `matListItemTitle`
or `matListItemLine` will never wrap.
</span>
</mat-list-item>
<mat-list-item lines="3">
<span matListItemTitle class="f-s-16 f-w-600">Title</span>
<span>Secondary line that will wrap because the list lines is
explicitly set to 3 lines. Text inside of a `matListItemTitle`
or `matListItemLine` will never wrap.
</span>
</mat-list-item>
</mat-list>
</mat-card-content>
</mat-card>
</div>
<div class="col-lg-6">
<!-- --------------------------------------------------- -->
<!-- List with Selection -->
<!-- --------------------------------------------------- -->
<mat-card class="b-1 shadow-none">
<mat-card-header>
<mat-card-title>List with Selection</mat-card-title>
</mat-card-header>
<mat-card-content class="b-t-1">
<mat-selection-list #shoes>
@for(shoe of typesOfShoes; track shoe) {
<mat-list-option>
{{ shoe }}
</mat-list-option>
}
</mat-selection-list>
<p class="f-w-600 p-16 bg-light-primary rounded">
Options selected: {{ shoes.selectedOptions.selected.length }}
</p>
</mat-card-content>
</mat-card>
</div>
<div class="col-lg-6">
<!-- --------------------------------------------------- -->
<!-- List with single Selection -->
<!-- --------------------------------------------------- -->
<mat-card class="b-1 shadow-none">
<mat-card-header>
<mat-card-title>List with single Selection</mat-card-title>
</mat-card-header>
<mat-card-content class="b-t-1">
<mat-selection-list #shoes2 [multiple]="false">
@for(shoe of typesOfShoes; track shoe) {
<mat-list-option [value]="shoe">
{{ shoe }}
</mat-list-option>
}
</mat-selection-list>
<p class="f-w-600 p-16 bg-light-primary rounded">
Option selected:
{{
shoes2.selectedOptions.hasValue()
? shoes2.selectedOptions.selected[0].value
: "None"
}}
</p>
</mat-card-content>
</mat-card>
</div>
<div class="col-12">
<!-- --------------------------------------------------- -->
<!-- List with sections -->
<!-- --------------------------------------------------- -->
<mat-card class="b-1 shadow-none">
<mat-card-header>
<mat-card-title>List with sections</mat-card-title>
</mat-card-header>
<mat-card-content class="b-t-1">
<mat-list>
<div mat-subheader class="m-b-16 f-w-600">Folders</div>
@for(folder of folders; track folder.name) {
<mat-list-item>
<mat-icon matListItemIcon>folder</mat-icon>
<div matListItemTitle class="f-w-600">
{{ folder.name }}
</div>
<div matListItemLine class="f-s-14 ">
{{ folder.updated | date }}
</div>
</mat-list-item>
}
<mat-divider></mat-divider>
<div mat-subheader class="m-y-16 f-w-600">Notes</div>
@for(note of notes; track note.name) {
<mat-list-item>
<mat-icon matListItemIcon>note</mat-icon>
<div matListItemTitle class="f-w-600">
{{ note.name }}
</div>
<div matListItemLine class="f-s-14 ">
{{ note.updated | date }}
</div>
</mat-list-item>
}
</mat-list>
</mat-card-content>
</mat-card>
</div>
</div>
</mat-card-content>
</mat-card>

View File

@@ -0,0 +1,48 @@
import { Component } from '@angular/core';
import { MatCardModule } from '@angular/material/card';
import { MatListModule } from '@angular/material/list';
import {MatIconModule} from '@angular/material/icon';
import {DatePipe} from '@angular/common';
import { MaterialModule } from 'src/app/material.module';
export interface Section {
name: string;
updated: Date;
}
@Component({
selector: 'app-lists',
imports: [MatListModule, MatCardModule, DatePipe,MatIconModule, MaterialModule ],
templateUrl: './lists.component.html',
})
export class AppListsComponent {
constructor() {}
typesOfShoes: string[] = ['Loafers', 'Sneakers'];
folders: Section[] = [
{
name: 'Photos',
updated: new Date('1/1/25'),
},
{
name: 'Recipes',
updated: new Date('1/17/25'),
},
{
name: 'Work',
updated: new Date('1/28/25'),
},
];
notes: Section[] = [
{
name: 'Vacation Itinerary',
updated: new Date('2/20/25'),
},
{
name: 'Kitchen Remodel',
updated: new Date('1/18/25'),
},
];
}

View File

@@ -0,0 +1,166 @@
<mat-card class="cardWithShadow theme-card">
<mat-card-header>
<mat-card-title class="m-b-0">Menu</mat-card-title>
</mat-card-header>
<mat-card-content class="b-t-1">
<div class="row">
<div class="col-sm-6 col-lg-4">
<mat-card class="b-1 shadow-none">
<mat-card-header>
<mat-card-title>Basic</mat-card-title>
</mat-card-header>
<mat-card-content class="b-t-1">
<button mat-flat-button color="primary" class="m-t-8" [matMenuTriggerFor]="menu">
Menu
</button>
<mat-menu #menu="matMenu" class="cardWithShadow">
<button mat-menu-item>Item 1</button>
<button mat-menu-item>Item 2</button>
</mat-menu>
</mat-card-content>
</mat-card>
</div>
<div class="col-sm-6 col-lg-4">
<mat-card class="b-1 shadow-none">
<mat-card-header>
<mat-card-title>with Icons</mat-card-title>
</mat-card-header>
<mat-card-content class="b-t-1">
<button mat-icon-button [matMenuTriggerFor]="menu" aria-label="Example icon-button with a menu">
<mat-icon>
<i-tabler name="dots" class="icon-20"></i-tabler>
</mat-icon>
</button>
<mat-menu #menu="matMenu" class="cardWithShadow">
<button mat-menu-item>
<mat-icon>dialpad</mat-icon>
<span>Redial</span>
</button>
<button mat-menu-item disabled>
<mat-icon>voicemail</mat-icon>
<span>Check voice mail</span>
</button>
<button mat-menu-item>
<mat-icon>notifications_off</mat-icon>
<span>Disable alerts</span>
</button>
</mat-menu>
</mat-card-content>
</mat-card>
</div>
<div class="col-sm-6 col-lg-4">
<mat-card class="b-1 shadow-none">
<mat-card-header>
<mat-card-title>Nested Menu</mat-card-title>
</mat-card-header>
<mat-card-content class="b-t-1">
<button mat-flat-button color="primary" [matMenuTriggerFor]="animals" class="m-t-8">
Animal index
</button>
<mat-menu class="cardWithShadow" #animals="matMenu">
<button mat-menu-item [matMenuTriggerFor]="vertebrates">
Vertebrates
</button>
<button mat-menu-item [matMenuTriggerFor]="invertebrates">
Invertebrates
</button>
</mat-menu>
<mat-menu class="cardWithShadow" #vertebrates="matMenu">
<button mat-menu-item [matMenuTriggerFor]="fish">Fishes</button>
<button mat-menu-item [matMenuTriggerFor]="amphibians">
Amphibians
</button>
<button mat-menu-item [matMenuTriggerFor]="reptiles">
Reptiles
</button>
<button mat-menu-item>Birds</button>
<button mat-menu-item>Mammals</button>
</mat-menu>
<mat-menu class="cardWithShadow" #invertebrates="matMenu">
<button mat-menu-item>Insects</button>
<button mat-menu-item>Molluscs</button>
<button mat-menu-item>Crustaceans</button>
<button mat-menu-item>Corals</button>
<button mat-menu-item>Arachnids</button>
<button mat-menu-item>Velvet worms</button>
<button mat-menu-item>Horseshoe crabs</button>
</mat-menu>
<mat-menu class="cardWithShadow" #fish="matMenu">
<button mat-menu-item>Baikal oilfish</button>
<button mat-menu-item>Bala shark</button>
<button mat-menu-item>Ballan wrasse</button>
<button mat-menu-item>Bamboo shark</button>
<button mat-menu-item>Banded killifish</button>
</mat-menu>
<mat-menu class="cardWithShadow" #amphibians="matMenu">
<button mat-menu-item>Sonoran desert toad</button>
<button mat-menu-item>Western toad</button>
<button mat-menu-item>Arroyo toad</button>
<button mat-menu-item>Yosemite toad</button>
</mat-menu>
<mat-menu class="cardWithShadow" #reptiles="matMenu">
<button mat-menu-item>Banded Day Gecko</button>
<button mat-menu-item>Banded Gila Monster</button>
<button mat-menu-item>Black Tree Monitor</button>
<button mat-menu-item>Blue Spiny Lizard</button>
<button mat-menu-item disabled>Velociraptor</button>
</mat-menu>
</mat-card-content>
</mat-card>
</div>
<div class="col-12">
<mat-card class="b-1 shadow-none">
<mat-card-header>
<mat-card-title>Positions</mat-card-title>
</mat-card-header>
<mat-card-content class="b-t-1">
<div class="row">
<div class="col-sm-3">
<button mat-flat-button color="primary" class="w-100" [matMenuTriggerFor]="aboveMenu">
Above
</button>
<mat-menu class="cardWithShadow" #aboveMenu="matMenu" yPosition="above">
<button mat-menu-item>Item 1</button>
<button mat-menu-item>Item 2</button>
</mat-menu>
</div>
<div class="col-sm-3">
<button mat-flat-button color="accent" class="w-100" [matMenuTriggerFor]="belowMenu">
Below
</button>
<mat-menu class="cardWithShadow" #belowMenu="matMenu" yPosition="below">
<button mat-menu-item>Item 1</button>
<button mat-menu-item>Item 2</button>
</mat-menu>
</div>
<div class="col-sm-3">
<button mat-flat-button color="warn" class="w-100" [matMenuTriggerFor]="beforeMenu">
Before
</button>
<mat-menu class="cardWithShadow" #beforeMenu="matMenu" xPosition="before">
<button mat-menu-item>Item 1</button>
<button mat-menu-item>Item 2</button>
</mat-menu>
</div>
<div class="col-sm-3">
<button mat-flat-button color="primary" class="w-100" [matMenuTriggerFor]="afterMenu">
After
</button>
<mat-menu class="cardWithShadow" #afterMenu="matMenu" xPosition="after">
<button mat-menu-item>Item 1</button>
<button mat-menu-item>Item 2</button>
</mat-menu>
</div>
</div>
</mat-card-content>
</mat-card>
</div>
</div>
</mat-card-content>
</mat-card>

View File

@@ -0,0 +1,15 @@
import { Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card';
import { MatIconModule } from '@angular/material/icon';
import { MatMenuModule } from '@angular/material/menu';
import { TablerIconsModule } from 'angular-tabler-icons';
@Component({
selector: 'app-menu',
imports: [MatCardModule, MatMenuModule, MatIconModule, TablerIconsModule, MatButtonModule],
templateUrl: './menu.component.html',
})
export class AppMenuComponent {
constructor() {}
}

View File

@@ -0,0 +1,102 @@
<mat-card class="cardWithShadow">
<mat-card-content>
<mat-card-title>Table</mat-card-title>
<div class="table-responsive">
<table mat-table [dataSource]="dataSource1" class="w-100">
<!-- Position Column -->
<ng-container matColumnDef="assigned">
<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="60" class="rounded" />
<div class="m-l-16">
<h6 class="f-s-14 f-w-600">
{{ element.uname }}
</h6>
</div>
</div>
</td>
</ng-container>
<!-- Name Column -->
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef class="f-w-600 f-s-14">
Payment
</th>
<td mat-cell *matCellDef="let element">
@if(element.budget >= 160) {
<h6 class=" f-s-16 m-b-4">
<span class="text-dark f-w-600">${{ element.budget }} </span>/ 499
</h6>
<span class="f-s-14 f-w-500 d-block m-b-4">Full paid</span>
<mat-progress-bar mode="determinate" value="80" color="primary"></mat-progress-bar>
} @else if(element.budget > 119) {
<h6 class=" f-s-16 m-b-4">
<span class="text-dark f-w-600">${{ element.budget }} </span>/ 499
</h6>
<span class="f-s-14 f-w-500 d-block m-b-4">Partially paid</span>
<mat-progress-bar mode="determinate" class="mat-error" value="35" color="accent"></mat-progress-bar>
} @else if(element.budget < 100) { <h6 class=" f-s-16 m-b-4">
<span class="text-dark f-w-600">${{ element.budget }} </span>/ 499
</h6>
<span class="f-s-14 f-w-500 d-block m-b-4">Cancelled</span>
<mat-progress-bar mode="determinate" class="mat-warning" value="50" color="warn"></mat-progress-bar>
}
</td>
</ng-container>
<!-- Weight Column -->
<ng-container matColumnDef="priority">
<th mat-header-cell *matHeaderCellDef class="f-w-600 f-s-14">
Status
</th>
<td mat-cell *matCellDef="let element">
@if(element.priority == 'cancelled') {
<span class="bg-light-warning text-warning rounded f-w-600 p-6 p-y-4 f-s-12">
{{ element.priority | titlecase }}
</span>
} @if(element.priority == 'rejected') {
<span class="bg-light-error text-error rounded f-w-600 p-6 p-y-4 f-s-12">
{{ element.priority | titlecase }}
</span>
} @if(element.priority == 'confirmed') {
<span class="bg-light-success text-success rounded f-w-600 p-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"></th>
<td mat-cell *matCellDef="let element">
<button mat-icon-button [matMenuTriggerFor]="menu" aria-label="Example icon-button with a menu">
<mat-icon>more_vert</mat-icon>
</button>
<mat-menu #menu="matMenu">
<button mat-menu-item>
<mat-icon>add</mat-icon>
<span>Add</span>
</button>
<button mat-menu-item>
<mat-icon>edit</mat-icon>
<span>Edit</span>
</button>
<button mat-menu-item>
<mat-icon>delete</mat-icon>
<span>Delete</span>
</button>
</mat-menu>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns1"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns1"></tr>
</table>
</div>
</mat-card-content>
</mat-card>

View File

@@ -0,0 +1,67 @@
import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import { MatCardModule } from '@angular/material/card';
import { MatTableModule } from '@angular/material/table';
import { MaterialModule } from 'src/app/material.module';
import { MatIconModule } from '@angular/material/icon';
import { MatMenuModule } from '@angular/material/menu';
import { MatButtonModule } from '@angular/material/button';
// table 1
export interface productsData {
id: number;
imagePath: string;
uname: string;
budget: number;
priority: string;
}
const PRODUCT_DATA: productsData[] = [
{
id: 1,
imagePath: 'assets/images/products/product-1.png',
uname: 'iPhone 13 pro max-Pacific Blue-128GB storage',
budget: 180,
priority: 'confirmed',
},
{
id: 2,
imagePath: 'assets/images/products/product-2.png',
uname: 'Apple MacBook Pro 13 inch-M1-8/256GB-space',
budget: 90,
priority: 'cancelled',
},
{
id: 3,
imagePath: 'assets/images/products/product-3.png',
uname: 'PlayStation 5 DualSense Wireless Controller',
budget: 120,
priority: 'rejected',
},
{
id: 4,
imagePath: 'assets/images/products/product-4.png',
uname: 'Amazon Basics Mesh, Mid-Back, Swivel Office',
budget: 160,
priority: 'confirmed',
},
];
@Component({
selector: 'app-tables',
imports: [
MatTableModule,
CommonModule,
MatCardModule,
MaterialModule,
MatIconModule,
MatMenuModule,
MatButtonModule,
],
templateUrl: './tables.component.html',
})
export class AppTablesComponent {
// table 1
displayedColumns1: string[] = ['assigned', 'name', 'priority', 'budget'];
dataSource1 = PRODUCT_DATA;
}

View File

@@ -0,0 +1,128 @@
<mat-card class="cardWithShadow theme-card">
<mat-card-header>
<mat-card-title class="m-b-0">Tooltips</mat-card-title>
</mat-card-header>
<mat-card-content class="b-t-1">
<div class="row">
<div class="col-lg-4 col-sm-6">
<mat-card class="b-1 shadow-none">
<mat-card-header>
<mat-card-title>Basic</mat-card-title>
</mat-card-header>
<mat-card-content class="b-t-1">
<button mat-flat-button color="primary" matTooltip="Info about the action">
Button
</button>
</mat-card-content>
</mat-card>
</div>
<div class="col-lg-4 col-sm-6">
<mat-card class="b-1 shadow-none">
<mat-card-header>
<mat-card-title>Uppercase</mat-card-title>
</mat-card-header>
<mat-card-content class="b-t-1">
<button mat-flat-button color="primary" matTooltip="Info about the action" matTooltipClass="text-uppercase">
Button
</button>
</mat-card-content>
</mat-card>
</div>
<div class="col-lg-4 col-sm-6">
<mat-card class="b-1 shadow-none">
<mat-card-header>
<mat-card-title>Disabled on click</mat-card-title>
</mat-card-header>
<mat-card-content class="b-t-1">
<button mat-flat-button color="primary" matTooltip="Info about the action"
[matTooltipDisabled]="disabled.value" class="m-r-8">
Action
</button>
<mat-checkbox [formControl]="disabled" class="example-disabled-checkbox">
Tooltip disabled
</mat-checkbox>
</mat-card-content>
</mat-card>
</div>
<div class="col-lg-6">
<mat-card class="b-1 shadow-none">
<mat-card-header>
<mat-card-title>Position</mat-card-title>
</mat-card-header>
<mat-card-content class="b-t-1">
<button mat-flat-button color="primary" #tooltip="matTooltip" matTooltip="Info about the action"
matTooltipPosition="below" matTooltipHideDelay="100000">
Below
</button>
<button mat-flat-button color="accent" #tooltip="matTooltip" matTooltip="Info about the action"
matTooltipPosition="above" class="m-l-8" matTooltipHideDelay="100000">
Above
</button>
<button mat-flat-button color="warn" #tooltip="matTooltip" matTooltip="Info about the action"
matTooltipPosition="left" class="m-l-8" matTooltipHideDelay="100000">
Left
</button>
<button mat-flat-button color="primary" #tooltip="matTooltip" matTooltip="Info about the action"
matTooltipPosition="right" class="m-l-8" matTooltipHideDelay="100000">
Right
</button>
</mat-card-content>
</mat-card>
</div>
<div class="col-lg-6">
<mat-card class="b-1 shadow-none">
<mat-card-header>
<mat-card-title>Show and Hide</mat-card-title>
</mat-card-header>
<mat-card-content class="b-t-1">
<div class="row">
<div class="col-sm-4">
<mat-form-field class="w-100" appearance="outline">
<mat-label>Show delay</mat-label>
<input matInput type="number" [formControl]="showDelay" />
<mat-hint>milliseconds</mat-hint>
</mat-form-field>
</div>
<div class="col-sm-4">
<mat-form-field class="w-100" appearance="outline">
<mat-label>Hide delay</mat-label>
<input matInput type="number" [formControl]="hideDelay2" />
<mat-hint>milliseconds</mat-hint>
</mat-form-field>
</div>
<div class="col-sm-4">
<button mat-flat-button color="primary" matTooltip="Info about the action"
[matTooltipShowDelay]="showDelay.value" [matTooltipHideDelay]="hideDelay2.value">
Action
</button>
</div>
</div>
</mat-card-content>
</mat-card>
</div>
<div class="col-lg-4 col-sm-6">
<mat-card class="b-1 shadow-none">
<mat-card-header>
<mat-card-title>Change Message</mat-card-title>
</mat-card-header>
<mat-card-content class="b-t-1">
<mat-form-field class="w-100" appearance="outline">
<mat-label>Tooltip message</mat-label>
<input matInput [formControl]="message" />
</mat-form-field>
<button mat-flat-button color="primary" [matTooltip]="message.value || ''"
aria-label="Button that displays a tooltip with a custom message">
Action
</button>
</mat-card-content>
</mat-card>
</div>
</div>
</mat-card-content>
</mat-card>

View File

@@ -0,0 +1,33 @@
import { Component } from '@angular/core';
import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms';
import {MatTooltipModule} from '@angular/material/tooltip';
import {MatButtonModule} from '@angular/material/button';
import {MatSelectModule} from '@angular/material/select';
import {MatFormFieldModule} from '@angular/material/form-field';
import { MatCardModule } from '@angular/material/card';
import { MatInputModule } from '@angular/material/input';
import { MatCheckboxModule } from '@angular/material/checkbox';
@Component({
selector: 'app-tooltips',
imports: [
MatFormFieldModule,
MatSelectModule,
FormsModule,
ReactiveFormsModule,
MatButtonModule,
MatTooltipModule, MatCardModule, MatInputModule, MatCheckboxModule
],
templateUrl: './tooltips.component.html',
})
export class AppTooltipsComponent {
// disabled
disabled = new FormControl(false);
// show and hide
showDelay = new FormControl(1000);
hideDelay2 = new FormControl(2000);
// change message
message = new FormControl('Info about the action');
}

View File

@@ -0,0 +1,46 @@
import { Routes } from '@angular/router';
// ui
import { AppBadgeComponent } from './badge/badge.component';
import { AppChipsComponent } from './chips/chips.component';
import { AppListsComponent } from './lists/lists.component';
import { AppMenuComponent } from './menu/menu.component';
import { AppTooltipsComponent } from './tooltips/tooltips.component';
import { AppFormsComponent } from './forms/forms.component';
import { AppTablesComponent } from './tables/tables.component';
export const UiComponentsRoutes: Routes = [
{
path: '',
children: [
{
path: 'badge',
component: AppBadgeComponent,
},
{
path: 'chips',
component: AppChipsComponent,
},
{
path: 'lists',
component: AppListsComponent,
},
{
path: 'menu',
component: AppMenuComponent,
},
{
path: 'tooltips',
component: AppTooltipsComponent,
},
{
path: 'forms',
component: AppFormsComponent,
},
{
path: 'tables',
component: AppTablesComponent,
},
],
},
];

View File

@@ -0,0 +1,18 @@
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({ name: 'appFilter', standalone: true, pure: true })
export class FilterPipe implements PipeTransform {
transform(items: any[], searchText: string): any[] {
if (!items) {
return [];
}
if (!searchText) {
return items;
}
searchText = searchText.toLocaleLowerCase();
return items.filter((it) => {
return it.displayName.toLocaleLowerCase().includes(searchText);
});
}
}

View File

@@ -0,0 +1,21 @@
import { Injectable, signal } from '@angular/core';
import { AppSettings, defaults } from '../config';
@Injectable({
providedIn: 'root',
})
export class CoreService {
private optionsSignal = signal<AppSettings>(defaults);
getOptions() {
return this.optionsSignal();
}
setOptions(options: Partial<AppSettings>) {
this.optionsSignal.update((current) => ({
...current,
...options,
}));
}
}

View File

@@ -0,0 +1,17 @@
import { Injectable, signal } from '@angular/core';
import { Event, NavigationEnd, Router } from '@angular/router';
@Injectable({ providedIn: 'root' })
export class NavService {
showClass: any = false;
public currentUrl = signal<string | undefined>(undefined);
constructor(private router: Router) {
this.router.events.subscribe((event: Event) => {
if (event instanceof NavigationEnd) {
this.currentUrl.set(event.urlAfterRedirects);
}
});
}
}

View File

View File

@@ -0,0 +1,7 @@
{
"Starter": "Menüebene",
"Menu Level": "Menüebene",
"Menu 1": "Menü 1",
"Menu 2": "Menü 2",
"Disabled": "Behinderte"
}

View File

@@ -0,0 +1,7 @@
{
"Starter": "Starter",
"Menu Level": "Menu Level",
"Menu 1": "Menu 1",
"Menu 2": "Menu 2",
"Disabled": "Disabled"
}

View File

@@ -0,0 +1,7 @@
{
"Starter": "Analítica",
"Menu Level": "Nível do menu",
"Menu 1": "Menu 1",
"Menu 2": "Menu 2",
"Disabled": "Desabilitada"
}

View File

@@ -0,0 +1,7 @@
{
"Starter": "Analytique",
"Menu Level": "Niveau menu",
"Menu 1": "Menu 1",
"Menu 2": "Menu 2",
"Disabled": "Désactivé"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.5 KiB

View File

@@ -0,0 +1,26 @@
<svg width="174" height="37" viewBox="0 0 174 37" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_191_340)">
<mask id="mask0_191_340" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="0" width="174" height="37">
<path d="M173.774 0H0V37H173.774V0Z" fill="white"/>
</mask>
<g mask="url(#mask0_191_340)">
<path d="M14.9806 5.34988C15.3855 4.66071 15.9677 4.08845 16.6687 3.69058C17.3699 3.29271 18.1651 3.08325 18.9747 3.08325C19.7842 3.08325 20.5795 3.29271 21.2805 3.69058C21.9817 4.08845 22.5639 4.66071 22.9686 5.34988L35.7495 27.1114C36.1542 27.8005 36.3674 28.5823 36.3674 29.3782C36.3674 30.174 36.1542 30.9557 35.7495 31.6449C35.3446 32.3341 34.7625 32.9064 34.0615 33.3043C33.3604 33.7022 32.5651 33.9119 31.7555 33.9119H6.19296C5.38339 33.9119 4.58806 33.7022 3.88696 33.3043C3.18589 32.9064 2.60369 32.3341 2.19891 31.6449C1.79413 30.9557 1.58105 30.174 1.58105 29.3782C1.58106 28.5823 1.79415 27.8005 2.19893 27.1114L14.9806 5.34988Z" fill="#3772FF"/>
<path d="M18.8598 17.6157C19.3927 17.9094 19.7853 18.3989 19.9514 18.9771C20.1174 19.555 20.0433 20.1742 19.7453 20.6986L12.5192 33.9124H6.93408L15.7208 18.4852C15.8689 18.2255 16.0675 17.997 16.3053 17.8128C16.5432 17.6286 16.8157 17.4922 17.1072 17.4114C17.3986 17.3306 17.7034 17.3071 18.0042 17.3422C18.3049 17.3773 18.5956 17.4701 18.8598 17.6157Z" fill="#90DBFB"/>
<path d="M19.8809 33.916L24.0225 26.645C24.1704 26.3853 24.369 26.1567 24.6068 25.9724C24.8446 25.7881 25.1171 25.6516 25.4085 25.5708C25.7 25.4899 26.0048 25.4663 26.3056 25.5013C26.6063 25.5363 26.8972 25.6292 27.1613 25.7746C27.4256 25.92 27.6581 26.1152 27.8457 26.349C28.0332 26.5828 28.172 26.8506 28.2542 27.1371C28.3364 27.4237 28.3605 27.7233 28.3248 28.0189C28.2893 28.3146 28.1949 28.6004 28.0469 28.8601L25.1709 33.9107" fill="white"/>
<path d="M63.6293 26.5951H67.1707L60.7964 10.6963H57.0194L50.5979 26.5951H54.0446L55.4375 22.9623H62.2364L63.6293 26.5951ZM58.837 14.1272L61.1506 20.1369H56.5236L58.837 14.1272Z" fill="white"/>
<path d="M79.6801 10.3604H76.5876V16.6616C76.257 16.0786 75.3127 15.2937 73.3061 15.2937C70.0249 15.2937 67.7349 17.8276 67.7349 21.0567C67.7349 24.3979 70.0957 26.8646 73.4005 26.8646C74.9588 26.8646 76.1391 26.1919 76.6584 25.3173C76.6584 25.8331 76.7292 26.3713 76.7764 26.5955H79.7748C79.7276 26.147 79.6801 25.3398 79.6801 24.5998V10.3604ZM70.8981 21.0567C70.8981 19.0834 72.173 17.9622 73.7783 17.9622C75.3838 17.9622 76.6348 19.061 76.6348 21.0343C76.6348 23.0301 75.3838 24.1961 73.7783 24.1961C72.1259 24.1961 70.8981 23.0301 70.8981 21.0567Z" fill="white"/>
<path d="M85.99 26.5957V20.1375C85.99 18.9266 86.7928 17.9624 88.1621 17.9624C89.5785 17.9624 90.2159 18.8593 90.2159 20.0478V26.5957H93.3319V20.1375C93.3319 18.949 94.1347 17.9624 95.4804 17.9624C96.9205 17.9624 97.5342 18.8593 97.5342 20.0478V26.5957H100.579V19.4424C100.579 16.4824 98.5257 15.249 96.3775 15.249C94.8428 15.249 93.6153 15.7424 92.6946 17.0878C92.1045 15.8993 90.8296 15.249 89.2479 15.249C87.973 15.249 86.4858 15.832 85.8485 16.9084V15.563H82.8503V26.5957H85.99Z" fill="white"/>
<path d="M106.664 26.5951V15.5623H103.525V26.5951H106.664ZM103.146 11.952C103.146 12.9387 104.02 13.7684 105.083 13.7684C106.168 13.7684 107.018 12.9387 107.018 11.952C107.018 10.9205 106.168 10.0908 105.083 10.0908C104.02 10.0908 103.146 10.9205 103.146 11.952Z" fill="white"/>
<path d="M112.929 20.2492C112.929 18.971 113.732 17.9619 115.101 17.9619C116.612 17.9619 117.249 18.9262 117.249 20.1595V26.5952H120.389V19.6437C120.389 17.2219 119.067 15.271 116.187 15.271C114.936 15.271 113.543 15.7868 112.835 16.9304V15.5625H109.789V26.5952H112.929V20.2492Z" fill="white"/>
<path d="M142.25 26.5951V10.6963H137.812L132.902 22.1775L127.873 10.6963H123.577V26.5951H126.693V15.5399L131.509 26.5951H134.224L139.04 15.4502V26.5951H142.25Z" fill="white"/>
<path d="M144.852 23.5903C144.852 25.317 146.363 26.9091 148.842 26.9091C150.565 26.9091 151.675 26.1467 152.265 25.2721C152.265 25.6982 152.312 26.3036 152.383 26.5951H155.263C155.192 26.2139 155.121 25.4291 155.121 24.8461V19.4194C155.121 17.1994 153.752 15.2261 150.069 15.2261C146.953 15.2261 145.277 17.1321 145.088 18.8588L147.874 19.4194C147.968 18.4551 148.724 17.6255 150.093 17.6255C151.415 17.6255 152.052 18.2758 152.052 19.0606C152.052 19.4418 151.84 19.7558 151.179 19.8455L148.322 20.2491C146.386 20.5182 144.852 21.617 144.852 23.5903ZM149.503 24.6891C148.488 24.6891 147.992 24.0612 147.992 23.4109C147.992 22.5588 148.629 22.1327 149.432 22.0206L152.052 21.6394V22.1327C152.052 24.0836 150.825 24.6891 149.503 24.6891Z" fill="white"/>
<path d="M165.131 15.5177C164.895 15.4953 164.659 15.4729 164.399 15.4729C163.407 15.4729 161.802 15.742 161.094 17.1996V15.5626H158.048V26.5953H161.188V21.5499C161.188 19.1729 162.581 18.4329 164.186 18.4329C164.47 18.4329 164.777 18.4553 165.131 18.5226V15.5177Z" fill="white"/>
<path d="M171.437 12.2666H168.604V13.8139C168.604 14.8005 168.038 15.563 166.81 15.563H166.22V18.209H168.321V23.3442C168.321 25.4745 169.737 26.7527 172.004 26.7527C172.924 26.7527 173.491 26.5957 173.774 26.4836V24.0169C173.609 24.0618 173.184 24.1066 172.806 24.1066C171.909 24.1066 171.437 23.7927 171.437 22.8284V18.209H173.774V15.563H171.437V12.2666Z" fill="white"/>
</g>
</g>
<defs>
<clipPath id="clip0_191_340">
<rect width="174" height="37" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

@@ -0,0 +1,12 @@
<svg width="26" height="27" viewBox="0 0 26 27" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_908_99)">
<path d="M0.0102539 4.51888L12.7873 0.0693359L25.9085 4.43976L23.7839 20.9624L12.7873 26.9149L1.96274 21.0415L0.0102539 4.51888Z" fill="#E23237"/>
<path d="M25.9087 4.43976L12.7876 0.0693359V26.9149L23.7842 20.9723L25.9087 4.43976Z" fill="#B52E31"/>
<path d="M12.8078 3.2041L4.84619 20.5178L7.82037 20.4683L9.41883 16.5626H16.561L18.3112 20.5178L21.1539 20.5672L12.8078 3.2041ZM12.8281 8.75121L15.519 14.2488H10.4607L12.8281 8.75121Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_908_99">
<rect width="26" height="27" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 693 B

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