ui update, init to consumer statistics and manage pos user types
This commit is contained in:
@@ -8,11 +8,9 @@ import { ToastModule } from 'primeng/toast';
|
|||||||
standalone: true,
|
standalone: true,
|
||||||
imports: [RouterModule, ToastModule, ConfirmDialog],
|
imports: [RouterModule, ToastModule, ConfirmDialog],
|
||||||
template: `
|
template: `
|
||||||
<div>
|
<p-toast position="bottom-right" />
|
||||||
<p-toast position="bottom-right" />
|
<p-confirmDialog />
|
||||||
<p-confirmDialog />
|
<router-outlet />
|
||||||
<router-outlet />
|
|
||||||
</div>
|
|
||||||
`,
|
`,
|
||||||
})
|
})
|
||||||
export class AppComponent {}
|
export class AppComponent {}
|
||||||
|
|||||||
+1
-1
@@ -4,11 +4,11 @@ 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 { AuthComponent } from '@/modules/auth/pages/auth.component';
|
import { AuthComponent } from '@/modules/auth/pages/auth.component';
|
||||||
|
import { Notfound } from '@/pages/notfound/notfound.component';
|
||||||
import { Routes } from '@angular/router';
|
import { Routes } from '@angular/router';
|
||||||
import { AppLayout } from './app/layout/default/app.layout.component';
|
import { AppLayout } from './app/layout/default/app.layout.component';
|
||||||
import { Dashboard } from './app/pages/dashboard/dashboard';
|
import { Dashboard } from './app/pages/dashboard/dashboard';
|
||||||
import { Documentation } from './app/pages/documentation/documentation';
|
import { Documentation } from './app/pages/documentation/documentation';
|
||||||
import { Notfound } from './app/pages/notfound/notfound.component';
|
|
||||||
|
|
||||||
export const appRoutes: Routes = [
|
export const appRoutes: Routes = [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ export const errorInterceptor: HttpInterceptorFn = (req, next) => {
|
|||||||
errorMessage = 'منبع مورد نظر یافت نشد';
|
errorMessage = 'منبع مورد نظر یافت نشد';
|
||||||
break;
|
break;
|
||||||
case 412:
|
case 412:
|
||||||
errorMessage = error.error?.detail || 'اطلاعات ارسالی نامعتبر است';
|
errorMessage = error.error?.message || '';
|
||||||
break;
|
break;
|
||||||
case 422:
|
case 422:
|
||||||
errorMessage = error.error?.message || 'اطلاعات ارسالی نامعتبر است';
|
errorMessage = error.error?.message || 'اطلاعات ارسالی نامعتبر است';
|
||||||
@@ -118,6 +118,7 @@ function showErrorNotification(message: string, status: number): void {
|
|||||||
* Error types for better error handling
|
* Error types for better error handling
|
||||||
*/
|
*/
|
||||||
export enum ErrorType {
|
export enum ErrorType {
|
||||||
|
PRE_CONDITION = 'PRE_CONDITION',
|
||||||
NETWORK = 'NETWORK',
|
NETWORK = 'NETWORK',
|
||||||
SERVER = 'SERVER',
|
SERVER = 'SERVER',
|
||||||
CLIENT = 'CLIENT',
|
CLIENT = 'CLIENT',
|
||||||
@@ -136,9 +137,10 @@ export function getErrorType(error: HttpErrorResponse): ErrorType {
|
|||||||
|
|
||||||
switch (error.status) {
|
switch (error.status) {
|
||||||
case 400:
|
case 400:
|
||||||
case 412:
|
|
||||||
case 422:
|
case 422:
|
||||||
return ErrorType.VALIDATION;
|
return ErrorType.VALIDATION;
|
||||||
|
case 412:
|
||||||
|
return ErrorType.PRE_CONDITION;
|
||||||
case 401:
|
case 401:
|
||||||
return ErrorType.AUTHENTICATION;
|
return ErrorType.AUTHENTICATION;
|
||||||
case 403:
|
case 403:
|
||||||
|
|||||||
@@ -5,9 +5,10 @@
|
|||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import { computed, inject, Injectable, signal } from '@angular/core';
|
import { computed, inject, Injectable, signal } from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
|
import { CookieService } from 'ngx-cookie-service';
|
||||||
import { BehaviorSubject, Observable, throwError } from 'rxjs';
|
import { BehaviorSubject, Observable, throwError } from 'rxjs';
|
||||||
import { catchError, finalize, tap } from 'rxjs/operators';
|
import { catchError, finalize, tap } from 'rxjs/operators';
|
||||||
import { LOCAL_STORAGE_KEYS } from '../../../assets/constants';
|
import { COOKIE_KEYS, LOCAL_STORAGE_KEYS } from '../../../assets/constants';
|
||||||
import {
|
import {
|
||||||
IAuthAccountResponse,
|
IAuthAccountResponse,
|
||||||
IAuthResponse,
|
IAuthResponse,
|
||||||
@@ -28,6 +29,7 @@ export class AuthService {
|
|||||||
|
|
||||||
private readonly http = inject(HttpClient);
|
private readonly http = inject(HttpClient);
|
||||||
private readonly router = inject(Router);
|
private readonly router = inject(Router);
|
||||||
|
private readonly cookieService = inject(CookieService);
|
||||||
private captchaService = inject(CaptchaService);
|
private captchaService = inject(CaptchaService);
|
||||||
|
|
||||||
private readonly currentAccountSubject = new BehaviorSubject<Maybe<IAuthAccountResponse>>(null);
|
private readonly currentAccountSubject = new BehaviorSubject<Maybe<IAuthAccountResponse>>(null);
|
||||||
@@ -81,6 +83,7 @@ export class AuthService {
|
|||||||
.pipe(
|
.pipe(
|
||||||
tap((response) => {
|
tap((response) => {
|
||||||
this.handleAuthSuccess(response);
|
this.handleAuthSuccess(response);
|
||||||
|
this.refreshCookies();
|
||||||
return response;
|
return response;
|
||||||
}),
|
}),
|
||||||
catchError((error) => {
|
catchError((error) => {
|
||||||
@@ -98,11 +101,17 @@ export class AuthService {
|
|||||||
localStorage.removeItem(LOCAL_STORAGE_KEYS.AUTH_TOKEN);
|
localStorage.removeItem(LOCAL_STORAGE_KEYS.AUTH_TOKEN);
|
||||||
localStorage.removeItem(LOCAL_STORAGE_KEYS.USER_DATA);
|
localStorage.removeItem(LOCAL_STORAGE_KEYS.USER_DATA);
|
||||||
localStorage.removeItem(LOCAL_STORAGE_KEYS.REFRESH_TOKEN);
|
localStorage.removeItem(LOCAL_STORAGE_KEYS.REFRESH_TOKEN);
|
||||||
|
this.refreshCookies();
|
||||||
|
|
||||||
this.setCurrentUser(null);
|
this.setCurrentUser(null);
|
||||||
this.router.navigate(['/auth']);
|
this.router.navigate(['/auth']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
refreshCookies() {
|
||||||
|
this.cookieService.set(COOKIE_KEYS.POS_ID, '', new Date());
|
||||||
|
this.cookieService.set(COOKIE_KEYS.ACCESS_TOKEN, '', new Date());
|
||||||
|
}
|
||||||
|
|
||||||
doRefreshToken(): Observable<IAuthResponse> {
|
doRefreshToken(): Observable<IAuthResponse> {
|
||||||
const refreshToken = this.getRefreshToken();
|
const refreshToken = this.getRefreshToken();
|
||||||
if (!refreshToken) {
|
if (!refreshToken) {
|
||||||
|
|||||||
@@ -26,33 +26,33 @@ export class ErrorHandlerService {
|
|||||||
*/
|
*/
|
||||||
private handleHttpError(error: HttpErrorResponse): void {
|
private handleHttpError(error: HttpErrorResponse): void {
|
||||||
const errorType = getErrorType(error);
|
const errorType = getErrorType(error);
|
||||||
|
|
||||||
const userMessage = this.getUserMessage(error);
|
const userMessage = this.getUserMessage(error);
|
||||||
|
|
||||||
if (userMessage) {
|
switch (errorType) {
|
||||||
this.toastService.error({
|
case ErrorType.NETWORK:
|
||||||
title: error.error?.title || 'خطا',
|
this.showNetworkError(userMessage);
|
||||||
text: userMessage,
|
break;
|
||||||
});
|
case ErrorType.PRE_CONDITION:
|
||||||
} else {
|
this.showPreConditionError(userMessage);
|
||||||
switch (errorType) {
|
break;
|
||||||
case ErrorType.NETWORK:
|
case ErrorType.AUTHENTICATION:
|
||||||
this.showNetworkError(userMessage);
|
this.showAuthError(userMessage);
|
||||||
break;
|
break;
|
||||||
case ErrorType.AUTHENTICATION:
|
case ErrorType.AUTHORIZATION:
|
||||||
this.showAuthError(userMessage);
|
this.showAuthorizationError(userMessage);
|
||||||
break;
|
break;
|
||||||
case ErrorType.AUTHORIZATION:
|
case ErrorType.VALIDATION:
|
||||||
this.showAuthorizationError(userMessage);
|
this.showValidationError(userMessage, error);
|
||||||
break;
|
break;
|
||||||
case ErrorType.VALIDATION:
|
case ErrorType.SERVER:
|
||||||
this.showValidationError(userMessage, error);
|
this.showServerError(userMessage);
|
||||||
break;
|
break;
|
||||||
case ErrorType.SERVER:
|
case ErrorType.SERVER:
|
||||||
this.showServerError(userMessage);
|
this.showServerError(userMessage);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
this.showGenericError(userMessage);
|
this.showGenericError(userMessage);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,7 +60,6 @@ export class ErrorHandlerService {
|
|||||||
* Handle generic JavaScript errors
|
* Handle generic JavaScript errors
|
||||||
*/
|
*/
|
||||||
private handleGenericError(error: any): void {
|
private handleGenericError(error: any): void {
|
||||||
console.error('Generic error:', error);
|
|
||||||
this.toastService.error({
|
this.toastService.error({
|
||||||
text: 'یک خطای غیرمنتظره رخ داده است. لطفاً صفحه را تازهسازی کنید.',
|
text: 'یک خطای غیرمنتظره رخ داده است. لطفاً صفحه را تازهسازی کنید.',
|
||||||
});
|
});
|
||||||
@@ -76,6 +75,15 @@ export class ErrorHandlerService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show preCondition error notification
|
||||||
|
*/
|
||||||
|
private showPreConditionError(message: string): void {
|
||||||
|
this.toastService.warn({
|
||||||
|
text: message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show authentication error notification
|
* Show authentication error notification
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { HttpErrorResponse } from '@angular/common/http';
|
||||||
import { Signal, WritableSignal, computed, signal } from '@angular/core';
|
import { Signal, WritableSignal, computed, signal } from '@angular/core';
|
||||||
import { BehaviorSubject, Observable } from 'rxjs';
|
import { BehaviorSubject, Observable } from 'rxjs';
|
||||||
import { Maybe } from '../models';
|
import { Maybe } from '../models';
|
||||||
@@ -8,7 +9,7 @@ import { IPaginatedQuery, IResponseMetadata } from '../models/service.model';
|
|||||||
*/
|
*/
|
||||||
export interface BaseState {
|
export interface BaseState {
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
error: Maybe<string>;
|
error: Maybe<HttpErrorResponse>;
|
||||||
isRefreshing?: boolean;
|
isRefreshing?: boolean;
|
||||||
initialized: boolean;
|
initialized: boolean;
|
||||||
}
|
}
|
||||||
@@ -72,6 +73,15 @@ export interface StateChange<T = any> {
|
|||||||
timestamp: number;
|
timestamp: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const defaultBaseStateData = {
|
||||||
|
loading: false,
|
||||||
|
error: null,
|
||||||
|
errorStatus: null,
|
||||||
|
entity: null,
|
||||||
|
initialized: false,
|
||||||
|
isRefreshing: false,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base store class with common functionality
|
* Base store class with common functionality
|
||||||
*/
|
*/
|
||||||
@@ -82,7 +92,7 @@ export abstract class BaseStore<T extends BaseState> {
|
|||||||
// Public readonly signals
|
// Public readonly signals
|
||||||
readonly state: Signal<T>;
|
readonly state: Signal<T>;
|
||||||
readonly loading: Signal<boolean>;
|
readonly loading: Signal<boolean>;
|
||||||
readonly error: Signal<Maybe<string>>;
|
readonly error: Signal<Maybe<HttpErrorResponse>>;
|
||||||
readonly initialized: Signal<boolean>;
|
readonly initialized: Signal<boolean>;
|
||||||
|
|
||||||
// Observable for RxJS compatibility
|
// Observable for RxJS compatibility
|
||||||
@@ -135,7 +145,7 @@ export abstract class BaseStore<T extends BaseState> {
|
|||||||
/**
|
/**
|
||||||
* Set error state
|
* Set error state
|
||||||
*/
|
*/
|
||||||
protected setError(error: string): void {
|
protected setError(error: HttpErrorResponse): void {
|
||||||
this.patchState({
|
this.patchState({
|
||||||
loading: false,
|
loading: false,
|
||||||
error,
|
error,
|
||||||
@@ -180,6 +190,7 @@ export abstract class EntityStore<
|
|||||||
setEntity(entity: Maybe<T>): void {
|
setEntity(entity: Maybe<T>): void {
|
||||||
this.patchState({
|
this.patchState({
|
||||||
entity,
|
entity,
|
||||||
|
error: null,
|
||||||
} as Partial<TState>);
|
} as Partial<TState>);
|
||||||
}
|
}
|
||||||
override reset(): void {
|
override reset(): void {
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
<div class="flex flex-col gap-6">
|
||||||
|
<app-card-data cardTitle="اطلاعات فاکتور" [editable]="false" [(editMode)]="editMode">
|
||||||
|
<div class="flex flex-col gap-4">
|
||||||
|
<div class="grid grid-cols-3 gap-4 items-center">
|
||||||
|
<app-key-value label="کد رهگیری" [value]="invoice()?.code" />
|
||||||
|
<app-key-value label="تاریخ فاکتور" [value]="invoice()?.invoice_date" type="dateTime" />
|
||||||
|
<app-key-value label="تاریخ ایجاد فاکتور" [value]="invoice()?.created_at" type="dateTime" />
|
||||||
|
<app-key-value label="وضعیت صدور به سامانهی مودیان">
|
||||||
|
<p-badge value="ارسال نشده" severity="danger" />
|
||||||
|
</app-key-value>
|
||||||
|
<div class="col-span-3">
|
||||||
|
<app-key-value label="توضیحات" [value]="invoice()?.notes" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p-divider align="center"> اطلاعات پرداخت </p-divider>
|
||||||
|
<div class="grid grid-cols-3 gap-4 items-center">
|
||||||
|
<app-key-value label="مجموع قابل پرداخت" [value]="invoice()?.total_amount" type="price" />
|
||||||
|
@for (payment of invoice()?.payments; track $index) {
|
||||||
|
<app-key-value
|
||||||
|
[label]="
|
||||||
|
`${payment.payment_method === 'SET_OF' ? 'تهاتر' : payment.payment_method === 'TERMINAL' ? 'پایانه' : 'نقدی'}`
|
||||||
|
"
|
||||||
|
[value]="payment.amount"
|
||||||
|
type="price"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p-divider align="center"> اطلاعات صادر کننده </p-divider>
|
||||||
|
<div class="grid grid-cols-3 gap-4 items-center">
|
||||||
|
<app-key-value label="کسب و کار" [value]="invoice()?.pos!.complex.business_activity.name" />
|
||||||
|
<app-key-value label="مجموعه" [value]="invoice()?.pos!.complex.name" />
|
||||||
|
<app-key-value label="پایانهی فروش" [value]="invoice()?.pos!.name" />
|
||||||
|
<app-key-value label="ایجاد کننده" [value]="invoice()?.account?.account?.username" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@if (variant !== "customer") {
|
||||||
|
<p-divider align="center"> اطلاعات مشتری </p-divider>
|
||||||
|
<div class="grid grid-cols-3 gap-4 items-center">
|
||||||
|
@if (invoice()?.customer) {}
|
||||||
|
<!-- <app-key-value label="کسب و کار" [value]="invoice()?.pos!.complex.business_activity.name" />
|
||||||
|
<app-key-value label="مجموعه" [value]="invoice()?.pos!.complex.name" />
|
||||||
|
<app-key-value label="پایانهی فروش" [value]="invoice()?.pos!.name" />
|
||||||
|
<app-key-value label="ایجاد کننده" [value]="invoice()?.account?.account?.username" /> -->
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</app-card-data>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import { AppCardComponent, KeyValueComponent } from '@/shared/components';
|
||||||
|
import { Component, Input, signal } from '@angular/core';
|
||||||
|
import { Badge } from 'primeng/badge';
|
||||||
|
import { Divider } from 'primeng/divider';
|
||||||
|
|
||||||
|
export type TConsumerSaleInvoice = 'full' | 'customer' | 'pos';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'consumer-saleInvoice-shared',
|
||||||
|
templateUrl: './single.component.html',
|
||||||
|
imports: [AppCardComponent, KeyValueComponent, Badge, Divider],
|
||||||
|
})
|
||||||
|
export class ConsumerSaleInvoiceSharedComponent {
|
||||||
|
@Input({ required: true }) loading!: boolean;
|
||||||
|
@Input({ required: true }) invoice!: any;
|
||||||
|
@Input() editable = false;
|
||||||
|
@Input() variant: TConsumerSaleInvoice = 'full';
|
||||||
|
|
||||||
|
editMode = signal<boolean>(false);
|
||||||
|
}
|
||||||
@@ -31,6 +31,8 @@ export class LayoutComponent {
|
|||||||
});
|
});
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
|
console.log('first');
|
||||||
|
|
||||||
this.layoutService.setMenuItems(CONSUMER_MENU_ITEMS);
|
this.layoutService.setMenuItems(CONSUMER_MENU_ITEMS);
|
||||||
this.store.getData();
|
this.store.getData();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { EntityState, EntityStore } from '@/core/state';
|
import { EntityState, EntityStore } from '@/core/state';
|
||||||
import { computed, inject, Injectable } from '@angular/core';
|
import { computed, inject, Injectable } from '@angular/core';
|
||||||
import { MenuItem } from 'primeng/api';
|
import { MenuItem } from 'primeng/api';
|
||||||
import { catchError, finalize, throwError } from 'rxjs';
|
import { catchError, finalize } from 'rxjs';
|
||||||
import { consumerAccountsNamedRoutes } from '../constants';
|
import { consumerAccountsNamedRoutes } from '../constants';
|
||||||
import { IAccountResponse } from '../models';
|
import { IAccountResponse } from '../models';
|
||||||
import { AccountsService } from '../services/main.service';
|
import { AccountsService } from '../services/main.service';
|
||||||
@@ -51,11 +51,9 @@ export class AccountStore extends EntityStore<IAccountResponse, AccountState> {
|
|||||||
finalize(() => {
|
finalize(() => {
|
||||||
this.patchState({ loading: false });
|
this.patchState({ loading: false });
|
||||||
}),
|
}),
|
||||||
catchError(() => {
|
catchError((error) => {
|
||||||
this.patchState({
|
this.setError(error);
|
||||||
error: '',
|
throw error;
|
||||||
});
|
|
||||||
return throwError('');
|
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.subscribe((entity) => {
|
.subscribe((entity) => {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { EntityState, EntityStore } from '@/core/state';
|
import { EntityState, EntityStore } from '@/core/state';
|
||||||
import { computed, inject, Injectable } from '@angular/core';
|
import { computed, inject, Injectable } from '@angular/core';
|
||||||
import { MenuItem } from 'primeng/api';
|
import { MenuItem } from 'primeng/api';
|
||||||
import { catchError, finalize, throwError } from 'rxjs';
|
import { catchError, finalize } from 'rxjs';
|
||||||
import { consumerBusinessActivityNamedRoutes } from '../constants';
|
import { consumerBusinessActivityNamedRoutes } from '../constants';
|
||||||
import { IBusinessActivityResponse } from '../models';
|
import { IBusinessActivityResponse } from '../models';
|
||||||
import { BusinessActivitiesService } from '../services/main.service';
|
import { BusinessActivitiesService } from '../services/main.service';
|
||||||
@@ -55,11 +55,9 @@ export class BusinessActivityStore extends EntityStore<
|
|||||||
finalize(() => {
|
finalize(() => {
|
||||||
this.patchState({ loading: false });
|
this.patchState({ loading: false });
|
||||||
}),
|
}),
|
||||||
catchError(() => {
|
catchError((error) => {
|
||||||
this.patchState({
|
this.setError(error);
|
||||||
error: '',
|
throw error;
|
||||||
});
|
|
||||||
return throwError('');
|
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.subscribe((entity) => {
|
.subscribe((entity) => {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { EntityState, EntityStore } from '@/core/state';
|
import { EntityState, EntityStore } from '@/core/state';
|
||||||
import { computed, inject, Injectable } from '@angular/core';
|
import { computed, inject, Injectable } from '@angular/core';
|
||||||
import { MenuItem } from 'primeng/api';
|
import { MenuItem } from 'primeng/api';
|
||||||
import { catchError, finalize, throwError } from 'rxjs';
|
import { catchError, finalize } from 'rxjs';
|
||||||
import { consumerComplexesNamedRoutes } from '../constants/routes/complexes';
|
import { consumerComplexesNamedRoutes } from '../constants/routes/complexes';
|
||||||
import { IComplexResponse } from '../models';
|
import { IComplexResponse } from '../models';
|
||||||
import { ConsumerComplexesService } from '../services/complexes.service';
|
import { ConsumerComplexesService } from '../services/complexes.service';
|
||||||
@@ -50,11 +50,9 @@ export class ConsumerComplexStore extends EntityStore<IComplexResponse, ComplexS
|
|||||||
finalize(() => {
|
finalize(() => {
|
||||||
this.patchState({ loading: false });
|
this.patchState({ loading: false });
|
||||||
}),
|
}),
|
||||||
catchError(() => {
|
catchError((error) => {
|
||||||
this.patchState({
|
this.setError(error);
|
||||||
error: '',
|
throw error;
|
||||||
});
|
|
||||||
return throwError('');
|
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.subscribe((entity) => {
|
.subscribe((entity) => {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { EntityState, EntityStore } from '@/core/state';
|
import { EntityState, EntityStore } from '@/core/state';
|
||||||
import { computed, inject, Injectable } from '@angular/core';
|
import { computed, inject, Injectable } from '@angular/core';
|
||||||
import { MenuItem } from 'primeng/api';
|
import { MenuItem } from 'primeng/api';
|
||||||
import { catchError, finalize, throwError } from 'rxjs';
|
import { catchError, finalize } from 'rxjs';
|
||||||
import { consumerPosesNamedRoutes } from '../constants/routes/poses';
|
import { consumerPosesNamedRoutes } from '../constants/routes/poses';
|
||||||
import { IPosResponse } from '../models';
|
import { IPosResponse } from '../models';
|
||||||
import { ConsumerPosesService } from '../services/poses.service';
|
import { ConsumerPosesService } from '../services/poses.service';
|
||||||
@@ -51,11 +51,9 @@ export class PosStore extends EntityStore<IPosResponse, PosState> {
|
|||||||
finalize(() => {
|
finalize(() => {
|
||||||
this.patchState({ loading: false });
|
this.patchState({ loading: false });
|
||||||
}),
|
}),
|
||||||
catchError(() => {
|
catchError((error) => {
|
||||||
this.patchState({
|
this.setError(error);
|
||||||
error: '',
|
throw error;
|
||||||
});
|
|
||||||
return throwError('');
|
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.subscribe((entity) => {
|
.subscribe((entity) => {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { Component, computed, effect, inject, signal } from '@angular/core';
|
|||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { CookieService } from 'ngx-cookie-service';
|
import { CookieService } from 'ngx-cookie-service';
|
||||||
import { Button } from 'primeng/button';
|
import { Button } from 'primeng/button';
|
||||||
|
import { COOKIE_KEYS } from 'src/assets/constants';
|
||||||
import { ConsumerPosFormComponent } from '../../components/poses/form.component';
|
import { ConsumerPosFormComponent } from '../../components/poses/form.component';
|
||||||
import { ConsumerSalesInvoicesComponent } from '../../components/salesInvoices/list.component';
|
import { ConsumerSalesInvoicesComponent } from '../../components/salesInvoices/list.component';
|
||||||
import { BusinessActivityStore } from '../../store/businessActivity.store';
|
import { BusinessActivityStore } from '../../store/businessActivity.store';
|
||||||
@@ -53,8 +54,8 @@ export class SuperAdminUserPosComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
toPosLanding() {
|
toPosLanding() {
|
||||||
// this.cookieService.delete('posId', '/', 'localhost', false, 'Lax');
|
this.cookieService.set(COOKIE_KEYS.POS_ID, '', new Date());
|
||||||
this.cookieService.set('posId', this.posId(), {
|
this.cookieService.set(COOKIE_KEYS.POS_ID, this.posId(), {
|
||||||
sameSite: 'Lax', // or 'Strict' for same-site requests only
|
sameSite: 'Lax', // or 'Strict' for same-site requests only
|
||||||
secure: false,
|
secure: false,
|
||||||
path: '/',
|
path: '/',
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { EntityState, EntityStore } from '@/core/state';
|
import { EntityState, EntityStore } from '@/core/state';
|
||||||
import { computed, inject, Injectable } from '@angular/core';
|
import { computed, inject, Injectable } from '@angular/core';
|
||||||
import { MenuItem } from 'primeng/api';
|
import { MenuItem } from 'primeng/api';
|
||||||
import { catchError, finalize, throwError } from 'rxjs';
|
import { catchError, finalize } from 'rxjs';
|
||||||
import { consumerCustomersNamedRoutes } from '../constants';
|
import { consumerCustomersNamedRoutes } from '../constants';
|
||||||
import { ICustomerResponse } from '../models';
|
import { ICustomerResponse } from '../models';
|
||||||
import { CustomersService } from '../services/main.service';
|
import { CustomersService } from '../services/main.service';
|
||||||
@@ -54,11 +54,9 @@ export class ConsumerCustomerStore extends EntityStore<ICustomerResponse, Consum
|
|||||||
finalize(() => {
|
finalize(() => {
|
||||||
this.patchState({ loading: false });
|
this.patchState({ loading: false });
|
||||||
}),
|
}),
|
||||||
catchError(() => {
|
catchError((error) => {
|
||||||
this.patchState({
|
this.setError(error);
|
||||||
error: '',
|
throw error;
|
||||||
});
|
|
||||||
return throwError('');
|
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.subscribe((entity) => {
|
.subscribe((entity) => {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { EntityState, EntityStore } from '@/core/state';
|
import { EntityState, EntityStore } from '@/core/state';
|
||||||
import { computed, inject, Injectable } from '@angular/core';
|
import { computed, inject, Injectable } from '@angular/core';
|
||||||
import { MenuItem } from 'primeng/api';
|
import { MenuItem } from 'primeng/api';
|
||||||
import { catchError, finalize, throwError } from 'rxjs';
|
import { catchError, finalize } from 'rxjs';
|
||||||
import { consumerCustomerSaleInvoicesNamedRoutes } from '../constants/routes/saleInvoices';
|
import { consumerCustomerSaleInvoicesNamedRoutes } from '../constants/routes/saleInvoices';
|
||||||
import { ICustomerSaleInvoicesResponse } from '../models';
|
import { ICustomerSaleInvoicesResponse } from '../models';
|
||||||
import { CustomerSaleInvoicesService } from '../services/saleInvoices.service';
|
import { CustomerSaleInvoicesService } from '../services/saleInvoices.service';
|
||||||
@@ -58,11 +58,9 @@ export class ConsumerCustomerSaleInvoiceStore extends EntityStore<
|
|||||||
finalize(() => {
|
finalize(() => {
|
||||||
this.patchState({ loading: false });
|
this.patchState({ loading: false });
|
||||||
}),
|
}),
|
||||||
catchError(() => {
|
catchError((error) => {
|
||||||
this.patchState({
|
this.setError(error);
|
||||||
error: '',
|
throw error;
|
||||||
});
|
|
||||||
return throwError('');
|
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.subscribe((entity) => {
|
.subscribe((entity) => {
|
||||||
|
|||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
<app-page-data-list
|
||||||
|
pageTitle="آخرین فاکتورهای صادر شدهی امروز"
|
||||||
|
[columns]="columns"
|
||||||
|
emptyPlaceholderTitle="تا به این لحظه فاکتوری صادر نشده است."
|
||||||
|
[items]="items()"
|
||||||
|
[showDetails]="true"
|
||||||
|
[loading]="loading()"
|
||||||
|
(onDetails)="toSinglePage($event)"
|
||||||
|
>
|
||||||
|
<ng-template #moreActions>
|
||||||
|
<a routerLink pButton [routerLink]="invoicesPageRoute" outlined>تمامی فاکتورها</a>
|
||||||
|
</ng-template>
|
||||||
|
</app-page-data-list>
|
||||||
+42
@@ -0,0 +1,42 @@
|
|||||||
|
import { consumerSaleInvoicesNamedRoutes } from '@/domains/consumer/modules/saleInvoices/constants';
|
||||||
|
import { AbstractList } from '@/shared/abstractClasses';
|
||||||
|
import { PageDataListComponent } from '@/shared/components/pageDataList/page-data-list.component';
|
||||||
|
import { Component, inject } from '@angular/core';
|
||||||
|
import { Router, RouterLink } from '@angular/router';
|
||||||
|
import { ButtonDirective } from 'primeng/button';
|
||||||
|
import { IStatisticsSaleInvoicesResponse } from '../../../models';
|
||||||
|
import { CustomerStatisticsService } from '../../../services/main.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'consumer-statistics-latest-Invoices',
|
||||||
|
templateUrl: './latest-Invoices.component.html',
|
||||||
|
imports: [PageDataListComponent, ButtonDirective, RouterLink],
|
||||||
|
})
|
||||||
|
export class ConsumerStatisticsLatestInvoicesComponent extends AbstractList<IStatisticsSaleInvoicesResponse> {
|
||||||
|
private readonly service = inject(CustomerStatisticsService);
|
||||||
|
private readonly router = inject(Router);
|
||||||
|
|
||||||
|
readonly invoicesPageRoute = consumerSaleInvoicesNamedRoutes.saleInvoices.meta.pagePath!();
|
||||||
|
|
||||||
|
override setColumns(): void {
|
||||||
|
this.columns = [
|
||||||
|
{ field: 'code', header: 'کد پیگیری' },
|
||||||
|
{ field: 'total_amount', header: 'مجموع قیمت', type: 'price' },
|
||||||
|
{
|
||||||
|
field: 'created_at',
|
||||||
|
header: 'تاریخ ایجاد',
|
||||||
|
type: 'date',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
override getDataRequest() {
|
||||||
|
return this.service.getInvoices();
|
||||||
|
}
|
||||||
|
|
||||||
|
toSinglePage(invoice: IStatisticsSaleInvoicesResponse) {
|
||||||
|
this.router.navigateByUrl(
|
||||||
|
consumerSaleInvoicesNamedRoutes.saleInvoice.meta.pagePath!(invoice.id),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
const baseUrl = '/api/v1/consumer/statistics';
|
||||||
|
|
||||||
|
export const CONSUMER_STATISTICS_API_ROUTES = {
|
||||||
|
invoices: () => `${baseUrl}/invoices`,
|
||||||
|
};
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export * from './apiRoutes';
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export * from './saleInvoices.io';
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import ISummary from '@/core/models/summary';
|
||||||
|
|
||||||
|
export interface IStatisticsSaleInvoicesRawResponse {
|
||||||
|
id: string;
|
||||||
|
code: string;
|
||||||
|
created_date: string;
|
||||||
|
total_amount: string;
|
||||||
|
pos: Pos;
|
||||||
|
consumer_account: ConsumerAccount;
|
||||||
|
created_at: string;
|
||||||
|
}
|
||||||
|
export interface IStatisticsSaleInvoicesResponse extends IStatisticsSaleInvoicesRawResponse {}
|
||||||
|
|
||||||
|
interface ConsumerAccount {
|
||||||
|
role: string;
|
||||||
|
account: {
|
||||||
|
username: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Pos extends ISummary {
|
||||||
|
complex: Complex;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Complex extends ISummary {
|
||||||
|
business_activity: ISummary;
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import { IListingResponse } from '@/core/models/service.model';
|
||||||
|
import { HttpClient } from '@angular/common/http';
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { CONSUMER_STATISTICS_API_ROUTES } from '../constants';
|
||||||
|
import { IStatisticsSaleInvoicesRawResponse, IStatisticsSaleInvoicesResponse } from '../models';
|
||||||
|
|
||||||
|
@Injectable({ providedIn: 'root' })
|
||||||
|
export class CustomerStatisticsService {
|
||||||
|
constructor(private http: HttpClient) {}
|
||||||
|
|
||||||
|
private apiRoutes = CONSUMER_STATISTICS_API_ROUTES;
|
||||||
|
|
||||||
|
getInvoices(): Observable<IListingResponse<IStatisticsSaleInvoicesResponse>> {
|
||||||
|
return this.http.get<IListingResponse<IStatisticsSaleInvoicesRawResponse>>(
|
||||||
|
this.apiRoutes.invoices(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
<div class="flex items-center justify-center h-[100cqmin]">
|
<div class="grid grid-cols-2 gap-10">
|
||||||
<span class="text-center"> به پنل کسب و کار خوش آمدید </span>
|
<div class="h-[300px] flex">
|
||||||
|
<consumer-statistics-latest-Invoices class="w-full" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
|
import { ConsumerStatisticsLatestInvoicesComponent } from '../components/statistics/latestInvoices/latest-Invoices.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'consumer-dashboard',
|
selector: 'consumer-dashboard',
|
||||||
templateUrl: './index.component.html',
|
templateUrl: './index.component.html',
|
||||||
|
imports: [ConsumerStatisticsLatestInvoicesComponent],
|
||||||
})
|
})
|
||||||
export class DashboardComponent {
|
export class DashboardComponent {
|
||||||
constructor() {}
|
constructor() {}
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
@if (loading()) {
|
||||||
|
<shared-page-loading />
|
||||||
|
} @else {
|
||||||
|
<router-outlet></router-outlet>
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import { PageLoadingComponent } from '@/shared/components/page-loading.component';
|
||||||
|
import { Component, computed, inject, signal } from '@angular/core';
|
||||||
|
import { ActivatedRoute, RouterOutlet } from '@angular/router';
|
||||||
|
import { ConsumerSaleInvoiceStore } from '../store/main.store';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'consumer-customer-layout',
|
||||||
|
templateUrl: './layout.component.html',
|
||||||
|
imports: [PageLoadingComponent, RouterOutlet],
|
||||||
|
})
|
||||||
|
export class ConsumerCustomerLayoutComponent {
|
||||||
|
private readonly route = inject(ActivatedRoute);
|
||||||
|
private readonly store = inject(ConsumerSaleInvoiceStore);
|
||||||
|
|
||||||
|
readonly invoiceId = signal<string>(this.route.snapshot.paramMap.get('invoiceId')!);
|
||||||
|
|
||||||
|
readonly loading = computed(() => this.store.loading());
|
||||||
|
|
||||||
|
getData() {
|
||||||
|
this.store.getData(this.invoiceId());
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.getData();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
<app-page-data-list
|
||||||
|
[pageTitle]="'لیست فاکتورهای ایجاد شده'"
|
||||||
|
[columns]="columns"
|
||||||
|
emptyPlaceholderTitle="فاکتوری یافت نشد"
|
||||||
|
[items]="items()"
|
||||||
|
[loading]="loading()"
|
||||||
|
[showDetails]="true"
|
||||||
|
(onDetails)="toSinglePage($event)"
|
||||||
|
/>
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
// import { CatalogRoleTagComponent } from '@/shared/catalog/roles';
|
||||||
|
import { AbstractList } from '@/shared/abstractClasses/abstract-list';
|
||||||
|
import {
|
||||||
|
IColumn,
|
||||||
|
PageDataListComponent,
|
||||||
|
} from '@/shared/components/pageDataList/page-data-list.component';
|
||||||
|
import { Component, inject, Input } from '@angular/core';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
import { consumerSaleInvoicesNamedRoutes } from '../constants/routes';
|
||||||
|
import { IConsumerSaleInvoicesResponse } from '../models';
|
||||||
|
import { ConsumerSaleInvoicesService } from '../services/main.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'consumer-saleInvoice-list',
|
||||||
|
templateUrl: './list.component.html',
|
||||||
|
imports: [PageDataListComponent],
|
||||||
|
})
|
||||||
|
export class ConsumerSaleInvoiceListComponent extends AbstractList<IConsumerSaleInvoicesResponse> {
|
||||||
|
@Input() fullHeight?: boolean;
|
||||||
|
@Input() header: IColumn[] = [
|
||||||
|
{ field: 'code', header: 'کد رهگیری' },
|
||||||
|
{
|
||||||
|
field: 'total_amount',
|
||||||
|
header: 'قیمت نهایی',
|
||||||
|
type: 'price',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'pos',
|
||||||
|
header: 'فروشگاه',
|
||||||
|
customDataModel(item: IConsumerSaleInvoicesResponse) {
|
||||||
|
return `${item.pos.complex.business_activity.name}، فروشگاه ${item.pos.complex.name}، پایانهی فروش ${item.pos.name}`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'account',
|
||||||
|
header: 'ایجاد شده توسط',
|
||||||
|
type: 'nested',
|
||||||
|
nestedPath: 'account.account.username',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'invoice_date',
|
||||||
|
header: 'تاریخ فاکتور',
|
||||||
|
type: 'date',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'created_at',
|
||||||
|
header: 'تاریخ ایجاد',
|
||||||
|
type: 'date',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
private readonly service = inject(ConsumerSaleInvoicesService);
|
||||||
|
private readonly router = inject(Router);
|
||||||
|
|
||||||
|
override setColumns(): void {
|
||||||
|
this.columns = this.header;
|
||||||
|
}
|
||||||
|
|
||||||
|
override getDataRequest() {
|
||||||
|
return this.service.getAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
toSinglePage(item: IConsumerSaleInvoicesResponse) {
|
||||||
|
this.router.navigateByUrl(consumerSaleInvoicesNamedRoutes.saleInvoice.meta.pagePath!(item.id));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
const baseUrl = () => `/api/v1/consumer/sale-invoices`;
|
||||||
|
|
||||||
|
export const CONSUMER_SALE_INVOICES_API_ROUTES = {
|
||||||
|
list: () => baseUrl(),
|
||||||
|
single: (id: string) => `${baseUrl()}/${id}`,
|
||||||
|
};
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
export * from './apiRoutes';
|
||||||
|
export * from './routes';
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
import { NamedRoutes } from '@/core';
|
||||||
|
import { Routes } from '@angular/router';
|
||||||
|
|
||||||
|
export type TConsumerSaleInvoicesRouteNames = 'saleInvoices' | 'saleInvoice';
|
||||||
|
|
||||||
|
export const consumerSaleInvoicesNamedRoutes: NamedRoutes<TConsumerSaleInvoicesRouteNames> = {
|
||||||
|
saleInvoices: {
|
||||||
|
path: 'saleInvoices',
|
||||||
|
loadComponent: () =>
|
||||||
|
import('../../views/list.component').then((m) => m.ConsumerSaleInvoicesComponent),
|
||||||
|
meta: {
|
||||||
|
title: 'فاکتورهای صادر شده',
|
||||||
|
pagePath: () => `/consumer/saleInvoices`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
saleInvoice: {
|
||||||
|
path: 'saleInvoices/:invoiceId',
|
||||||
|
loadComponent: () =>
|
||||||
|
import('../../views/single.component').then((m) => m.ConsumerSaleInvoiceComponent),
|
||||||
|
meta: {
|
||||||
|
title: 'فاکتور صادر شده',
|
||||||
|
pagePath: (saleInvoiceId: string) => `/consumer/saleInvoices/${saleInvoiceId}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const CONSUMER_SALE_INVOICES_ROUTES: Routes = [
|
||||||
|
consumerSaleInvoicesNamedRoutes.saleInvoices,
|
||||||
|
consumerSaleInvoicesNamedRoutes.saleInvoice,
|
||||||
|
];
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export * from './io';
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
import ISummary from '@/core/models/summary';
|
||||||
|
|
||||||
|
export interface IConsumerSaleInvoicesRawResponse {
|
||||||
|
id: string;
|
||||||
|
code: string;
|
||||||
|
invoice_date: string;
|
||||||
|
notes?: string;
|
||||||
|
total_amount: string;
|
||||||
|
pos: Pos;
|
||||||
|
account: ConsumerAccount;
|
||||||
|
created_at: string;
|
||||||
|
items_count: number;
|
||||||
|
payments: Payments[];
|
||||||
|
}
|
||||||
|
export interface IConsumerSaleInvoicesResponse extends IConsumerSaleInvoicesRawResponse {}
|
||||||
|
|
||||||
|
interface ConsumerAccount {
|
||||||
|
role: string;
|
||||||
|
user: User;
|
||||||
|
account: Account;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Account {
|
||||||
|
username: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface User {
|
||||||
|
first_name: string;
|
||||||
|
last_name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Pos extends ISummary {
|
||||||
|
complex: Complex;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Complex extends ISummary {
|
||||||
|
business_activity: ISummary;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Payments {
|
||||||
|
amount: string;
|
||||||
|
paid_at: string;
|
||||||
|
payment_method: string;
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import { IPaginatedResponse } from '@/core/models/service.model';
|
||||||
|
import { HttpClient } from '@angular/common/http';
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { CONSUMER_SALE_INVOICES_API_ROUTES } from '../constants';
|
||||||
|
import { IConsumerSaleInvoicesRawResponse, IConsumerSaleInvoicesResponse } from '../models';
|
||||||
|
|
||||||
|
@Injectable({ providedIn: 'root' })
|
||||||
|
export class ConsumerSaleInvoicesService {
|
||||||
|
constructor(private http: HttpClient) {}
|
||||||
|
|
||||||
|
private apiRoutes = CONSUMER_SALE_INVOICES_API_ROUTES;
|
||||||
|
|
||||||
|
getAll(): Observable<IPaginatedResponse<IConsumerSaleInvoicesResponse>> {
|
||||||
|
return this.http.get<IPaginatedResponse<IConsumerSaleInvoicesRawResponse>>(
|
||||||
|
this.apiRoutes.list(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
getSingle(invoiceId: string): Observable<IConsumerSaleInvoicesResponse> {
|
||||||
|
return this.http.get<IConsumerSaleInvoicesRawResponse>(this.apiRoutes.single(invoiceId));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
import { EntityState, EntityStore } from '@/core/state';
|
||||||
|
import { computed, inject, Injectable } from '@angular/core';
|
||||||
|
import { MenuItem } from 'primeng/api';
|
||||||
|
import { catchError, finalize } from 'rxjs';
|
||||||
|
import { consumerSaleInvoicesNamedRoutes } from '../constants';
|
||||||
|
import { IConsumerSaleInvoicesResponse } from '../models';
|
||||||
|
import { ConsumerSaleInvoicesService } from '../services/main.service';
|
||||||
|
|
||||||
|
interface ConsumerSaleInvoiceState extends EntityState<IConsumerSaleInvoicesResponse> {
|
||||||
|
breadcrumbItems: MenuItem[];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root',
|
||||||
|
})
|
||||||
|
export class ConsumerSaleInvoiceStore extends EntityStore<
|
||||||
|
IConsumerSaleInvoicesResponse,
|
||||||
|
ConsumerSaleInvoiceState
|
||||||
|
> {
|
||||||
|
private readonly service = inject(ConsumerSaleInvoicesService);
|
||||||
|
constructor() {
|
||||||
|
super({
|
||||||
|
loading: false,
|
||||||
|
error: null,
|
||||||
|
entity: null,
|
||||||
|
initialized: false,
|
||||||
|
isRefreshing: false,
|
||||||
|
breadcrumbItems: [],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
breadcrumbItems = computed(() => this._state().breadcrumbItems);
|
||||||
|
|
||||||
|
private setBreadcrumb(invoiceId: string) {
|
||||||
|
this.patchState({
|
||||||
|
breadcrumbItems: [
|
||||||
|
{
|
||||||
|
...consumerSaleInvoicesNamedRoutes.saleInvoices.meta,
|
||||||
|
routerLink: consumerSaleInvoicesNamedRoutes.saleInvoices.meta.pagePath!(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: this.entity()?.code,
|
||||||
|
routerLink: consumerSaleInvoicesNamedRoutes.saleInvoice.meta.pagePath!(invoiceId),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getData(invoiceId: string) {
|
||||||
|
this.patchState({ loading: true });
|
||||||
|
this.service
|
||||||
|
.getSingle(invoiceId)
|
||||||
|
.pipe(
|
||||||
|
finalize(() => {
|
||||||
|
this.patchState({ loading: false });
|
||||||
|
}),
|
||||||
|
catchError((error) => {
|
||||||
|
this.setError(error);
|
||||||
|
throw error;
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.subscribe((entity) => {
|
||||||
|
this.patchState({ entity });
|
||||||
|
this.setBreadcrumb(invoiceId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
override reset(): void {
|
||||||
|
this.setState({
|
||||||
|
loading: false,
|
||||||
|
error: null,
|
||||||
|
entity: null,
|
||||||
|
initialized: false,
|
||||||
|
isRefreshing: false,
|
||||||
|
breadcrumbItems: [],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
export * from './list.component';
|
||||||
|
export * from './single.component';
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<consumer-saleInvoice-list />
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
// import { CatalogRoleTagComponent } from '@/shared/catalog/roles';
|
||||||
|
import { Component } from '@angular/core';
|
||||||
|
import { ConsumerSaleInvoiceListComponent } from '../components/list.component';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'consumer-saleInvoices',
|
||||||
|
templateUrl: './list.component.html',
|
||||||
|
imports: [ConsumerSaleInvoiceListComponent],
|
||||||
|
})
|
||||||
|
export class ConsumerSaleInvoicesComponent {}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<consumer-saleInvoice-shared [loading]="loading()" [invoice]="invoice" />
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
import { BreadcrumbService } from '@/core/services';
|
||||||
|
import { ConsumerSaleInvoiceSharedComponent } from '@/domains/consumer/components/invoices/single.component';
|
||||||
|
import pageParamsUtils from '@/utils/page-params.utils';
|
||||||
|
import { Component, computed, effect, inject, signal } from '@angular/core';
|
||||||
|
import { ActivatedRoute } from '@angular/router';
|
||||||
|
import { ConsumerSaleInvoiceStore } from '../store/main.store';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'consumer-saleInvoice',
|
||||||
|
templateUrl: './single.component.html',
|
||||||
|
imports: [ConsumerSaleInvoiceSharedComponent],
|
||||||
|
})
|
||||||
|
export class ConsumerSaleInvoiceComponent {
|
||||||
|
private readonly route = inject(ActivatedRoute);
|
||||||
|
private readonly breadcrumbService = inject(BreadcrumbService);
|
||||||
|
private readonly store = inject(ConsumerSaleInvoiceStore);
|
||||||
|
|
||||||
|
pageParams = computed(() => pageParamsUtils(this.route));
|
||||||
|
invoiceId = signal<string>(this.pageParams()['invoiceId']);
|
||||||
|
editMode = signal<boolean>(false);
|
||||||
|
|
||||||
|
readonly invoice = computed(() => this.store.entity());
|
||||||
|
readonly loading = computed(() => this.store.loading());
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
effect(() => {
|
||||||
|
if (this.invoice()?.id) {
|
||||||
|
this.setBreadcrumb();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.getData();
|
||||||
|
}
|
||||||
|
|
||||||
|
getData() {
|
||||||
|
this.store.getData(this.invoiceId());
|
||||||
|
}
|
||||||
|
|
||||||
|
setBreadcrumb() {
|
||||||
|
this.breadcrumbService.setItems([...this.store.breadcrumbItems()]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ import { Route } from '@angular/router';
|
|||||||
import { CONSUMER_ACCOUNTS_ROUTES } from './modules/accounts/constants';
|
import { CONSUMER_ACCOUNTS_ROUTES } from './modules/accounts/constants';
|
||||||
import { CONSUMER_BUSINESS_ACTIVITIES_ROUTES } from './modules/businessActivities/constants';
|
import { CONSUMER_BUSINESS_ACTIVITIES_ROUTES } from './modules/businessActivities/constants';
|
||||||
import { CONSUMER_CUSTOMERS_ROUTES } from './modules/customers/constants';
|
import { CONSUMER_CUSTOMERS_ROUTES } from './modules/customers/constants';
|
||||||
|
import { CONSUMER_SALE_INVOICES_ROUTES } from './modules/saleInvoices/constants';
|
||||||
|
|
||||||
export const CONSUMER_ROUTES = {
|
export const CONSUMER_ROUTES = {
|
||||||
path: 'consumer',
|
path: 'consumer',
|
||||||
@@ -15,5 +16,6 @@ export const CONSUMER_ROUTES = {
|
|||||||
...CONSUMER_ACCOUNTS_ROUTES,
|
...CONSUMER_ACCOUNTS_ROUTES,
|
||||||
...CONSUMER_BUSINESS_ACTIVITIES_ROUTES,
|
...CONSUMER_BUSINESS_ACTIVITIES_ROUTES,
|
||||||
...CONSUMER_CUSTOMERS_ROUTES,
|
...CONSUMER_CUSTOMERS_ROUTES,
|
||||||
|
...CONSUMER_SALE_INVOICES_ROUTES,
|
||||||
],
|
],
|
||||||
} as Route;
|
} as Route;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { EntityState, EntityStore } from '@/core/state';
|
import { EntityState, EntityStore } from '@/core/state';
|
||||||
import { LayoutService } from '@/layout/service/layout.service';
|
import { LayoutService } from '@/layout/service/layout.service';
|
||||||
import { inject, Injectable } from '@angular/core';
|
import { inject, Injectable } from '@angular/core';
|
||||||
import { catchError, finalize, throwError } from 'rxjs';
|
import { catchError, finalize } from 'rxjs';
|
||||||
import { IConsumerInfoResponse } from '../models';
|
import { IConsumerInfoResponse } from '../models';
|
||||||
import { ConsumerService } from '../services/main.service';
|
import { ConsumerService } from '../services/main.service';
|
||||||
|
|
||||||
@@ -32,11 +32,9 @@ export class ConsumerStore extends EntityStore<IConsumerInfoResponse, ConsumerSt
|
|||||||
finalize(() => {
|
finalize(() => {
|
||||||
this.patchState({ loading: false });
|
this.patchState({ loading: false });
|
||||||
}),
|
}),
|
||||||
catchError(() => {
|
catchError((error) => {
|
||||||
this.patchState({
|
this.setError(error);
|
||||||
error: '',
|
throw error;
|
||||||
});
|
|
||||||
return throwError('');
|
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.subscribe((entity) => {
|
.subscribe((entity) => {
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
@if (loading()) {
|
||||||
|
<shared-page-loading />
|
||||||
|
} @else if (items()) {
|
||||||
|
<div class="h-full w-full max-w-6xl mx-auto flex flex-col items-center justify-center gap-10">
|
||||||
|
<p-message severity="warn"> برای ادامه میبایست یکی از پایانههای زیر را انتخاب کنید. </p-message>
|
||||||
|
<div class="grid grid-cols-2 gap-10 items-stretch w-full">
|
||||||
|
@for (item of items(); track $index) {
|
||||||
|
<p-card
|
||||||
|
class="border border-surface-border bg-surface-card rounded-2xl cursor-pointer hover:bg-surface-50! transition-colors"
|
||||||
|
(click)="selectPos(item)"
|
||||||
|
>
|
||||||
|
<div class="flex flex-col gap-2 items-center justify-between shrink-0">
|
||||||
|
<i class="pi pi-select text-6xl! mb-3 text-surface-card" aria-hidden="true"></i>
|
||||||
|
<span class="text-xl font-semibold mb-2 block"> {{ item.name }} </span>
|
||||||
|
<span class="inline-block text-base">
|
||||||
|
{{ item.complex.business_activity.name }} - {{ item.complex.name }}
|
||||||
|
</span>
|
||||||
|
<button pButton class="w-full max-w-xs mx-auto mt-4">انتخاب پایانه</button>
|
||||||
|
</div>
|
||||||
|
</p-card>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
import { Maybe } from '@/core';
|
||||||
|
import { PageLoadingComponent } from '@/shared/components/page-loading.component';
|
||||||
|
import { HttpErrorResponse } from '@angular/common/http';
|
||||||
|
import { Component, EventEmitter, inject, Output, signal } from '@angular/core';
|
||||||
|
import { CookieService } from 'ngx-cookie-service';
|
||||||
|
import { ButtonDirective } from 'primeng/button';
|
||||||
|
import { Card } from 'primeng/card';
|
||||||
|
import { Message } from 'primeng/message';
|
||||||
|
import { catchError, finalize } from 'rxjs';
|
||||||
|
import { COOKIE_KEYS } from 'src/assets/constants';
|
||||||
|
import { IPosAccessibleResponse } from '../models/pos.io';
|
||||||
|
import { PosService } from '../modules/landing/services/main.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'pos-choose-cards',
|
||||||
|
templateUrl: './choose-pos.component.html',
|
||||||
|
imports: [PageLoadingComponent, Card, ButtonDirective, Message],
|
||||||
|
})
|
||||||
|
export class PosChooseCardsComponent {
|
||||||
|
@Output() onChoose = new EventEmitter();
|
||||||
|
|
||||||
|
private readonly service = inject(PosService);
|
||||||
|
private readonly cookieService = inject(CookieService);
|
||||||
|
|
||||||
|
loading = signal(true);
|
||||||
|
items = signal<IPosAccessibleResponse[]>([]);
|
||||||
|
error = signal<Maybe<HttpErrorResponse>>(null);
|
||||||
|
|
||||||
|
getData() {
|
||||||
|
this.loading.set(true);
|
||||||
|
this.service
|
||||||
|
.getAccessible()
|
||||||
|
.pipe(
|
||||||
|
finalize(() => this.loading.set(false)),
|
||||||
|
catchError((err) => {
|
||||||
|
this.error.set(err);
|
||||||
|
throw err;
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.subscribe((res) => {
|
||||||
|
this.items.set(res?.data || []);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.getData();
|
||||||
|
}
|
||||||
|
|
||||||
|
selectPos(pos: IPosAccessibleResponse) {
|
||||||
|
this.cookieService.set(COOKIE_KEYS.POS_ID, pos.id, {
|
||||||
|
sameSite: 'Lax', // or 'Strict' for same-site requests only
|
||||||
|
secure: false,
|
||||||
|
path: '/',
|
||||||
|
domain: 'localhost',
|
||||||
|
});
|
||||||
|
|
||||||
|
this.onChoose.emit();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,17 +7,42 @@
|
|||||||
<div class="w-10 h-10">
|
<div class="w-10 h-10">
|
||||||
<img [src]="placeholderLogo" alt="Logo" class="w-full h-full object-cover rounded-md bg-surface-card" />
|
<img [src]="placeholderLogo" alt="Logo" class="w-full h-full object-cover rounded-md bg-surface-card" />
|
||||||
</div>
|
</div>
|
||||||
<span class="text-lg font-bold">{{ posInfo()?.name }} - فروشگاه {{ posInfo()?.complex?.name }}</span>
|
@if (posInfo()) {
|
||||||
|
<span class="text-lg font-bold">{{ posInfo()?.name }} - فروشگاه {{ posInfo()?.complex?.name }}</span>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
<div class="flex gap-2 items-center">
|
<div class="flex gap-2 items-center">
|
||||||
<div class="bg-surface-card py-1 px-3 rounded-md shadow-sm">
|
<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>
|
<span [jalaliDate]="now" jalaliFormat="dddd YYYY/MM/DD" class="text-base"></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="bg-surface-card py-1 px-3 rounded-md shadow-sm">
|
<div class="">
|
||||||
<span class="text-base"> {{ userInfo()?.username }} </span>
|
<p-menu #menu [model]="profileMenuItems" [popup]="true" />
|
||||||
|
<button pButton (click)="menu.toggle($event)" icon="pi pi-user" severity="contrast">
|
||||||
|
{{ userInfo()?.username }}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<router-outlet></router-outlet>
|
@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 {
|
||||||
|
<router-outlet></router-outlet>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,13 +3,26 @@ import { PageLoadingComponent } from '@/shared/components/page-loading.component
|
|||||||
import { JalaliDateDirective } from '@/shared/directives';
|
import { JalaliDateDirective } from '@/shared/directives';
|
||||||
import { Component, computed, inject } from '@angular/core';
|
import { Component, computed, inject } from '@angular/core';
|
||||||
import { RouterOutlet } from '@angular/router';
|
import { RouterOutlet } from '@angular/router';
|
||||||
|
import { MenuItem } from 'primeng/api';
|
||||||
|
import { ButtonDirective } from 'primeng/button';
|
||||||
|
import { Card } from 'primeng/card';
|
||||||
|
import { Menu } from 'primeng/menu';
|
||||||
import images from 'src/assets/images';
|
import images from 'src/assets/images';
|
||||||
import { PosStore } from '../pos.store';
|
import { PosStore } from '../pos.store';
|
||||||
|
import { PosChooseCardsComponent } from './choose-pos.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'pos-layout',
|
selector: 'pos-layout',
|
||||||
templateUrl: './layout.component.html',
|
templateUrl: './layout.component.html',
|
||||||
imports: [PageLoadingComponent, RouterOutlet, JalaliDateDirective],
|
imports: [
|
||||||
|
PageLoadingComponent,
|
||||||
|
RouterOutlet,
|
||||||
|
JalaliDateDirective,
|
||||||
|
Menu,
|
||||||
|
ButtonDirective,
|
||||||
|
Card,
|
||||||
|
PosChooseCardsComponent,
|
||||||
|
],
|
||||||
})
|
})
|
||||||
export class PosLayoutComponent {
|
export class PosLayoutComponent {
|
||||||
constructor() {}
|
constructor() {}
|
||||||
@@ -19,8 +32,26 @@ export class PosLayoutComponent {
|
|||||||
|
|
||||||
readonly loading = computed(() => this.store.loading());
|
readonly loading = computed(() => this.store.loading());
|
||||||
readonly posInfo = computed(() => this.store.entity());
|
readonly posInfo = computed(() => this.store.entity());
|
||||||
|
readonly error = computed(() => this.store.error());
|
||||||
readonly userInfo = computed(() => this.authService.currentAccount());
|
readonly userInfo = computed(() => this.authService.currentAccount());
|
||||||
|
|
||||||
|
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;
|
placeholderLogo = images.placeholders.logo;
|
||||||
|
|
||||||
now = new Date();
|
now = new Date();
|
||||||
@@ -29,6 +60,10 @@ export class PosLayoutComponent {
|
|||||||
this.store.getData().subscribe();
|
this.store.getData().subscribe();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onChoosePos() {
|
||||||
|
this.getData();
|
||||||
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.getData();
|
this.getData();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import ISummary from '@/core/models/summary';
|
||||||
|
|
||||||
export interface IPosInfoRawResponse {
|
export interface IPosInfoRawResponse {
|
||||||
name: true;
|
name: true;
|
||||||
complex: {
|
complex: {
|
||||||
@@ -16,3 +18,12 @@ export interface IPosInfoRawResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface IPosInfoResponse extends IPosInfoRawResponse {}
|
export interface IPosInfoResponse extends IPosInfoRawResponse {}
|
||||||
|
|
||||||
|
export interface IPosAccessibleRawResponse extends ISummary {
|
||||||
|
complex: Complex;
|
||||||
|
}
|
||||||
|
export interface IPosAccessibleResponse extends IPosAccessibleRawResponse {}
|
||||||
|
|
||||||
|
interface Complex extends ISummary {
|
||||||
|
business_activity: ISummary;
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ const baseUrl = '/api/v1/pos';
|
|||||||
|
|
||||||
export const POS_API_ROUTES = {
|
export const POS_API_ROUTES = {
|
||||||
info: () => `${baseUrl}`,
|
info: () => `${baseUrl}`,
|
||||||
|
accessible: () => `${baseUrl}/accessible`,
|
||||||
goods: () => `${baseUrl}/goods`,
|
goods: () => `${baseUrl}/goods`,
|
||||||
goodCategories: () => `${baseUrl}/good_categories`,
|
goodCategories: () => `${baseUrl}/good_categories`,
|
||||||
submitOrder: () => `${baseUrl}/sales_invoices`,
|
submitOrder: () => `${baseUrl}/sales_invoices`,
|
||||||
|
|||||||
@@ -5,7 +5,12 @@ import {
|
|||||||
IGoodRawResponse,
|
IGoodRawResponse,
|
||||||
IGoodResponse,
|
IGoodResponse,
|
||||||
} from '@/domains/pos/models/good.io';
|
} from '@/domains/pos/models/good.io';
|
||||||
import { IPosInfoRawResponse, IPosInfoResponse } from '@/domains/pos/models/pos.io';
|
import {
|
||||||
|
IPosAccessibleRawResponse,
|
||||||
|
IPosAccessibleResponse,
|
||||||
|
IPosInfoRawResponse,
|
||||||
|
IPosInfoResponse,
|
||||||
|
} from '@/domains/pos/models/pos.io';
|
||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
@@ -21,6 +26,11 @@ export class PosService {
|
|||||||
getInfo(): Observable<IPosInfoResponse> {
|
getInfo(): Observable<IPosInfoResponse> {
|
||||||
return this.http.get<IPosInfoRawResponse>(this.apiRoutes.info());
|
return this.http.get<IPosInfoRawResponse>(this.apiRoutes.info());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getAccessible(): Observable<IListingResponse<IPosAccessibleResponse>> {
|
||||||
|
return this.http.get<IListingResponse<IPosAccessibleRawResponse>>(this.apiRoutes.accessible());
|
||||||
|
}
|
||||||
|
|
||||||
getGoods(searchQuery: string): Observable<IListingResponse<IGoodResponse>> {
|
getGoods(searchQuery: string): Observable<IListingResponse<IGoodResponse>> {
|
||||||
return this.http.get<IListingResponse<IGoodRawResponse>>(this.apiRoutes.goods());
|
return this.http.get<IListingResponse<IGoodRawResponse>>(this.apiRoutes.goods());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
<div class="flex gap-4 grow overflow-hidden h-full">
|
<div class="flex gap-4 grow overflow-hidden h-full">
|
||||||
<div class="grow h-full overflow-auto">
|
@if (posInfo()) {
|
||||||
<pos-goods />
|
<div class="grow h-full overflow-auto">
|
||||||
</div>
|
<pos-goods />
|
||||||
<div class="shrink-0 h-full">
|
</div>
|
||||||
<pos-order-section />
|
<div class="shrink-0 h-full">
|
||||||
</div>
|
<pos-order-section />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
// import { CatalogRoleTagComponent } from '@/shared/catalog/roles';
|
// import { CatalogRoleTagComponent } from '@/shared/catalog/roles';
|
||||||
import { Component } from '@angular/core';
|
import { PosStore } from '@/domains/pos/pos.store';
|
||||||
|
import { Component, computed, inject } from '@angular/core';
|
||||||
import { PosGoodsComponent } from '../components/goods.component';
|
import { PosGoodsComponent } from '../components/goods.component';
|
||||||
import { PosOrderSectionComponent } from '../components/order/order-section.component';
|
import { PosOrderSectionComponent } from '../components/order/order-section.component';
|
||||||
|
|
||||||
@@ -10,4 +11,8 @@ import { PosOrderSectionComponent } from '../components/order/order-section.comp
|
|||||||
|
|
||||||
imports: [PosGoodsComponent, PosOrderSectionComponent],
|
imports: [PosGoodsComponent, PosOrderSectionComponent],
|
||||||
})
|
})
|
||||||
export class PosLandingComponent {}
|
export class PosLandingComponent {
|
||||||
|
private readonly posStore = inject(PosStore);
|
||||||
|
|
||||||
|
readonly posInfo = computed(() => this.posStore.entity());
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
import { EntityState, EntityStore } from '@/core/state';
|
import { defaultBaseStateData, EntityState, EntityStore } from '@/core/state';
|
||||||
|
import { HttpErrorResponse } from '@angular/common/http';
|
||||||
import { computed, inject, Injectable } from '@angular/core';
|
import { computed, inject, Injectable } from '@angular/core';
|
||||||
import { CookieService } from 'ngx-cookie-service';
|
import { CookieService } from 'ngx-cookie-service';
|
||||||
import { finalize, map } from 'rxjs';
|
import { catchError, finalize, map } from 'rxjs';
|
||||||
|
import { COOKIE_KEYS } from 'src/assets/constants';
|
||||||
import { IPosInfoResponse } from './models/pos.io';
|
import { IPosInfoResponse } from './models/pos.io';
|
||||||
import { PosService } from './modules/landing/services/main.service';
|
import { PosService } from './modules/landing/services/main.service';
|
||||||
|
|
||||||
@@ -17,12 +19,8 @@ export class PosStore extends EntityStore<IPosInfoResponse, PosState> {
|
|||||||
|
|
||||||
constructor(private readonly cookieService: CookieService) {
|
constructor(private readonly cookieService: CookieService) {
|
||||||
super({
|
super({
|
||||||
loading: false,
|
...defaultBaseStateData,
|
||||||
error: null,
|
posId: cookieService.get(COOKIE_KEYS.POS_ID),
|
||||||
entity: null,
|
|
||||||
initialized: false,
|
|
||||||
isRefreshing: false,
|
|
||||||
posId: cookieService.get('posId'),
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,9 +33,15 @@ export class PosStore extends EntityStore<IPosInfoResponse, PosState> {
|
|||||||
this.patchState({ loading: false });
|
this.patchState({ loading: false });
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
catchError((err: HttpErrorResponse) => {
|
||||||
|
this.setError(err);
|
||||||
|
// if (err.status === 403) debugger;
|
||||||
|
throw err;
|
||||||
|
}),
|
||||||
|
|
||||||
map((entity: IPosInfoResponse) => {
|
map((entity: IPosInfoResponse) => {
|
||||||
if (entity) {
|
if (entity) {
|
||||||
this.patchState({ entity: entity });
|
this.setEntity(entity);
|
||||||
}
|
}
|
||||||
return entity;
|
return entity;
|
||||||
}),
|
}),
|
||||||
@@ -46,12 +50,8 @@ export class PosStore extends EntityStore<IPosInfoResponse, PosState> {
|
|||||||
|
|
||||||
override reset(): void {
|
override reset(): void {
|
||||||
this.setState({
|
this.setState({
|
||||||
loading: false,
|
...defaultBaseStateData,
|
||||||
error: null,
|
posId: this.cookieService.get(COOKIE_KEYS.POS_ID),
|
||||||
entity: null,
|
|
||||||
initialized: false,
|
|
||||||
isRefreshing: false,
|
|
||||||
posId: this.cookieService.get('posId'),
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -14,7 +14,7 @@
|
|||||||
hint="مدت زمان لایسنسها ۱ ساله هستند."
|
hint="مدت زمان لایسنسها ۱ ساله هستند."
|
||||||
/>
|
/>
|
||||||
<!-- <uikit-datepicker label="تاریخ انقضای لایسنس" [control]="form.controls.expires_at" name="expires_at" /> -->
|
<!-- <uikit-datepicker label="تاریخ انقضای لایسنس" [control]="form.controls.expires_at" name="expires_at" /> -->
|
||||||
<app-partner-select label="شریک تجاری" [control]="form.controls.partner_id" />
|
<app-partner-select label="شریک تجاری" [control]="form.controls.partner_id" [showClear]="true" />
|
||||||
<app-form-footer-actions [submitLabel]="'ذخیره'" [loading]="submitLoading()" (onCancel)="close()" />
|
<app-form-footer-actions [submitLabel]="'ذخیره'" [loading]="submitLoading()" (onCancel)="close()" />
|
||||||
</form>
|
</form>
|
||||||
</p-dialog>
|
</p-dialog>
|
||||||
|
|||||||
@@ -16,12 +16,13 @@ export class SuperAdminConsumerPosLayoutComponent {
|
|||||||
readonly loading = computed(() => this.store.loading());
|
readonly loading = computed(() => this.store.loading());
|
||||||
readonly pageParams = computed(() => pageParamsUtils(this.route));
|
readonly pageParams = computed(() => pageParamsUtils(this.route));
|
||||||
|
|
||||||
|
readonly consumerId = computed(() => this.pageParams()['consumerId']!);
|
||||||
readonly businessId = computed(() => this.pageParams()['businessActivityId']!);
|
readonly businessId = computed(() => this.pageParams()['businessActivityId']!);
|
||||||
readonly complexId = computed(() => this.pageParams()['complexId']!);
|
readonly complexId = computed(() => this.pageParams()['complexId']!);
|
||||||
readonly posId = computed(() => this.pageParams()['posId']!);
|
readonly posId = computed(() => this.pageParams()['posId']!);
|
||||||
|
|
||||||
getData() {
|
getData() {
|
||||||
this.store.getData(this.businessId(), this.complexId(), this.posId());
|
this.store.getData(this.consumerId(), this.businessId(), this.complexId(), this.posId());
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
import { EntityState, EntityStore } from '@/core/state';
|
import { EntityState, EntityStore } from '@/core/state';
|
||||||
import { inject, Injectable } from '@angular/core';
|
import { computed, inject, Injectable } from '@angular/core';
|
||||||
import { catchError, finalize, throwError } from 'rxjs';
|
import { MenuItem } from 'primeng/api';
|
||||||
|
import { catchError, finalize } from 'rxjs';
|
||||||
|
import { superAdminConsumerBusinessActivitiesNamedRoutes } from '../constants/routes/businessActivities';
|
||||||
import { IBusinessActivityResponse } from '../models';
|
import { IBusinessActivityResponse } from '../models';
|
||||||
import { AdminConsumerBusinessActivitiesService } from '../services/businessActivities.service';
|
import { AdminConsumerBusinessActivitiesService } from '../services/businessActivities.service';
|
||||||
|
|
||||||
interface BusinessActivityState extends EntityState<IBusinessActivityResponse> {}
|
interface BusinessActivityState extends EntityState<IBusinessActivityResponse> {
|
||||||
|
breadcrumbItems: MenuItem[];
|
||||||
|
}
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
@@ -21,26 +25,47 @@ export class BusinessActivityStore extends EntityStore<
|
|||||||
entity: null,
|
entity: null,
|
||||||
initialized: false,
|
initialized: false,
|
||||||
isRefreshing: false,
|
isRefreshing: false,
|
||||||
|
breadcrumbItems: [],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getData(consumerId: string, business_id: string) {
|
breadcrumbItems = computed(() => this._state().breadcrumbItems);
|
||||||
|
|
||||||
|
private setBreadcrumb(consumerId: string, businessId: string) {
|
||||||
|
this.patchState({
|
||||||
|
breadcrumbItems: [
|
||||||
|
{
|
||||||
|
...superAdminConsumerBusinessActivitiesNamedRoutes.businessActivities.meta,
|
||||||
|
routerLink:
|
||||||
|
superAdminConsumerBusinessActivitiesNamedRoutes.businessActivities.meta.pagePath!(
|
||||||
|
consumerId,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: this.entity()?.name,
|
||||||
|
routerLink: superAdminConsumerBusinessActivitiesNamedRoutes.businessActivity.meta
|
||||||
|
.pagePath!(consumerId, businessId),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getData(consumerId: string, businessId: string) {
|
||||||
this.patchState({ loading: true });
|
this.patchState({ loading: true });
|
||||||
this.service
|
this.service
|
||||||
.getSingle(consumerId, business_id)
|
.getSingle(consumerId, businessId)
|
||||||
.pipe(
|
.pipe(
|
||||||
finalize(() => {
|
finalize(() => {
|
||||||
this.patchState({ loading: false });
|
this.patchState({ loading: false });
|
||||||
}),
|
}),
|
||||||
catchError(() => {
|
catchError((error) => {
|
||||||
this.patchState({
|
this.setError(error);
|
||||||
error: '',
|
throw error;
|
||||||
});
|
|
||||||
return throwError('');
|
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.subscribe((entity) => {
|
.subscribe((entity) => {
|
||||||
this.patchState({ entity });
|
this.patchState({ entity });
|
||||||
|
this.setBreadcrumb(consumerId, businessId);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,6 +76,7 @@ export class BusinessActivityStore extends EntityStore<
|
|||||||
entity: null,
|
entity: null,
|
||||||
initialized: false,
|
initialized: false,
|
||||||
isRefreshing: false,
|
isRefreshing: false,
|
||||||
|
breadcrumbItems: [],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
import { EntityState, EntityStore } from '@/core/state';
|
import { EntityState, EntityStore } from '@/core/state';
|
||||||
import { inject, Injectable } from '@angular/core';
|
import { computed, inject, Injectable } from '@angular/core';
|
||||||
import { catchError, finalize, throwError } from 'rxjs';
|
import { MenuItem } from 'primeng/api';
|
||||||
|
import { catchError, finalize } from 'rxjs';
|
||||||
|
import { superAdminConsumerComplexesNamedRoutes } from '../constants/routes/complexes';
|
||||||
import { IComplexResponse } from '../models';
|
import { IComplexResponse } from '../models';
|
||||||
import { AdminComplexesService } from '../services/complexes.service';
|
import { AdminComplexesService } from '../services/complexes.service';
|
||||||
|
|
||||||
interface ComplexState extends EntityState<IComplexResponse> {}
|
interface ComplexState extends EntityState<IComplexResponse> {
|
||||||
|
breadcrumbItems: MenuItem[];
|
||||||
|
}
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
@@ -18,6 +22,31 @@ export class ComplexStore extends EntityStore<IComplexResponse, ComplexState> {
|
|||||||
entity: null,
|
entity: null,
|
||||||
initialized: false,
|
initialized: false,
|
||||||
isRefreshing: false,
|
isRefreshing: false,
|
||||||
|
breadcrumbItems: [],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
breadcrumbItems = computed(() => this._state().breadcrumbItems);
|
||||||
|
|
||||||
|
private setBreadcrumb(consumerId: string, businessId: string, complexId: string) {
|
||||||
|
this.patchState({
|
||||||
|
breadcrumbItems: [
|
||||||
|
{
|
||||||
|
...superAdminConsumerComplexesNamedRoutes.complexes.meta,
|
||||||
|
routerLink: superAdminConsumerComplexesNamedRoutes.complexes.meta.pagePath!(
|
||||||
|
consumerId,
|
||||||
|
businessId,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: this.entity()?.name,
|
||||||
|
routerLink: superAdminConsumerComplexesNamedRoutes.complex.meta.pagePath!(
|
||||||
|
consumerId,
|
||||||
|
businessId,
|
||||||
|
complexId,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,15 +58,14 @@ export class ComplexStore extends EntityStore<IComplexResponse, ComplexState> {
|
|||||||
finalize(() => {
|
finalize(() => {
|
||||||
this.patchState({ loading: false });
|
this.patchState({ loading: false });
|
||||||
}),
|
}),
|
||||||
catchError(() => {
|
catchError((error) => {
|
||||||
this.patchState({
|
this.setError(error);
|
||||||
error: '',
|
throw error;
|
||||||
});
|
|
||||||
return throwError('');
|
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.subscribe((entity) => {
|
.subscribe((entity) => {
|
||||||
this.patchState({ entity });
|
this.patchState({ entity });
|
||||||
|
this.setBreadcrumb(consumerId, businessId, complexId);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,6 +76,7 @@ export class ComplexStore extends EntityStore<IComplexResponse, ComplexState> {
|
|||||||
entity: null,
|
entity: null,
|
||||||
initialized: false,
|
initialized: false,
|
||||||
isRefreshing: false,
|
isRefreshing: false,
|
||||||
|
breadcrumbItems: [],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
import { EntityState, EntityStore } from '@/core/state';
|
import { EntityState, EntityStore } from '@/core/state';
|
||||||
import { inject, Injectable } from '@angular/core';
|
import { computed, inject, Injectable } from '@angular/core';
|
||||||
import { catchError, finalize, throwError } from 'rxjs';
|
import { MenuItem } from 'primeng/api';
|
||||||
|
import { catchError, finalize } from 'rxjs';
|
||||||
|
import { superAdminConsumersNamedRoutes } from '../constants';
|
||||||
import { IConsumerResponse } from '../models';
|
import { IConsumerResponse } from '../models';
|
||||||
import { ConsumersService } from '../services/main.service';
|
import { ConsumersService } from '../services/main.service';
|
||||||
|
|
||||||
interface ConsumerState extends EntityState<IConsumerResponse> {}
|
interface ConsumerState extends EntityState<IConsumerResponse> {
|
||||||
|
breadcrumbItems: MenuItem[];
|
||||||
|
}
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
@@ -18,26 +22,43 @@ export class ConsumerStore extends EntityStore<IConsumerResponse, ConsumerState>
|
|||||||
entity: null,
|
entity: null,
|
||||||
initialized: false,
|
initialized: false,
|
||||||
isRefreshing: false,
|
isRefreshing: false,
|
||||||
|
breadcrumbItems: [],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getData(partnerId: string) {
|
breadcrumbItems = computed(() => this._state().breadcrumbItems);
|
||||||
|
|
||||||
|
private setBreadcrumb(consumerId: string) {
|
||||||
|
this.patchState({
|
||||||
|
breadcrumbItems: [
|
||||||
|
{
|
||||||
|
...superAdminConsumersNamedRoutes.consumers.meta,
|
||||||
|
routerLink: superAdminConsumersNamedRoutes.consumers.meta.pagePath!(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: this.entity()?.fullname,
|
||||||
|
routerLink: superAdminConsumersNamedRoutes.consumer.meta.pagePath!(consumerId),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getData(consumerId: string) {
|
||||||
this.patchState({ loading: true });
|
this.patchState({ loading: true });
|
||||||
this.service
|
this.service
|
||||||
.getSingle(partnerId)
|
.getSingle(consumerId)
|
||||||
.pipe(
|
.pipe(
|
||||||
finalize(() => {
|
finalize(() => {
|
||||||
this.patchState({ loading: false });
|
this.patchState({ loading: false });
|
||||||
}),
|
}),
|
||||||
catchError(() => {
|
catchError((error) => {
|
||||||
this.patchState({
|
this.setError(error);
|
||||||
error: '',
|
throw error;
|
||||||
});
|
|
||||||
return throwError('');
|
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.subscribe((entity) => {
|
.subscribe((entity) => {
|
||||||
this.patchState({ entity });
|
this.patchState({ entity });
|
||||||
|
this.setBreadcrumb(consumerId);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
import { EntityState, EntityStore } from '@/core/state';
|
import { EntityState, EntityStore } from '@/core/state';
|
||||||
import { inject, Injectable } from '@angular/core';
|
import { computed, inject, Injectable } from '@angular/core';
|
||||||
import { catchError, finalize, throwError } from 'rxjs';
|
import { MenuItem } from 'primeng/api';
|
||||||
|
import { catchError, finalize } from 'rxjs';
|
||||||
|
import { superAdminConsumerPosesNamedRoutes } from '../constants/routes/poses';
|
||||||
import { IPosResponse } from '../models';
|
import { IPosResponse } from '../models';
|
||||||
import { AdminPosesService } from '../services/poses.service';
|
import { AdminPosesService } from '../services/poses.service';
|
||||||
|
|
||||||
interface PosState extends EntityState<IPosResponse> {}
|
interface PosState extends EntityState<IPosResponse> {
|
||||||
|
breadcrumbItems: MenuItem[];
|
||||||
|
}
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
@@ -18,10 +22,38 @@ export class PosStore extends EntityStore<IPosResponse, PosState> {
|
|||||||
entity: null,
|
entity: null,
|
||||||
initialized: false,
|
initialized: false,
|
||||||
isRefreshing: false,
|
isRefreshing: false,
|
||||||
|
breadcrumbItems: [],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getData(businessId: string, complexId: string, posId: string) {
|
breadcrumbItems = computed(() => this._state().breadcrumbItems);
|
||||||
|
|
||||||
|
private setBreadcrumb(consumerId: string, businessId: string, complexId: string, posId: string) {
|
||||||
|
this.patchState({
|
||||||
|
breadcrumbItems: [
|
||||||
|
{
|
||||||
|
title: superAdminConsumerPosesNamedRoutes.poses.meta.title,
|
||||||
|
routerLink: superAdminConsumerPosesNamedRoutes.poses.meta.pagePath!(
|
||||||
|
consumerId,
|
||||||
|
businessId,
|
||||||
|
complexId,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
title: this.entity()?.name,
|
||||||
|
routerLink: superAdminConsumerPosesNamedRoutes.pos.meta.pagePath!(
|
||||||
|
consumerId,
|
||||||
|
businessId,
|
||||||
|
complexId,
|
||||||
|
posId,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getData(consumerId: string, businessId: string, complexId: string, posId: string) {
|
||||||
this.patchState({ loading: true });
|
this.patchState({ loading: true });
|
||||||
this.service
|
this.service
|
||||||
.getSingle(businessId, complexId, posId)
|
.getSingle(businessId, complexId, posId)
|
||||||
@@ -29,15 +61,14 @@ export class PosStore extends EntityStore<IPosResponse, PosState> {
|
|||||||
finalize(() => {
|
finalize(() => {
|
||||||
this.patchState({ loading: false });
|
this.patchState({ loading: false });
|
||||||
}),
|
}),
|
||||||
catchError(() => {
|
catchError((error) => {
|
||||||
this.patchState({
|
this.setError(error);
|
||||||
error: '',
|
throw error;
|
||||||
});
|
|
||||||
return throwError('');
|
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.subscribe((entity) => {
|
.subscribe((entity) => {
|
||||||
this.patchState({ entity });
|
this.patchState({ entity });
|
||||||
|
this.setBreadcrumb(consumerId, businessId, complexId, posId);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,6 +79,7 @@ export class PosStore extends EntityStore<IPosResponse, PosState> {
|
|||||||
entity: null,
|
entity: null,
|
||||||
initialized: false,
|
initialized: false,
|
||||||
isRefreshing: false,
|
isRefreshing: false,
|
||||||
|
breadcrumbItems: [],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import { BreadcrumbService } from '@/core/services';
|
|||||||
import { Component, inject, signal } from '@angular/core';
|
import { Component, inject, signal } from '@angular/core';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { ConsumerAccountListComponent } from '../../components/accounts/list.component';
|
import { ConsumerAccountListComponent } from '../../components/accounts/list.component';
|
||||||
import { superAdminConsumersNamedRoutes } from '../../constants';
|
|
||||||
import { superAdminConsumerAccountsNamedRoutes } from '../../constants/routes/accounts';
|
import { superAdminConsumerAccountsNamedRoutes } from '../../constants/routes/accounts';
|
||||||
import { ConsumerStore } from '../../store/consumer.store';
|
import { ConsumerStore } from '../../store/consumer.store';
|
||||||
|
|
||||||
@@ -25,14 +24,7 @@ export class ConsumerAccountsComponent {
|
|||||||
|
|
||||||
setBreadcrumb() {
|
setBreadcrumb() {
|
||||||
this.breadcrumbService.setItems([
|
this.breadcrumbService.setItems([
|
||||||
{
|
...this.store.breadcrumbItems(),
|
||||||
...superAdminConsumersNamedRoutes.consumers.meta,
|
|
||||||
routerLink: superAdminConsumersNamedRoutes.consumers.meta.pagePath!(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: this.store.entity()?.fullname,
|
|
||||||
routerLink: superAdminConsumersNamedRoutes.consumer.meta.pagePath!(this.consumerId()),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
title: superAdminConsumerAccountsNamedRoutes.accounts.meta.title,
|
title: superAdminConsumerAccountsNamedRoutes.accounts.meta.title,
|
||||||
},
|
},
|
||||||
|
|||||||
+1
-9
@@ -4,7 +4,6 @@ import pageParamsUtils from '@/utils/page-params.utils';
|
|||||||
import { Component, computed, inject, signal } from '@angular/core';
|
import { Component, computed, inject, signal } from '@angular/core';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { ConsumerBusinessActivitiesComponent } from '../../components/businessActivities/list.component';
|
import { ConsumerBusinessActivitiesComponent } from '../../components/businessActivities/list.component';
|
||||||
import { superAdminConsumersNamedRoutes } from '../../constants';
|
|
||||||
import { superAdminConsumerBusinessActivitiesNamedRoutes } from '../../constants/routes/businessActivities';
|
import { superAdminConsumerBusinessActivitiesNamedRoutes } from '../../constants/routes/businessActivities';
|
||||||
import { ConsumerStore } from '../../store/consumer.store';
|
import { ConsumerStore } from '../../store/consumer.store';
|
||||||
|
|
||||||
@@ -27,14 +26,7 @@ export class SuperAdminUserBusinessActivitiesComponent {
|
|||||||
|
|
||||||
setBreadcrumb() {
|
setBreadcrumb() {
|
||||||
this.breadcrumbService.setItems([
|
this.breadcrumbService.setItems([
|
||||||
{
|
...this.consumerStore.breadcrumbItems(),
|
||||||
...superAdminConsumersNamedRoutes.consumers.meta,
|
|
||||||
routerLink: superAdminConsumersNamedRoutes.consumers.meta.pagePath!(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: this.consumerStore.entity()?.fullname,
|
|
||||||
routerLink: superAdminConsumersNamedRoutes.consumer.meta.pagePath!(this.consumerId()),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
title: superAdminConsumerBusinessActivitiesNamedRoutes.businessActivities.meta.title,
|
title: superAdminConsumerBusinessActivitiesNamedRoutes.businessActivities.meta.title,
|
||||||
},
|
},
|
||||||
|
|||||||
+2
-22
@@ -6,8 +6,6 @@ import { ActivatedRoute } from '@angular/router';
|
|||||||
|
|
||||||
import { ConsumerBusinessActivitiesFormComponent } from '../../components/businessActivities/form.component';
|
import { ConsumerBusinessActivitiesFormComponent } from '../../components/businessActivities/form.component';
|
||||||
import { ConsumerComplexesComponent } from '../../components/complexes/list.component';
|
import { ConsumerComplexesComponent } from '../../components/complexes/list.component';
|
||||||
import { superAdminConsumersNamedRoutes } from '../../constants';
|
|
||||||
import { superAdminConsumerBusinessActivitiesNamedRoutes } from '../../constants/routes/businessActivities';
|
|
||||||
import { BusinessActivityStore } from '../../store/businessActivity.store';
|
import { BusinessActivityStore } from '../../store/businessActivity.store';
|
||||||
import { ConsumerStore } from '../../store/consumer.store';
|
import { ConsumerStore } from '../../store/consumer.store';
|
||||||
|
|
||||||
@@ -50,26 +48,8 @@ export class SuperAdminUserBusinessActivityComponent {
|
|||||||
|
|
||||||
setBreadcrumb() {
|
setBreadcrumb() {
|
||||||
this.breadcrumbService.setItems([
|
this.breadcrumbService.setItems([
|
||||||
{
|
...this.consumerStore.breadcrumbItems(),
|
||||||
...superAdminConsumersNamedRoutes.consumers.meta,
|
...this.store.breadcrumbItems(),
|
||||||
routerLink: superAdminConsumersNamedRoutes.consumers.meta.pagePath!(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: this.consumerStore.entity()?.fullname,
|
|
||||||
routerLink: superAdminConsumersNamedRoutes.consumers.meta.pagePath!(this.consumerId()),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
...superAdminConsumerBusinessActivitiesNamedRoutes.businessActivities.meta,
|
|
||||||
routerLink: superAdminConsumerBusinessActivitiesNamedRoutes.businessActivities.meta
|
|
||||||
.pagePath!(this.consumerId()),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: this.businessActivity()?.name,
|
|
||||||
routerLink: superAdminConsumerBusinessActivitiesNamedRoutes.businessActivity.meta.pagePath!(
|
|
||||||
this.consumerId(),
|
|
||||||
this.businessId(),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,8 +4,6 @@ import pageParamsUtils from '@/utils/page-params.utils';
|
|||||||
import { Component, computed, inject, signal } from '@angular/core';
|
import { Component, computed, inject, signal } from '@angular/core';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { ConsumerComplexesComponent } from '../../components/complexes/list.component';
|
import { ConsumerComplexesComponent } from '../../components/complexes/list.component';
|
||||||
import { superAdminConsumersNamedRoutes } from '../../constants';
|
|
||||||
import { superAdminConsumerBusinessActivitiesNamedRoutes } from '../../constants/routes/businessActivities';
|
|
||||||
import { superAdminConsumerComplexesNamedRoutes } from '../../constants/routes/complexes';
|
import { superAdminConsumerComplexesNamedRoutes } from '../../constants/routes/complexes';
|
||||||
import { BusinessActivityStore } from '../../store/businessActivity.store';
|
import { BusinessActivityStore } from '../../store/businessActivity.store';
|
||||||
import { ConsumerStore } from '../../store/consumer.store';
|
import { ConsumerStore } from '../../store/consumer.store';
|
||||||
@@ -31,26 +29,8 @@ export class SuperAdminUserComplexesComponent {
|
|||||||
|
|
||||||
setBreadcrumb() {
|
setBreadcrumb() {
|
||||||
this.breadcrumbService.setItems([
|
this.breadcrumbService.setItems([
|
||||||
{
|
...this.consumerStore.breadcrumbItems(),
|
||||||
...superAdminConsumersNamedRoutes.consumers.meta,
|
...this.businessStore.breadcrumbItems(),
|
||||||
routerLink: superAdminConsumersNamedRoutes.consumers.meta.pagePath!(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: this.consumerStore.entity()?.fullname,
|
|
||||||
routerLink: superAdminConsumersNamedRoutes.consumer.meta.pagePath!(this.consumerId()),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: superAdminConsumerBusinessActivitiesNamedRoutes.businessActivities.meta.title,
|
|
||||||
routerLink: superAdminConsumerBusinessActivitiesNamedRoutes.businessActivities.meta
|
|
||||||
.pagePath!(this.consumerId()),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: this.businessStore.entity()?.name,
|
|
||||||
routerLink: superAdminConsumerBusinessActivitiesNamedRoutes.businessActivity.meta.pagePath!(
|
|
||||||
this.consumerId(),
|
|
||||||
this.businessId(),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
title: superAdminConsumerComplexesNamedRoutes.complexes.meta.title,
|
title: superAdminConsumerComplexesNamedRoutes.complexes.meta.title,
|
||||||
routerLink: superAdminConsumerComplexesNamedRoutes.complexes.meta.pagePath!(
|
routerLink: superAdminConsumerComplexesNamedRoutes.complexes.meta.pagePath!(
|
||||||
|
|||||||
@@ -5,9 +5,6 @@ import { Component, computed, effect, inject, signal } from '@angular/core';
|
|||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { ConsumerComplexFormComponent } from '../../components/complexes/form.component';
|
import { ConsumerComplexFormComponent } from '../../components/complexes/form.component';
|
||||||
import { ConsumerPosesComponent } from '../../components/poses/list.component';
|
import { ConsumerPosesComponent } from '../../components/poses/list.component';
|
||||||
import { superAdminConsumersNamedRoutes } from '../../constants';
|
|
||||||
import { superAdminConsumerBusinessActivitiesNamedRoutes } from '../../constants/routes/businessActivities';
|
|
||||||
import { superAdminConsumerComplexesNamedRoutes } from '../../constants/routes/complexes';
|
|
||||||
import { BusinessActivityStore } from '../../store/businessActivity.store';
|
import { BusinessActivityStore } from '../../store/businessActivity.store';
|
||||||
import { ComplexStore } from '../../store/complex.store';
|
import { ComplexStore } from '../../store/complex.store';
|
||||||
import { ConsumerStore } from '../../store/consumer.store';
|
import { ConsumerStore } from '../../store/consumer.store';
|
||||||
@@ -54,41 +51,9 @@ export class SuperAdminUserComplexComponent {
|
|||||||
|
|
||||||
setBreadcrumb() {
|
setBreadcrumb() {
|
||||||
this.breadcrumbService.setItems([
|
this.breadcrumbService.setItems([
|
||||||
{
|
...this.consumerStore.breadcrumbItems(),
|
||||||
...superAdminConsumersNamedRoutes.consumers.meta,
|
...this.businessStore.breadcrumbItems(),
|
||||||
routerLink: superAdminConsumersNamedRoutes.consumers.meta.pagePath!(),
|
...this.store.breadcrumbItems(),
|
||||||
},
|
|
||||||
{
|
|
||||||
title: this.consumerStore.entity()?.fullname,
|
|
||||||
routerLink: superAdminConsumersNamedRoutes.consumer.meta.pagePath!(this.consumerId()),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
...superAdminConsumerBusinessActivitiesNamedRoutes.businessActivities.meta,
|
|
||||||
routerLink: superAdminConsumerBusinessActivitiesNamedRoutes.businessActivities.meta
|
|
||||||
.pagePath!(this.consumerId()),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: this.businessStore.entity()?.name,
|
|
||||||
routerLink: superAdminConsumerBusinessActivitiesNamedRoutes.businessActivity.meta.pagePath!(
|
|
||||||
this.consumerId(),
|
|
||||||
this.businessId(),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
...superAdminConsumerComplexesNamedRoutes.complexes.meta,
|
|
||||||
routerLink: superAdminConsumerComplexesNamedRoutes.complexes.meta.pagePath!(
|
|
||||||
this.consumerId(),
|
|
||||||
this.businessId(),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: this.complex()?.name,
|
|
||||||
routerLink: superAdminConsumerComplexesNamedRoutes.complex.meta.pagePath!(
|
|
||||||
this.consumerId(),
|
|
||||||
this.businessId(),
|
|
||||||
this.complexId(),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,9 +4,6 @@ import pageParamsUtils from '@/utils/page-params.utils';
|
|||||||
import { Component, computed, inject, signal } from '@angular/core';
|
import { Component, computed, inject, signal } from '@angular/core';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { ConsumerPosesComponent } from '../../components/poses/list.component';
|
import { ConsumerPosesComponent } from '../../components/poses/list.component';
|
||||||
import { superAdminConsumersNamedRoutes } from '../../constants';
|
|
||||||
import { superAdminConsumerBusinessActivitiesNamedRoutes } from '../../constants/routes/businessActivities';
|
|
||||||
import { superAdminConsumerComplexesNamedRoutes } from '../../constants/routes/complexes';
|
|
||||||
import { superAdminConsumerPosesNamedRoutes } from '../../constants/routes/poses';
|
import { superAdminConsumerPosesNamedRoutes } from '../../constants/routes/poses';
|
||||||
import { BusinessActivityStore } from '../../store/businessActivity.store';
|
import { BusinessActivityStore } from '../../store/businessActivity.store';
|
||||||
import { ComplexStore } from '../../store/complex.store';
|
import { ComplexStore } from '../../store/complex.store';
|
||||||
@@ -35,43 +32,9 @@ export class SuperAdminUserPosesComponent {
|
|||||||
|
|
||||||
setBreadcrumb() {
|
setBreadcrumb() {
|
||||||
this.breadcrumbService.setItems([
|
this.breadcrumbService.setItems([
|
||||||
{
|
...this.consumerStore.breadcrumbItems(),
|
||||||
...superAdminConsumersNamedRoutes.consumers.meta,
|
...this.businessStore.breadcrumbItems(),
|
||||||
routerLink: superAdminConsumersNamedRoutes.consumers.meta.pagePath!(),
|
...this.complexStore.breadcrumbItems(),
|
||||||
},
|
|
||||||
{
|
|
||||||
title: this.consumerStore.entity()?.fullname,
|
|
||||||
routerLink: superAdminConsumersNamedRoutes.consumer.meta.pagePath!(this.consumerId()),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: superAdminConsumerBusinessActivitiesNamedRoutes.businessActivities.meta.title,
|
|
||||||
routerLink: superAdminConsumerBusinessActivitiesNamedRoutes.businessActivities.meta
|
|
||||||
.pagePath!(this.consumerId()),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: this.businessStore.entity()?.name,
|
|
||||||
routerLink: superAdminConsumerBusinessActivitiesNamedRoutes.businessActivity.meta.pagePath!(
|
|
||||||
this.consumerId(),
|
|
||||||
this.businessId(),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
title: superAdminConsumerComplexesNamedRoutes.complexes.meta.title,
|
|
||||||
routerLink: superAdminConsumerComplexesNamedRoutes.complexes.meta.pagePath!(
|
|
||||||
this.consumerId(),
|
|
||||||
this.businessId(),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: this.complexStore.entity()?.name,
|
|
||||||
routerLink: superAdminConsumerComplexesNamedRoutes.complex.meta.pagePath!(
|
|
||||||
this.consumerId(),
|
|
||||||
this.businessId(),
|
|
||||||
this.complexId(),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
{
|
||||||
title: superAdminConsumerPosesNamedRoutes.poses.meta.title,
|
title: superAdminConsumerPosesNamedRoutes.poses.meta.title,
|
||||||
routerLink: superAdminConsumerPosesNamedRoutes.poses.meta.pagePath!(
|
routerLink: superAdminConsumerPosesNamedRoutes.poses.meta.pagePath!(
|
||||||
|
|||||||
@@ -4,10 +4,6 @@ import pageParamsUtils from '@/utils/page-params.utils';
|
|||||||
import { Component, computed, effect, inject, signal } from '@angular/core';
|
import { Component, computed, effect, inject, signal } from '@angular/core';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { ConsumerPosFormComponent } from '../../components/poses/form.component';
|
import { ConsumerPosFormComponent } from '../../components/poses/form.component';
|
||||||
import { superAdminConsumersNamedRoutes } from '../../constants';
|
|
||||||
import { superAdminConsumerBusinessActivitiesNamedRoutes } from '../../constants/routes/businessActivities';
|
|
||||||
import { superAdminConsumerComplexesNamedRoutes } from '../../constants/routes/complexes';
|
|
||||||
import { superAdminConsumerPosesNamedRoutes } from '../../constants/routes/poses';
|
|
||||||
import { BusinessActivityStore } from '../../store/businessActivity.store';
|
import { BusinessActivityStore } from '../../store/businessActivity.store';
|
||||||
import { ComplexStore } from '../../store/complex.store';
|
import { ComplexStore } from '../../store/complex.store';
|
||||||
import { ConsumerStore } from '../../store/consumer.store';
|
import { ConsumerStore } from '../../store/consumer.store';
|
||||||
@@ -46,72 +42,15 @@ export class SuperAdminUserPosComponent {
|
|||||||
readonly pos = computed(() => this.store.entity());
|
readonly pos = computed(() => this.store.entity());
|
||||||
|
|
||||||
getData() {
|
getData() {
|
||||||
this.store.getData(this.businessId(), this.complexId(), this.posId());
|
this.store.getData(this.consumerId(), this.businessId(), this.complexId(), this.posId());
|
||||||
}
|
|
||||||
|
|
||||||
toPosLanding() {
|
|
||||||
// @ts-ignore
|
|
||||||
window.cookieStore.set('posId', this.posId());
|
|
||||||
// window.open('pos')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setBreadcrumb() {
|
setBreadcrumb() {
|
||||||
this.breadcrumbService.setItems([
|
this.breadcrumbService.setItems([
|
||||||
{
|
...this.consumerStore.breadcrumbItems(),
|
||||||
...superAdminConsumersNamedRoutes.consumers.meta,
|
...this.businessStore.breadcrumbItems(),
|
||||||
routerLink: superAdminConsumersNamedRoutes.consumers.meta.pagePath!(),
|
...this.complexStore.breadcrumbItems(),
|
||||||
},
|
...this.store.breadcrumbItems(),
|
||||||
{
|
|
||||||
title: this.consumerStore.entity()?.fullname,
|
|
||||||
routerLink: superAdminConsumersNamedRoutes.consumer.meta.pagePath!(this.consumerId()),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: superAdminConsumerBusinessActivitiesNamedRoutes.businessActivities.meta.title,
|
|
||||||
routerLink: superAdminConsumerBusinessActivitiesNamedRoutes.businessActivities.meta
|
|
||||||
.pagePath!(this.consumerId()),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: this.businessStore.entity()?.name,
|
|
||||||
routerLink: superAdminConsumerBusinessActivitiesNamedRoutes.businessActivity.meta.pagePath!(
|
|
||||||
this.consumerId(),
|
|
||||||
this.businessId(),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
title: superAdminConsumerComplexesNamedRoutes.complexes.meta.title,
|
|
||||||
routerLink: superAdminConsumerComplexesNamedRoutes.complexes.meta.pagePath!(
|
|
||||||
this.consumerId(),
|
|
||||||
this.businessId(),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: this.complexStore.entity()?.name,
|
|
||||||
routerLink: superAdminConsumerComplexesNamedRoutes.complex.meta.pagePath!(
|
|
||||||
this.consumerId(),
|
|
||||||
this.businessId(),
|
|
||||||
this.complexId(),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
title: superAdminConsumerPosesNamedRoutes.poses.meta.title,
|
|
||||||
routerLink: superAdminConsumerPosesNamedRoutes.poses.meta.pagePath!(
|
|
||||||
this.consumerId(),
|
|
||||||
this.businessId(),
|
|
||||||
this.complexId(),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
title: this.pos()?.name,
|
|
||||||
routerLink: superAdminConsumerPosesNamedRoutes.pos.meta.pagePath!(
|
|
||||||
this.consumerId(),
|
|
||||||
this.businessId(),
|
|
||||||
this.complexId(),
|
|
||||||
this.posId(),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import { ConsumerAccountListComponent } from '../components/accounts/list.compon
|
|||||||
import { ConsumerBusinessActivitiesComponent } from '../components/businessActivities/list.component';
|
import { ConsumerBusinessActivitiesComponent } from '../components/businessActivities/list.component';
|
||||||
import { ConsumerUserFormComponent } from '../components/form.component';
|
import { ConsumerUserFormComponent } from '../components/form.component';
|
||||||
import { ConsumerLicenseFormComponent } from '../components/licenses/form.component';
|
import { ConsumerLicenseFormComponent } from '../components/licenses/form.component';
|
||||||
import { superAdminConsumersNamedRoutes } from '../constants';
|
|
||||||
import { ConsumerStore } from '../store/consumer.store';
|
import { ConsumerStore } from '../store/consumer.store';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@@ -62,16 +61,7 @@ export class ConsumerComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setBreadcrumb() {
|
setBreadcrumb() {
|
||||||
this.breadcrumbService.setItems([
|
this.breadcrumbService.setItems(this.store.breadcrumbItems());
|
||||||
{
|
|
||||||
...superAdminConsumersNamedRoutes.consumers.meta,
|
|
||||||
routerLink: superAdminConsumersNamedRoutes.consumers.meta.pagePath!(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: this.consumer()?.fullname,
|
|
||||||
routerLink: superAdminConsumersNamedRoutes.consumer.meta.pagePath!(this.consumerId()),
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
openLicenseForm() {
|
openLicenseForm() {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { EntityState, EntityStore } from '@/core/state';
|
import { EntityState, EntityStore } from '@/core/state';
|
||||||
import { inject, Injectable } from '@angular/core';
|
import { inject, Injectable } from '@angular/core';
|
||||||
import { catchError, finalize, throwError } from 'rxjs';
|
import { catchError, finalize } from 'rxjs';
|
||||||
import { IGuildResponse } from '../models';
|
import { IGuildResponse } from '../models';
|
||||||
import { GuildsService } from '../services/main.service';
|
import { GuildsService } from '../services/main.service';
|
||||||
|
|
||||||
@@ -29,11 +29,9 @@ export class GuildStore extends EntityStore<IGuildResponse, GuildState> {
|
|||||||
finalize(() => {
|
finalize(() => {
|
||||||
this.patchState({ loading: false });
|
this.patchState({ loading: false });
|
||||||
}),
|
}),
|
||||||
catchError(() => {
|
catchError((error) => {
|
||||||
this.patchState({
|
this.setError(error);
|
||||||
error: '',
|
throw error;
|
||||||
});
|
|
||||||
return throwError('');
|
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.subscribe((entity) => {
|
.subscribe((entity) => {
|
||||||
|
|||||||
@@ -8,8 +8,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</app-card-data>
|
</app-card-data>
|
||||||
|
|
||||||
<admin-guild-good-categories-list [guildId]="guildId()" />
|
<div class="max-h-[500px] flex">
|
||||||
<admin-guild-goods-list [guildId]="guildId()" />
|
<admin-guild-good-categories-list [guildId]="guildId()" class="w-full" />
|
||||||
|
</div>
|
||||||
|
<div class="max-h-[500px] flex">
|
||||||
|
<admin-guild-goods-list [guildId]="guildId()" class="w-full" />
|
||||||
|
</div>
|
||||||
|
|
||||||
<admin-guild-form
|
<admin-guild-form
|
||||||
[(visible)]="editMode"
|
[(visible)]="editMode"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { EntityState, EntityStore } from '@/core/state';
|
import { EntityState, EntityStore } from '@/core/state';
|
||||||
import { inject, Injectable } from '@angular/core';
|
import { inject, Injectable } from '@angular/core';
|
||||||
import { catchError, finalize, throwError } from 'rxjs';
|
import { catchError, finalize } from 'rxjs';
|
||||||
import { IPartnerResponse } from '../models';
|
import { IPartnerResponse } from '../models';
|
||||||
import { PartnersService } from '../services/main.service';
|
import { PartnersService } from '../services/main.service';
|
||||||
|
|
||||||
@@ -29,11 +29,9 @@ export class PartnerStore extends EntityStore<IPartnerResponse, PartnerState> {
|
|||||||
finalize(() => {
|
finalize(() => {
|
||||||
this.patchState({ loading: false });
|
this.patchState({ loading: false });
|
||||||
}),
|
}),
|
||||||
catchError(() => {
|
catchError((error) => {
|
||||||
this.patchState({
|
this.setError(error);
|
||||||
error: '',
|
throw error;
|
||||||
});
|
|
||||||
return throwError('');
|
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.subscribe((entity) => {
|
.subscribe((entity) => {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { EntityState, EntityStore } from '@/core/state';
|
import { EntityState, EntityStore } from '@/core/state';
|
||||||
import { inject, Injectable } from '@angular/core';
|
import { inject, Injectable } from '@angular/core';
|
||||||
import { catchError, finalize, throwError } from 'rxjs';
|
import { catchError, finalize } from 'rxjs';
|
||||||
import { IUserResponse } from '../models';
|
import { IUserResponse } from '../models';
|
||||||
import { UsersService } from '../services/main.service';
|
import { UsersService } from '../services/main.service';
|
||||||
|
|
||||||
@@ -29,11 +29,9 @@ export class UserStore extends EntityStore<IUserResponse, UserState> {
|
|||||||
finalize(() => {
|
finalize(() => {
|
||||||
this.patchState({ loading: false });
|
this.patchState({ loading: false });
|
||||||
}),
|
}),
|
||||||
catchError(() => {
|
catchError((error) => {
|
||||||
this.patchState({
|
this.setError(error);
|
||||||
error: '',
|
throw error;
|
||||||
});
|
|
||||||
return throwError('');
|
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.subscribe((entity) => {
|
.subscribe((entity) => {
|
||||||
|
|||||||
@@ -3,14 +3,14 @@
|
|||||||
<ng-container [ngTemplateOutlet]="topBarMoreAction"></ng-container>
|
<ng-container [ngTemplateOutlet]="topBarMoreAction"></ng-container>
|
||||||
</app-topbar>
|
</app-topbar>
|
||||||
@if (fullLoading) {
|
@if (fullLoading) {
|
||||||
<div class="flex justify-center align-items-center h-svh items-center">
|
<div class="flex justify-center align-items-center grow items-center">
|
||||||
<p-progressSpinner></p-progressSpinner>
|
<p-progressSpinner></p-progressSpinner>
|
||||||
</div>
|
</div>
|
||||||
} @else {
|
} @else {
|
||||||
@if (showMenu()) {
|
@if (showMenu()) {
|
||||||
<app-sidebar></app-sidebar>
|
<app-sidebar></app-sidebar>
|
||||||
}
|
}
|
||||||
<div [class]="`layout-main-container ${!showMenu() ? 'hideMenu' : ''}`">
|
<div [class]="`layout-main-container ${!showMenu() ? 'hideMenu' : ''} grow`">
|
||||||
<div class="layout-main flex flex-col gap-4">
|
<div class="layout-main flex flex-col gap-4">
|
||||||
@if (showBreadcrumb) {
|
@if (showBreadcrumb) {
|
||||||
<app-breadcrumb class="rounded-md overflow-hidden shrink-0" />
|
<app-breadcrumb class="rounded-md overflow-hidden shrink-0" />
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<div class="layout-topbar">
|
<div class="layout-topbar shrink-0">
|
||||||
<div class="layout-topbar-logo-container">
|
<div class="layout-topbar-logo-container">
|
||||||
@if (showMenu) {
|
@if (showMenu) {
|
||||||
<button class="layout-menu-button layout-topbar-action" (click)="layoutService.onMenuToggle()">
|
<button class="layout-menu-button layout-topbar-action" (click)="layoutService.onMenuToggle()">
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Maybe } from '@/core';
|
import { Maybe } from '@/core';
|
||||||
import { IPaginatedResponse } from '@/core/models/service.model';
|
import { IListingResponse, IPaginatedResponse } from '@/core/models/service.model';
|
||||||
import { Component, signal } from '@angular/core';
|
import { Component, signal } from '@angular/core';
|
||||||
import { Observable } from 'rxjs';
|
import { catchError, finalize, Observable } from 'rxjs';
|
||||||
import { IColumn } from '../components/pageDataList/page-data-list.component';
|
import { IColumn } from '../components/pageDataList/page-data-list.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@@ -28,10 +28,21 @@ export abstract class AbstractList<ResponseModel, RequestParams = null> {
|
|||||||
|
|
||||||
getData() {
|
getData() {
|
||||||
this.loading.set(true);
|
this.loading.set(true);
|
||||||
this.getDataRequest(this.requestPayload())?.subscribe((res) => {
|
this.items.set([]);
|
||||||
this.loading.set(false);
|
this.getDataRequest(this.requestPayload())
|
||||||
this.items.set(res.data);
|
?.pipe(
|
||||||
});
|
finalize(() => {
|
||||||
|
console.log('first');
|
||||||
|
|
||||||
|
this.loading.set(false);
|
||||||
|
}),
|
||||||
|
catchError((error) => {
|
||||||
|
throw error;
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.subscribe((res) => {
|
||||||
|
this.items.set(res.data ?? []);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
openAddForm() {
|
openAddForm() {
|
||||||
@@ -42,7 +53,7 @@ export abstract class AbstractList<ResponseModel, RequestParams = null> {
|
|||||||
|
|
||||||
abstract getDataRequest(
|
abstract getDataRequest(
|
||||||
payload: Maybe<RequestParams>,
|
payload: Maybe<RequestParams>,
|
||||||
): Observable<IPaginatedResponse<ResponseModel>> | void;
|
): Observable<IPaginatedResponse<ResponseModel> | IListingResponse<ResponseModel>> | void;
|
||||||
|
|
||||||
abstract setColumns(): void;
|
abstract setColumns(): void;
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ export abstract class AbstractSelectComponent<T = ISelectItem, serviceResponse =
|
|||||||
@Input() canInsert: boolean = false;
|
@Input() canInsert: boolean = false;
|
||||||
@Input() showLabel: boolean = true;
|
@Input() showLabel: boolean = true;
|
||||||
@Input() showErrors: boolean = true;
|
@Input() showErrors: boolean = true;
|
||||||
@Input() showClear: boolean = true;
|
@Input() showClear: boolean = false;
|
||||||
@Input() isFullDataOptionValue: boolean = false;
|
@Input() isFullDataOptionValue: boolean = false;
|
||||||
@Input() optionValue = 'id';
|
@Input() optionValue = 'id';
|
||||||
@Output() onChange = new EventEmitter<Maybe<T>>();
|
@Output() onChange = new EventEmitter<Maybe<T>>();
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import { EnumsService } from './services';
|
|||||||
imports: [UikitFieldComponent, Select, ReactiveFormsModule],
|
imports: [UikitFieldComponent, Select, ReactiveFormsModule],
|
||||||
})
|
})
|
||||||
export class EnumSelectComponent extends AbstractSelectComponent<string, IApiEnumResponse[]> {
|
export class EnumSelectComponent extends AbstractSelectComponent<string, IApiEnumResponse[]> {
|
||||||
@Input() type!: TEnumApi;
|
@Input({ required: true }) type!: TEnumApi;
|
||||||
@Input() customLabel?: string;
|
@Input() customLabel?: string;
|
||||||
|
|
||||||
private readonly service = inject(EnumsService);
|
private readonly service = inject(EnumsService);
|
||||||
|
|||||||
@@ -16,8 +16,9 @@
|
|||||||
<ng-container [ngTemplateOutlet]="caption">
|
<ng-container [ngTemplateOutlet]="caption">
|
||||||
<div class="flex justify-between items-center gap-4">
|
<div class="flex justify-between items-center gap-4">
|
||||||
<h5 class="font-bold">{{ pageTitle }}</h5>
|
<h5 class="font-bold">{{ pageTitle }}</h5>
|
||||||
@if (showAdd || filter) {
|
@if (showAdd || filter || moreActions) {
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
|
<ng-container [ngTemplateOutlet]="moreActions" />
|
||||||
@if (filter) {
|
@if (filter) {
|
||||||
<p-button
|
<p-button
|
||||||
label="فیلتر"
|
label="فیلتر"
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ export interface IColumn<T = any> {
|
|||||||
selector: 'app-page-data-list',
|
selector: 'app-page-data-list',
|
||||||
templateUrl: './page-data-list.component.html',
|
templateUrl: './page-data-list.component.html',
|
||||||
host: {
|
host: {
|
||||||
class: 'block w-full',
|
class: 'block w-full h-full overflow-hidden',
|
||||||
},
|
},
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
@@ -77,6 +77,7 @@ export class PageDataListComponent<I> {
|
|||||||
|
|
||||||
@ContentChild('filter', { static: true }) filter!: TemplateRef<any> | null;
|
@ContentChild('filter', { static: true }) filter!: TemplateRef<any> | null;
|
||||||
@ContentChild('caption', { static: true }) caption!: TemplateRef<any> | null;
|
@ContentChild('caption', { static: true }) caption!: TemplateRef<any> | null;
|
||||||
|
@ContentChild('moreActions', { static: true }) moreActions!: TemplateRef<any> | null;
|
||||||
|
|
||||||
@Output() onEdit = new EventEmitter<I>();
|
@Output() onEdit = new EventEmitter<I>();
|
||||||
@Output() onDelete = new EventEmitter<I>();
|
@Output() onDelete = new EventEmitter<I>();
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
export enum COOKIE_KEYS {
|
||||||
|
POS_ID = 'posId',
|
||||||
|
ACCESS_TOKEN = 'accessToken',
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
export * from './accountTypes.const';
|
export * from './accountTypes.const';
|
||||||
|
export * from './cookieKeys.const';
|
||||||
export * from './localStorageKeys.const';
|
export * from './localStorageKeys.const';
|
||||||
export * from './roleTypes.const';
|
export * from './roleTypes.const';
|
||||||
export * from './userRoles.const';
|
export * from './userRoles.const';
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ a {
|
|||||||
|
|
||||||
.layout-wrapper {
|
.layout-wrapper {
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
html {
|
html {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
// height: 100vh;
|
// height: 100vh;
|
||||||
// overflow: hidden;
|
// overflow: hidden;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding: 6rem 1rem 2rem 2rem;
|
padding: 2rem 1rem 2rem 2rem;
|
||||||
transition: margin-inline-start var(--layout-section-transition-duration);
|
transition: margin-inline-start var(--layout-section-transition-duration);
|
||||||
&.hideMenu {
|
&.hideMenu {
|
||||||
margin: 0 !important;
|
margin: 0 !important;
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
@use "mixins" as *;
|
@use "mixins" as *;
|
||||||
|
|
||||||
.layout-topbar {
|
.layout-topbar {
|
||||||
position: fixed;
|
|
||||||
height: 4rem;
|
height: 4rem;
|
||||||
z-index: 997;
|
z-index: 997;
|
||||||
right: 0;
|
right: 0;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ export const environment = {
|
|||||||
production: false,
|
production: false,
|
||||||
// apiBaseUrl: 'http://194.59.214.243:5002',
|
// apiBaseUrl: 'http://194.59.214.243:5002',
|
||||||
apiBaseUrl: 'http://localhost:5002',
|
apiBaseUrl: 'http://localhost:5002',
|
||||||
|
// host: 'http://194.59.214.243',
|
||||||
host: 'localhost',
|
host: 'localhost',
|
||||||
port: 5000,
|
port: 5000,
|
||||||
enableLogging: true,
|
enableLogging: true,
|
||||||
|
|||||||
+1
-1
@@ -9,7 +9,7 @@
|
|||||||
<link rel="manifest" href="/favicon/site.webmanifest" />
|
<link rel="manifest" href="/favicon/site.webmanifest" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body class="min-h-svh overflow-auto">
|
||||||
<app-root></app-root>
|
<app-root></app-root>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user