Add branding assets for TIS tenant with logo and login image
This commit is contained in:
+49
-1
@@ -116,6 +116,10 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"fileReplacements": [
|
"fileReplacements": [
|
||||||
|
{
|
||||||
|
"replace": "src/assets/images/brandingAssets.ts",
|
||||||
|
"with": "src/tenants/tis/brandingAssets.ts"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"replace": "src/environments/environment.ts",
|
"replace": "src/environments/environment.ts",
|
||||||
"with": "src/environments/environment.tis.ts"
|
"with": "src/environments/environment.tis.ts"
|
||||||
@@ -132,6 +136,50 @@
|
|||||||
"outputHashing": "all",
|
"outputHashing": "all",
|
||||||
"outputPath": "dist/tis",
|
"outputPath": "dist/tis",
|
||||||
"serviceWorker": "ngsw-config.json"
|
"serviceWorker": "ngsw-config.json"
|
||||||
|
},
|
||||||
|
"tis-development": {
|
||||||
|
"assets": [
|
||||||
|
{
|
||||||
|
"glob": "**/*",
|
||||||
|
"input": "public-tis"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"budgets": [
|
||||||
|
{
|
||||||
|
"maximumError": "2.5MB",
|
||||||
|
"maximumWarning": "1.5MB",
|
||||||
|
"type": "initial"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"maximumError": "6kB",
|
||||||
|
"maximumWarning": "3kB",
|
||||||
|
"type": "anyComponentStyle"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"extractLicenses": false,
|
||||||
|
"fileReplacements": [
|
||||||
|
{
|
||||||
|
"replace": "src/assets/images/brandingAssets.ts",
|
||||||
|
"with": "src/tenants/tis/brandingAssets.ts"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"replace": "src/environments/environment.ts",
|
||||||
|
"with": "src/environments/environment.tis.ts"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"replace": "src/app.routes.ts",
|
||||||
|
"with": "src/tenants/tis/app.routes.ts"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"replace": "src/app/branding/branding.config.ts",
|
||||||
|
"with": "src/tenants/tis/branding.config.ts"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"optimization": false,
|
||||||
|
"outputHashing": "all",
|
||||||
|
"outputPath": "dist/tis",
|
||||||
|
"serviceWorker": "ngsw-config.json",
|
||||||
|
"sourceMap": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"defaultConfiguration": "production",
|
"defaultConfiguration": "production",
|
||||||
@@ -179,7 +227,7 @@
|
|||||||
"buildTarget": "pos.client:build:staging"
|
"buildTarget": "pos.client:build:staging"
|
||||||
},
|
},
|
||||||
"tis": {
|
"tis": {
|
||||||
"buildTarget": "pos.client:build:tis"
|
"buildTarget": "pos.client:build:tis-development"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"defaultConfiguration": "development",
|
"defaultConfiguration": "development",
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
"$schema": "./node_modules/@angular/service-worker/config/schema.json",
|
"$schema": "./node_modules/@angular/service-worker/config/schema.json",
|
||||||
"appData": {
|
"appData": {
|
||||||
"appVersion": "0.0.0",
|
"appVersion": "0.0.0",
|
||||||
"buildDate": "2026-05-10T09:04:30.388Z"
|
"buildDate": "2026-05-11T09:56:45.724Z"
|
||||||
},
|
},
|
||||||
"assetGroups": [
|
"assetGroups": [
|
||||||
{
|
{
|
||||||
|
|||||||
+2
-2
@@ -71,10 +71,10 @@
|
|||||||
"build:tis": "ng build --configuration tis",
|
"build:tis": "ng build --configuration tis",
|
||||||
"ng": "ng",
|
"ng": "ng",
|
||||||
"prebuild": "node scripts/update-ngsw-appdata.js",
|
"prebuild": "node scripts/update-ngsw-appdata.js",
|
||||||
"prebuild:tis": "node scripts/tis/prepare-tis-logo.js && node scripts/tis/update-tis-ngsw-appdata.js",
|
"prebuild:tis": "node scripts/tis/update-tis-ngsw-appdata.js",
|
||||||
"prestart": "node aspnetcore-https",
|
"prestart": "node aspnetcore-https",
|
||||||
"start": "run-script-os",
|
"start": "run-script-os",
|
||||||
"start:tis": "ng serve --configuration tis",
|
"start:tis": " ng serve --configuration tis",
|
||||||
"test": "ng test",
|
"test": "ng test",
|
||||||
"watch": "ng build --watch --configuration development"
|
"watch": "ng build --watch --configuration development"
|
||||||
},
|
},
|
||||||
|
|||||||
+26
-1
@@ -1 +1,26 @@
|
|||||||
export { appRoutes } from './tenants/default/app.routes';
|
import { CONSUMER_ROUTES } from '@/domains/consumer/routes';
|
||||||
|
import { PARTNER_ROUTES } from '@/domains/partner/routes';
|
||||||
|
import { POS_ROUTES } from '@/domains/pos/routes';
|
||||||
|
import { PROVIDER_ROUTES } from '@/domains/provider/routes';
|
||||||
|
import { SUPER_ADMIN_ROUTES } from '@/domains/superAdmin/routes';
|
||||||
|
import { Notfound } from '@/pages/notfound/notfound.component';
|
||||||
|
import { Routes } from '@angular/router';
|
||||||
|
|
||||||
|
export const appRoutes: Routes = [
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
loadComponent: () => import('@/layout/default/app.layout.component').then((m) => m.AppLayout),
|
||||||
|
children: [SUPER_ADMIN_ROUTES, CONSUMER_ROUTES, PROVIDER_ROUTES, PARTNER_ROUTES],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
...POS_ROUTES,
|
||||||
|
path: 'pos',
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
path: 'auth',
|
||||||
|
loadComponent: () => import('@/modules/auth/pages/auth.component').then((m) => m.AuthComponent),
|
||||||
|
},
|
||||||
|
{ path: 'notfound', component: Notfound },
|
||||||
|
{ path: '**', redirectTo: '/notfound' },
|
||||||
|
];
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
<div class="h-svh w-svw flex flex-col items-center justify-center">
|
||||||
|
<img [src]="logo" class="w-32 animate-pulse" />
|
||||||
|
<span class="text-xl font-medium text-center text-muted-color mt-4"> در حال بارگذاری ... </span>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import { Component, EventEmitter, inject, Output } from '@angular/core';
|
||||||
|
import { finalize, forkJoin } from 'rxjs';
|
||||||
|
import images from 'src/assets/images';
|
||||||
|
import { PosInfoStore, PosProfileStore } from '../store';
|
||||||
|
import { DeviceInfoStore } from '../store/device.store';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'pos-splash',
|
||||||
|
templateUrl: 'splash.component.html',
|
||||||
|
})
|
||||||
|
export class PosSplashComponent {
|
||||||
|
@Output() onComplete = new EventEmitter<void>();
|
||||||
|
|
||||||
|
private readonly posProfileStore = inject(PosProfileStore);
|
||||||
|
private readonly posInfoStore = inject(PosInfoStore);
|
||||||
|
private readonly deviceInfoStore = inject(DeviceInfoStore);
|
||||||
|
|
||||||
|
logo = images.logo;
|
||||||
|
|
||||||
|
async ngOnInit() {
|
||||||
|
const data = await this.deviceInfoStore.getData();
|
||||||
|
const profileObs = await this.posProfileStore.getData();
|
||||||
|
const infoObs = await this.posInfoStore.getData();
|
||||||
|
|
||||||
|
forkJoin([profileObs, infoObs])
|
||||||
|
.pipe(
|
||||||
|
finalize(() => {
|
||||||
|
this.onComplete.emit();
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.subscribe(([profileResult, infoResult]) => {});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,35 +1,13 @@
|
|||||||
<ng-template #topbarStart>
|
@if (showSplash()) {
|
||||||
<p-button (click)="toggleMenu()" icon="pi pi-bars" outlined size="large" />
|
<pos-splash (onComplete)="onSplashCompleted()" />
|
||||||
</ng-template>
|
} @else {
|
||||||
|
@defer (when !showSplash()) {
|
||||||
<ng-template #topbarCenter>
|
<div
|
||||||
@if (posInfo()) {
|
|
||||||
<a [routerLink]="homeRouteLink" class="flex flex-col items-center justify-center gap-2">
|
|
||||||
<div class="w-8 h-8">
|
|
||||||
<img
|
|
||||||
[src]="posInfo()?.partner?.logo_url ?? placeholderLogo"
|
|
||||||
alt="Logo"
|
|
||||||
class="w-full h-full object-cover rounded-md bg-surface-card"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<span class="text-base font-semibold">{{ posInfo()?.partner?.name }}</span>
|
|
||||||
</a>
|
|
||||||
}
|
|
||||||
</ng-template>
|
|
||||||
|
|
||||||
<ng-template #topbarEnd>
|
|
||||||
<div class="">
|
|
||||||
<p-menu #menu [model]="profileMenuItems" [popup]="true" />
|
|
||||||
<p-button (click)="menu.toggle($event)" icon="pi pi-user" outlined size="large" />
|
|
||||||
</div>
|
|
||||||
</ng-template>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="h-full relative"
|
class="h-full relative"
|
||||||
(touchstart)="onTouchStart($event)"
|
(touchstart)="onTouchStart($event)"
|
||||||
(touchmove)="onTouchMove($event)"
|
(touchmove)="onTouchMove($event)"
|
||||||
(touchend)="onTouchEnd()"
|
(touchend)="onTouchEnd()"
|
||||||
>
|
>
|
||||||
@if (pullDistance() >= 0) {
|
@if (pullDistance() >= 0) {
|
||||||
<div
|
<div
|
||||||
class="w-full flex justify-center items-center py-2 min-h-10 text-xs text-surface-500 overflow-hidden fixed top-0 inset-x-0 z-1000 translate-y-[-20px]"
|
class="w-full flex justify-center items-center py-2 min-h-10 text-xs text-surface-500 overflow-hidden fixed top-0 inset-x-0 z-1000 translate-y-[-20px]"
|
||||||
@@ -47,55 +25,13 @@
|
|||||||
<!-- [ngStyle]="{ transform: 'scale(1.' + pullDistance() * 10 + ')' }" -->
|
<!-- [ngStyle]="{ transform: 'scale(1.' + pullDistance() * 10 + ')' }" -->
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@if (loading()) {
|
@if (isAuth()) {
|
||||||
<shared-page-loading />
|
|
||||||
} @else {
|
|
||||||
<!-- <div class="w-svw h-svh bg-surface-ground flex flex-col gap-4 p-4"> -->
|
|
||||||
<!-- <div class="w-full flex items-center gap-4 shrink-0 justify-between">
|
|
||||||
<div class="flex gap-2 items-center">
|
|
||||||
@if (posInfo()) {
|
|
||||||
<div class="w-10 h-10">
|
|
||||||
<img [src]="placeholderLogo" alt="Logo" class="w-full h-full object-cover rounded-md bg-surface-card" />
|
|
||||||
</div>
|
|
||||||
<span class="text-lg font-bold">
|
|
||||||
{{ posInfo()?.name }} ({{ posInfo()?.complex!.name }} - {{ posInfo()?.businessActivity!.name }})
|
|
||||||
</span>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
<div class="flex gap-2 items-center">
|
|
||||||
<div class="bg-surface-card px-3 rounded-md shadow-sm h-9 flex items-center">
|
|
||||||
<span [jalaliDate]="now" jalaliFormat="dddd YYYY/MM/DD" class="text-base"></span>
|
|
||||||
</div>
|
|
||||||
<div class="">
|
|
||||||
<p-menu #menu [model]="profileMenuItems" [popup]="true" />
|
|
||||||
<button pButton (click)="menu.toggle($event)" icon="pi pi-user" severity="contrast">
|
|
||||||
{{ posProfile()?.account?.username }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div> -->
|
|
||||||
@if (error()) {
|
|
||||||
@switch (error()?.status) {
|
|
||||||
@case (412) {
|
|
||||||
<pos-choose-cards class="h-full" (onChoose)="onChoosePos()" />
|
|
||||||
}
|
|
||||||
@default {
|
|
||||||
<div class="h-full w-full flex items-center justify-center">
|
|
||||||
<p-card class="border border-surface-border">
|
|
||||||
<div class="flex flex-col gap-2 items-center justify-between shrink-0">
|
|
||||||
<i class="pi pi-exclamation-triangle text-6xl! mb-3 text-error" aria-hidden="true"></i>
|
|
||||||
<span class="text-xl font-semibold mb-2 text-error block"> عدم دسترسی </span>
|
|
||||||
<p class="inline-block text-base">متاسفانه امکان دسترسی برای کاربر شما فراهم نیست</p>
|
|
||||||
<button pButton outlined severity="danger" class="mt-5 w-32" (click)="logout()">خروج</button>
|
|
||||||
</div>
|
|
||||||
</p-card>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} @else {
|
|
||||||
<pos-main-menu-sidebar [(visible)]="mainMenuVisible" />
|
|
||||||
<router-outlet></router-outlet>
|
<router-outlet></router-outlet>
|
||||||
|
} @else {
|
||||||
|
@defer (when !isAuth()) {
|
||||||
|
<pos-pages-layout />
|
||||||
}
|
}
|
||||||
<!-- </div> -->
|
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,143 +1,25 @@
|
|||||||
import { AuthService } from '@/core';
|
|
||||||
import { LayoutService } from '@/layout/service/layout.service';
|
|
||||||
import { PageLoadingComponent } from '@/shared/components/page-loading.component';
|
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import {
|
import { Component, computed, signal } from '@angular/core';
|
||||||
AfterViewInit,
|
import { RouterOutlet } from '@angular/router';
|
||||||
Component,
|
import { PosSplashComponent } from '../components/splash.component';
|
||||||
TemplateRef,
|
import { PosPagesLayoutComponent } from './pagesLayout/layout.component';
|
||||||
ViewChild,
|
|
||||||
computed,
|
|
||||||
inject,
|
|
||||||
signal,
|
|
||||||
} from '@angular/core';
|
|
||||||
import { RouterLinkWithHref, RouterOutlet } from '@angular/router';
|
|
||||||
import { MenuItem } from 'primeng/api';
|
|
||||||
import { Button, ButtonDirective } from 'primeng/button';
|
|
||||||
import { Card } from 'primeng/card';
|
|
||||||
import { Menu } from 'primeng/menu';
|
|
||||||
import { finalize } from 'rxjs';
|
|
||||||
import images from 'src/assets/images';
|
|
||||||
import { PosInfoStore, PosProfileStore } from '../store';
|
|
||||||
import { DeviceInfoStore } from '../store/device.store';
|
|
||||||
import { PosChooseCardsComponent } from './choose-pos.component';
|
|
||||||
import { PosMainMenuSidebarComponent } from './mainMenuSidebar/main-menu-sidebar.component';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'pos-layout',
|
selector: 'pos-layout',
|
||||||
templateUrl: './layout.component.html',
|
templateUrl: 'layout.component.html',
|
||||||
imports: [
|
imports: [PosSplashComponent, PosPagesLayoutComponent, RouterOutlet, CommonModule],
|
||||||
PageLoadingComponent,
|
|
||||||
RouterOutlet,
|
|
||||||
ButtonDirective,
|
|
||||||
Card,
|
|
||||||
PosChooseCardsComponent,
|
|
||||||
Button,
|
|
||||||
PosMainMenuSidebarComponent,
|
|
||||||
Menu,
|
|
||||||
CommonModule,
|
|
||||||
RouterLinkWithHref,
|
|
||||||
],
|
|
||||||
})
|
})
|
||||||
export class PosLayoutComponent implements AfterViewInit {
|
export class PosLayoutComponent {
|
||||||
constructor() {}
|
showSplash = signal(true);
|
||||||
|
isAuth = computed(() => window.location.pathname === '/auth');
|
||||||
|
|
||||||
// private readonly nativeBridgeService = inject(NativeBridgeService);
|
|
||||||
// private readonly toastService = inject(ToastService);
|
|
||||||
|
|
||||||
@ViewChild('topbarStart', { static: true }) topbarStart!: TemplateRef<any>;
|
|
||||||
@ViewChild('topbarCenter', { static: true }) topbarCenter!: TemplateRef<any>;
|
|
||||||
@ViewChild('topbarEnd', { static: true }) topbarEnd!: TemplateRef<any>;
|
|
||||||
|
|
||||||
private readonly posProfileStore = inject(PosProfileStore);
|
|
||||||
private readonly posInfoStore = inject(PosInfoStore);
|
|
||||||
private readonly deviceInfoStore = inject(DeviceInfoStore);
|
|
||||||
private readonly authService = inject(AuthService);
|
|
||||||
private readonly layoutService = inject(LayoutService);
|
|
||||||
|
|
||||||
mainMenuVisible = signal(false);
|
|
||||||
|
|
||||||
readonly posProfileLoading = computed(() => this.posProfileStore.loading());
|
|
||||||
readonly posProfile = computed(() => this.posProfileStore.entity());
|
|
||||||
readonly posProfileError = computed(() => this.posProfileStore.error());
|
|
||||||
|
|
||||||
readonly posInfoLoading = computed(() => this.posInfoStore.loading());
|
|
||||||
readonly posInfo = computed(() => this.posInfoStore.entity());
|
|
||||||
readonly posInfoError = computed(() => this.posInfoStore.error());
|
|
||||||
|
|
||||||
readonly loading = computed(() => this.posProfileLoading());
|
|
||||||
readonly error = computed(() => this.posProfileError());
|
|
||||||
|
|
||||||
readonly deviceInfo = computed(() => this.deviceInfoStore.entity());
|
|
||||||
|
|
||||||
logout = () => {
|
|
||||||
this.authService.logout();
|
|
||||||
};
|
|
||||||
|
|
||||||
profileMenuItems: MenuItem[] = [
|
|
||||||
{
|
|
||||||
label: 'راهنمای سامانه',
|
|
||||||
icon: 'pi pi-question-circle',
|
|
||||||
disabled: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'خروج',
|
|
||||||
icon: 'pi pi-sign-out',
|
|
||||||
command: this.logout,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
placeholderLogo = images.placeholders.logo;
|
|
||||||
|
|
||||||
now = new Date();
|
|
||||||
private touchStartY = 0;
|
private touchStartY = 0;
|
||||||
private pulling = false;
|
private pulling = false;
|
||||||
pullDistance = signal(0);
|
pullDistance = signal(0);
|
||||||
readonly pullThreshold = 80;
|
readonly pullThreshold = 80;
|
||||||
|
|
||||||
homeRouteLink = '/pos';
|
onSplashCompleted() {
|
||||||
|
this.showSplash.set(false);
|
||||||
async getData() {
|
|
||||||
await this.layoutService.changeFullPageLoading(true);
|
|
||||||
await this.deviceInfoStore.getData();
|
|
||||||
await this.posProfileStore.getData().subscribe({
|
|
||||||
next: () => {
|
|
||||||
this.posInfoStore
|
|
||||||
.getData()
|
|
||||||
.pipe(
|
|
||||||
finalize(() => {
|
|
||||||
this.layoutService.changeFullPageLoading(false);
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.subscribe();
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleMenu() {
|
|
||||||
this.mainMenuVisible.update((v) => !v);
|
|
||||||
}
|
|
||||||
|
|
||||||
onChoosePos() {
|
|
||||||
this.getData();
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.layoutService.changeIsFullPage(true);
|
|
||||||
this.getData();
|
|
||||||
}
|
|
||||||
|
|
||||||
ngAfterViewInit() {
|
|
||||||
this.layoutService.setTopbarStartSlot(this.topbarStart);
|
|
||||||
this.layoutService.setTopbarCenterSlot(this.topbarCenter);
|
|
||||||
this.layoutService.setTopbarEndSlot(this.topbarEnd);
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnDestroy() {
|
|
||||||
this.layoutService.changeIsFullPage(false);
|
|
||||||
this.layoutService.setTopbarStartSlot(null);
|
|
||||||
this.layoutService.setTopbarCenterSlot(null);
|
|
||||||
this.layoutService.setTopbarEndSlot(null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onTouchStart(event: TouchEvent) {
|
onTouchStart(event: TouchEvent) {
|
||||||
@@ -165,8 +47,7 @@ export class PosLayoutComponent implements AfterViewInit {
|
|||||||
this.pulling = false;
|
this.pulling = false;
|
||||||
this.pullDistance.set(0);
|
this.pullDistance.set(0);
|
||||||
if (shouldRefresh) {
|
if (shouldRefresh) {
|
||||||
this.layoutService.changeIsFullPage(true);
|
this.showSplash.set(true);
|
||||||
this.getData();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -8,8 +8,8 @@ import { Card } from 'primeng/card';
|
|||||||
import { Message } from 'primeng/message';
|
import { Message } from 'primeng/message';
|
||||||
import { catchError, finalize } from 'rxjs';
|
import { catchError, finalize } from 'rxjs';
|
||||||
import { COOKIE_KEYS } from 'src/assets/constants';
|
import { COOKIE_KEYS } from 'src/assets/constants';
|
||||||
import { IPosAccessibleResponse } from '../models/pos.io';
|
import { IPosAccessibleResponse } from '../../models/pos.io';
|
||||||
import { PosService } from '../modules/landing/services/main.service';
|
import { PosService } from '../../modules/landing/services/main.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'pos-choose-cards',
|
selector: 'pos-choose-cards',
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
<ng-template #topbarStart>
|
||||||
|
<p-button (click)="toggleMenu()" icon="pi pi-bars" outlined size="large" />
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<ng-template #topbarCenter>
|
||||||
|
@if (posInfo()) {
|
||||||
|
<a [routerLink]="homeRouteLink" class="flex flex-col items-center justify-center gap-2">
|
||||||
|
<div class="w-8 h-8">
|
||||||
|
<img
|
||||||
|
[src]="posInfo()?.partner?.logo_url ?? placeholderLogo"
|
||||||
|
alt="Logo"
|
||||||
|
class="w-full h-full object-cover rounded-md bg-surface-card"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<span class="text-base font-semibold">{{ posInfo()?.partner?.name }}</span>
|
||||||
|
</a>
|
||||||
|
}
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<ng-template #topbarEnd>
|
||||||
|
<div class="">
|
||||||
|
<p-menu #menu [model]="profileMenuItems" [popup]="true" />
|
||||||
|
<p-button (click)="menu.toggle($event)" icon="pi pi-user" outlined size="large" />
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
@if (loading()) {
|
||||||
|
<shared-page-loading />
|
||||||
|
} @else {
|
||||||
|
<!-- <div class="w-svw h-svh bg-surface-ground flex flex-col gap-4 p-4"> -->
|
||||||
|
<!-- <div class="w-full flex items-center gap-4 shrink-0 justify-between">
|
||||||
|
<div class="flex gap-2 items-center">
|
||||||
|
@if (posInfo()) {
|
||||||
|
<div class="w-10 h-10">
|
||||||
|
<img [src]="placeholderLogo" alt="Logo" class="w-full h-full object-cover rounded-md bg-surface-card" />
|
||||||
|
</div>
|
||||||
|
<span class="text-lg font-bold">
|
||||||
|
{{ posInfo()?.name }} ({{ posInfo()?.complex!.name }} - {{ posInfo()?.businessActivity!.name }})
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<div class="flex gap-2 items-center">
|
||||||
|
<div class="bg-surface-card px-3 rounded-md shadow-sm h-9 flex items-center">
|
||||||
|
<span [jalaliDate]="now" jalaliFormat="dddd YYYY/MM/DD" class="text-base"></span>
|
||||||
|
</div>
|
||||||
|
<div class="">
|
||||||
|
<p-menu #menu [model]="profileMenuItems" [popup]="true" />
|
||||||
|
<button pButton (click)="menu.toggle($event)" icon="pi pi-user" severity="contrast">
|
||||||
|
{{ posProfile()?.account?.username }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div> -->
|
||||||
|
@if (error()) {
|
||||||
|
@switch (error()?.status) {
|
||||||
|
@case (412) {
|
||||||
|
<pos-choose-cards class="h-full" (onChoose)="onChoosePos()" />
|
||||||
|
}
|
||||||
|
@default {
|
||||||
|
<div class="h-full w-full flex items-center justify-center">
|
||||||
|
<p-card class="border border-surface-border">
|
||||||
|
<div class="flex flex-col gap-2 items-center justify-between shrink-0">
|
||||||
|
<i class="pi pi-exclamation-triangle text-6xl! mb-3 text-error" aria-hidden="true"></i>
|
||||||
|
<span class="text-xl font-semibold mb-2 text-error block"> عدم دسترسی </span>
|
||||||
|
<p class="inline-block text-base">متاسفانه امکان دسترسی برای کاربر شما فراهم نیست</p>
|
||||||
|
<button pButton outlined severity="danger" class="mt-5 w-32" (click)="logout()">خروج</button>
|
||||||
|
</div>
|
||||||
|
</p-card>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} @else {
|
||||||
|
<pos-main-menu-sidebar [(visible)]="mainMenuVisible" />
|
||||||
|
<router-outlet></router-outlet>
|
||||||
|
}
|
||||||
|
<!-- </div> -->
|
||||||
|
}
|
||||||
@@ -0,0 +1,131 @@
|
|||||||
|
import { AuthService } from '@/core';
|
||||||
|
import { LayoutService } from '@/layout/service/layout.service';
|
||||||
|
import { PageLoadingComponent } from '@/shared/components/page-loading.component';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import {
|
||||||
|
AfterViewInit,
|
||||||
|
Component,
|
||||||
|
TemplateRef,
|
||||||
|
ViewChild,
|
||||||
|
computed,
|
||||||
|
inject,
|
||||||
|
signal,
|
||||||
|
} from '@angular/core';
|
||||||
|
import { RouterLinkWithHref, RouterOutlet } from '@angular/router';
|
||||||
|
import { MenuItem } from 'primeng/api';
|
||||||
|
import { Button, ButtonDirective } from 'primeng/button';
|
||||||
|
import { Card } from 'primeng/card';
|
||||||
|
import { Menu } from 'primeng/menu';
|
||||||
|
import images from 'src/assets/images';
|
||||||
|
import { PosInfoStore, PosProfileStore } from '../../store';
|
||||||
|
import { DeviceInfoStore } from '../../store/device.store';
|
||||||
|
import { PosMainMenuSidebarComponent } from '../mainMenuSidebar/main-menu-sidebar.component';
|
||||||
|
import { PosChooseCardsComponent } from './choose-pos.component';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'pos-pages-layout',
|
||||||
|
templateUrl: './layout.component.html',
|
||||||
|
imports: [
|
||||||
|
PageLoadingComponent,
|
||||||
|
ButtonDirective,
|
||||||
|
Card,
|
||||||
|
PosChooseCardsComponent,
|
||||||
|
Button,
|
||||||
|
PosMainMenuSidebarComponent,
|
||||||
|
Menu,
|
||||||
|
CommonModule,
|
||||||
|
RouterLinkWithHref,
|
||||||
|
RouterOutlet,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class PosPagesLayoutComponent implements AfterViewInit {
|
||||||
|
constructor() {}
|
||||||
|
|
||||||
|
// private readonly nativeBridgeService = inject(NativeBridgeService);
|
||||||
|
// private readonly toastService = inject(ToastService);
|
||||||
|
|
||||||
|
@ViewChild('topbarStart', { static: true }) topbarStart!: TemplateRef<any>;
|
||||||
|
@ViewChild('topbarCenter', { static: true }) topbarCenter!: TemplateRef<any>;
|
||||||
|
@ViewChild('topbarEnd', { static: true }) topbarEnd!: TemplateRef<any>;
|
||||||
|
|
||||||
|
private readonly posProfileStore = inject(PosProfileStore);
|
||||||
|
private readonly posInfoStore = inject(PosInfoStore);
|
||||||
|
private readonly deviceInfoStore = inject(DeviceInfoStore);
|
||||||
|
private readonly authService = inject(AuthService);
|
||||||
|
private readonly layoutService = inject(LayoutService);
|
||||||
|
|
||||||
|
mainMenuVisible = signal(false);
|
||||||
|
|
||||||
|
readonly posProfileLoading = computed(() => this.posProfileStore.loading());
|
||||||
|
readonly posProfile = computed(() => this.posProfileStore.entity());
|
||||||
|
readonly posProfileError = computed(() => this.posProfileStore.error());
|
||||||
|
|
||||||
|
readonly posInfoLoading = computed(() => this.posInfoStore.loading());
|
||||||
|
readonly posInfo = computed(() => this.posInfoStore.entity());
|
||||||
|
readonly posInfoError = computed(() => this.posInfoStore.error());
|
||||||
|
|
||||||
|
readonly loading = computed(() => this.posProfileLoading());
|
||||||
|
readonly error = computed(() => this.posProfileError());
|
||||||
|
|
||||||
|
readonly deviceInfo = computed(() => this.deviceInfoStore.entity());
|
||||||
|
|
||||||
|
logout = () => {
|
||||||
|
this.authService.logout();
|
||||||
|
};
|
||||||
|
|
||||||
|
profileMenuItems: MenuItem[] = [
|
||||||
|
{
|
||||||
|
label: 'راهنمای سامانه',
|
||||||
|
icon: 'pi pi-question-circle',
|
||||||
|
disabled: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'خروج',
|
||||||
|
icon: 'pi pi-sign-out',
|
||||||
|
command: this.logout,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
placeholderLogo = images.placeholders.logo;
|
||||||
|
|
||||||
|
now = new Date();
|
||||||
|
|
||||||
|
homeRouteLink = '/pos';
|
||||||
|
|
||||||
|
async getData() {
|
||||||
|
// await this.layoutService.changeFullPageLoading(true);
|
||||||
|
// await this.posProfileStore.getData().subscribe({
|
||||||
|
// next: () => {
|
||||||
|
// this.posInfoStore
|
||||||
|
// .getData()
|
||||||
|
// .pipe(
|
||||||
|
// finalize(() => {
|
||||||
|
// this.layoutService.changeFullPageLoading(false);
|
||||||
|
// }),
|
||||||
|
// )
|
||||||
|
// .subscribe();
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleMenu() {
|
||||||
|
this.mainMenuVisible.update((v) => !v);
|
||||||
|
}
|
||||||
|
|
||||||
|
onChoosePos() {
|
||||||
|
this.getData();
|
||||||
|
}
|
||||||
|
|
||||||
|
ngAfterViewInit() {
|
||||||
|
this.layoutService.setTopbarStartSlot(this.topbarStart);
|
||||||
|
this.layoutService.setTopbarCenterSlot(this.topbarCenter);
|
||||||
|
this.layoutService.setTopbarEndSlot(this.topbarEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy() {
|
||||||
|
this.layoutService.changeIsFullPage(false);
|
||||||
|
this.layoutService.setTopbarStartSlot(null);
|
||||||
|
this.layoutService.setTopbarCenterSlot(null);
|
||||||
|
this.layoutService.setTopbarEndSlot(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
export interface IDeviceProfileRawResponse {
|
export interface IDeviceProfileRawResponse {
|
||||||
androidId: string;
|
deviceId: string;
|
||||||
deviceName: string;
|
deviceName: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<div class="flex flex-col min-h-full">
|
<div class="flex flex-col min-h-full">
|
||||||
<div class="bg-surface-ground z-10 p-4 border-b border-surface-border shadow-[0_-4px_16px_rgba(0,0,0,0.08)]">
|
<div class="bg-surface-card z-10 p-4 border-b border-surface-border shadow-[0_-4px_16px_rgba(0,0,0,0.08)] rounded-xl">
|
||||||
<div class="flex items-center justify-end mb-4">
|
<div class="flex items-center justify-end mb-4">
|
||||||
<!-- <div class="flex items-center gap-2 text-muted-color">
|
<!-- <div class="flex items-center gap-2 text-muted-color">
|
||||||
<i class="pi pi-list"></i>
|
<i class="pi pi-list"></i>
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
<shared-page-loading />
|
<shared-page-loading />
|
||||||
} @else if (pos()) {
|
} @else if (pos()) {
|
||||||
<div class="w-full min-h-[calc(100dvh-5.5rem)] md:overflow-hidden">
|
<div class="w-full min-h-[calc(100dvh-5.5rem)] md:overflow-hidden">
|
||||||
<div [class]="`w-full h-full flex max-md:flex-col gap-4 pb-4 pt-0`">
|
<div class="w-full! h-full flex max-md:flex-col gap-4 pt-0">
|
||||||
<div class="grow min-h-[calc(100dvh-5.5rem)]">
|
<div class="grow min-h-[calc(100dvh-5.5rem)] w-full">
|
||||||
<pos-goods class="block h-full" />
|
<pos-goods class="block h-full" />
|
||||||
</div>
|
</div>
|
||||||
@if (!isMobile()) {
|
@if (!isMobile()) {
|
||||||
|
|||||||
@@ -43,9 +43,9 @@ export class PosLandingComponent extends AbstractIsMobileComponent {
|
|||||||
readonly priceInfo = computed(() => this.landingStore.orderPricingInfo());
|
readonly priceInfo = computed(() => this.landingStore.orderPricingInfo());
|
||||||
readonly showInvoiceBottomSheet = signal(false);
|
readonly showInvoiceBottomSheet = signal(false);
|
||||||
|
|
||||||
getData() {
|
// getData() {
|
||||||
this.infoStore.getData().subscribe();
|
// this.infoStore.getData().subscribe();
|
||||||
}
|
// }
|
||||||
|
|
||||||
openInvoiceBottomSheet() {
|
openInvoiceBottomSheet() {
|
||||||
this.showInvoiceBottomSheet.set(true);
|
this.showInvoiceBottomSheet.set(true);
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import { POS_SALE_INVOICES_ROUTES } from './modules/saleInvoices/constants';
|
|||||||
import { POS_SUPPORT_ROUTES } from './modules/support/constants';
|
import { POS_SUPPORT_ROUTES } from './modules/support/constants';
|
||||||
|
|
||||||
export const POS_ROUTES = {
|
export const POS_ROUTES = {
|
||||||
path: 'pos',
|
path: '',
|
||||||
loadComponent: () => import('./layouts/layout.component').then((m) => m.PosLayoutComponent),
|
loadComponent: () => import('@/layout/default/app.layout.component').then((m) => m.AppLayout),
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ export class DeviceInfoStore extends EntityStore<IDeviceProfileResponse, DeviceI
|
|||||||
const deviceInfo = deviceInfoRes.data;
|
const deviceInfo = deviceInfoRes.data;
|
||||||
this.setEntity({
|
this.setEntity({
|
||||||
deviceName: deviceInfo.deviceName,
|
deviceName: deviceInfo.deviceName,
|
||||||
androidId: deviceInfo.androidId,
|
deviceId: deviceInfo.androidId,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.setError(
|
this.setError(
|
||||||
|
|||||||
@@ -137,29 +137,29 @@ export class AppLayout {
|
|||||||
this.layoutService.topbarCenterSlot$.subscribe((tpl) => (this.topBarCenterAction = tpl));
|
this.layoutService.topbarCenterSlot$.subscribe((tpl) => (this.topBarCenterAction = tpl));
|
||||||
this.layoutService.topbarEndSlot$.subscribe((tpl) => (this.topBarEndAction = tpl));
|
this.layoutService.topbarEndSlot$.subscribe((tpl) => (this.topBarEndAction = tpl));
|
||||||
|
|
||||||
if (window.location.pathname === '/') {
|
// if (window.location.pathname === '/') {
|
||||||
if (!this.authService.currentAccount()) {
|
// if (!this.authService.currentAccount()) {
|
||||||
this.router.navigateByUrl('auth');
|
// this.router.navigateByUrl('auth');
|
||||||
}
|
// }
|
||||||
switch (this.authService.currentAccount()?.type) {
|
// switch (this.authService.currentAccount()?.type) {
|
||||||
case 'ADMIN':
|
// case 'ADMIN':
|
||||||
this.router.navigateByUrl('super_admin');
|
// this.router.navigateByUrl('super_admin');
|
||||||
break;
|
// break;
|
||||||
case 'CONSUMER':
|
// case 'CONSUMER':
|
||||||
if (this.authService.currentAccount()?.role === 'OWNER')
|
// if (this.authService.currentAccount()?.role === 'OWNER')
|
||||||
this.router.navigateByUrl('consumer');
|
// this.router.navigateByUrl('consumer');
|
||||||
else {
|
// // else {
|
||||||
this.router.navigateByUrl('pos');
|
// // this.router.navigateByUrl('pos');
|
||||||
}
|
// // }
|
||||||
break;
|
// break;
|
||||||
case 'PARTNER':
|
// case 'PARTNER':
|
||||||
this.router.navigateByUrl('partner');
|
// this.router.navigateByUrl('partner');
|
||||||
break;
|
// break;
|
||||||
case 'PROVIDER':
|
// case 'PROVIDER':
|
||||||
this.router.navigateByUrl('provider');
|
// this.router.navigateByUrl('provider');
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
|
|||||||
@@ -84,7 +84,7 @@
|
|||||||
@if (expandable && expandColumns && expandableItemKey) {
|
@if (expandable && expandColumns && expandableItemKey) {
|
||||||
<ng-template #expandedrow let-item>
|
<ng-template #expandedrow let-item>
|
||||||
<tr>
|
<tr>
|
||||||
<td [attr.colspan]="columns.length + 1">
|
<td [attr.colspan]="columns.length + 1 + (showIndex ? 1 : 0) + (actionsCount() ? 1 : 0)">
|
||||||
<div class="px-4">
|
<div class="px-4">
|
||||||
@if (item[expandableItemKey]?.length) {
|
@if (item[expandableItemKey]?.length) {
|
||||||
<p-table
|
<p-table
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
[size]="size"
|
[size]="size"
|
||||||
[invalid]="passwordControl.touched && passwordControl.invalid"
|
[invalid]="passwordControl.touched && passwordControl.invalid"
|
||||||
/>
|
/>
|
||||||
<span class="text-xs mt-1 mb-3 text-muted-color">
|
<span class="text-xs mt-1 text-muted-color">
|
||||||
{{ hint }}
|
{{ hint }}
|
||||||
</span>
|
</span>
|
||||||
</uikit-field>
|
</uikit-field>
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
pre.app-code {
|
|
||||||
background-color: var(--code-background);
|
|
||||||
margin: 0 0 1rem 0;
|
|
||||||
padding: 0;
|
|
||||||
border-radius: var(--content-border-radius);
|
|
||||||
overflow: auto;
|
|
||||||
|
|
||||||
code {
|
|
||||||
color: var(--code-color);
|
|
||||||
padding: 1rem;
|
|
||||||
margin: 0;
|
|
||||||
line-height: 1.5;
|
|
||||||
display: block;
|
|
||||||
font-weight: semibold;
|
|
||||||
font-family: monaco, Consolas, monospace;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
@use './code.scss';
|
|
||||||
@use './flags/flags';
|
|
||||||
File diff suppressed because one or more lines are too long
Binary file not shown.
|
Before Width: | Height: | Size: 54 KiB |
@@ -0,0 +1,7 @@
|
|||||||
|
import login from './login.jpg';
|
||||||
|
import logo from './logo.png';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
logo,
|
||||||
|
login,
|
||||||
|
};
|
||||||
@@ -1,13 +1,9 @@
|
|||||||
// Export the public URL for static assets so bundlers don't need a loader for binary imports.
|
import brandingAssets from './brandingAssets';
|
||||||
// The Angular CLI / build serves files in `src/assets` at `/assets`.
|
|
||||||
import errors from './errors';
|
import errors from './errors';
|
||||||
import login from './login.jpg';
|
|
||||||
import logo from './logo.png';
|
|
||||||
import { placeholders } from './placeholders';
|
import { placeholders } from './placeholders';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
logo,
|
...brandingAssets,
|
||||||
login,
|
|
||||||
errors,
|
errors,
|
||||||
placeholders,
|
placeholders,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -49,10 +49,6 @@ const MyPreset = definePreset(Aura, {
|
|||||||
950: '{surface.950}',
|
950: '{surface.950}',
|
||||||
},
|
},
|
||||||
colorScheme: {
|
colorScheme: {
|
||||||
colorScheme: {
|
|
||||||
light: {},
|
|
||||||
dark: {},
|
|
||||||
},
|
|
||||||
light: {
|
light: {
|
||||||
surface: {
|
surface: {
|
||||||
0: '#fcfcfc',
|
0: '#fcfcfc',
|
||||||
|
|||||||
@@ -3,20 +3,18 @@ import { PARTNER_ROUTES } from '@/domains/partner/routes';
|
|||||||
import { POS_ROUTES } from '@/domains/pos/routes';
|
import { POS_ROUTES } from '@/domains/pos/routes';
|
||||||
import { PROVIDER_ROUTES } from '@/domains/provider/routes';
|
import { PROVIDER_ROUTES } from '@/domains/provider/routes';
|
||||||
import { SUPER_ADMIN_ROUTES } from '@/domains/superAdmin/routes';
|
import { SUPER_ADMIN_ROUTES } from '@/domains/superAdmin/routes';
|
||||||
import { AppLayout } from '@/layout/default/app.layout.component';
|
|
||||||
import { AuthComponent } from '@/modules/auth/pages/auth.component';
|
|
||||||
import { Notfound } from '@/pages/notfound/notfound.component';
|
import { Notfound } from '@/pages/notfound/notfound.component';
|
||||||
import { Routes } from '@angular/router';
|
import { Routes } from '@angular/router';
|
||||||
|
|
||||||
export const appRoutes: Routes = [
|
export const appRoutes: Routes = [
|
||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
component: AppLayout,
|
loadComponent: () => import('@/layout/default/app.layout.component').then((m) => m.AppLayout),
|
||||||
children: [SUPER_ADMIN_ROUTES, CONSUMER_ROUTES, PROVIDER_ROUTES, PARTNER_ROUTES, POS_ROUTES],
|
children: [SUPER_ADMIN_ROUTES, CONSUMER_ROUTES, PROVIDER_ROUTES, PARTNER_ROUTES, POS_ROUTES],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'auth',
|
path: 'auth',
|
||||||
component: AuthComponent,
|
loadComponent: () => import('@/modules/auth/pages/auth.component').then((m) => m.AuthComponent),
|
||||||
},
|
},
|
||||||
{ path: 'notfound', component: Notfound },
|
{ path: 'notfound', component: Notfound },
|
||||||
{ path: '**', redirectTo: '/notfound' },
|
{ path: '**', redirectTo: '/notfound' },
|
||||||
|
|||||||
@@ -1,18 +1,20 @@
|
|||||||
import { POS_ROUTES } from '@/domains/pos/routes';
|
import { POS_ROUTES } from '@/domains/pos/routes';
|
||||||
import { AppLayout } from '@/layout/default/app.layout.component';
|
|
||||||
import { AuthComponent } from '@/modules/auth/pages/auth.component';
|
|
||||||
import { Notfound } from '@/pages/notfound/notfound.component';
|
import { Notfound } from '@/pages/notfound/notfound.component';
|
||||||
import { Routes } from '@angular/router';
|
import { Routes } from '@angular/router';
|
||||||
|
|
||||||
export const appRoutes: Routes = [
|
export const appRoutes: Routes = [
|
||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
component: AppLayout,
|
loadComponent: () =>
|
||||||
children: [POS_ROUTES],
|
import('@/domains/pos/layouts/layout.component').then((m) => m.PosLayoutComponent),
|
||||||
},
|
children: [
|
||||||
|
POS_ROUTES,
|
||||||
{
|
{
|
||||||
path: 'auth',
|
path: 'auth',
|
||||||
component: AuthComponent,
|
loadComponent: () =>
|
||||||
|
import('@/modules/auth/pages/auth.component').then((m) => m.AuthComponent),
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{ path: 'notfound', component: Notfound },
|
{ path: 'notfound', component: Notfound },
|
||||||
{ path: '**', redirectTo: '/notfound' },
|
{ path: '**', redirectTo: '/notfound' },
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 83 KiB |
@@ -0,0 +1,7 @@
|
|||||||
|
import login from 'src/tenants/tis/assets/images/login.jpg';
|
||||||
|
import logo from 'src/tenants/tis/assets/images/logo.png';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
logo,
|
||||||
|
login,
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user