diff --git a/src/app.component.ts b/src/app.component.ts index 419041b..62820ab 100644 --- a/src/app.component.ts +++ b/src/app.component.ts @@ -8,11 +8,9 @@ import { ToastModule } from 'primeng/toast'; standalone: true, imports: [RouterModule, ToastModule, ConfirmDialog], template: ` -
- - - -
+ + + `, }) export class AppComponent {} diff --git a/src/app.routes.ts b/src/app.routes.ts index 2aec508..0017e36 100644 --- a/src/app.routes.ts +++ b/src/app.routes.ts @@ -4,11 +4,11 @@ import { POS_ROUTES } from '@/domains/pos/routes'; import { PROVIDER_ROUTES } from '@/domains/provider/routes'; import { SUPER_ADMIN_ROUTES } from '@/domains/superAdmin/routes'; import { AuthComponent } from '@/modules/auth/pages/auth.component'; +import { Notfound } from '@/pages/notfound/notfound.component'; import { Routes } from '@angular/router'; import { AppLayout } from './app/layout/default/app.layout.component'; import { Dashboard } from './app/pages/dashboard/dashboard'; import { Documentation } from './app/pages/documentation/documentation'; -import { Notfound } from './app/pages/notfound/notfound.component'; export const appRoutes: Routes = [ { diff --git a/src/app/core/interceptors/error.interceptor.ts b/src/app/core/interceptors/error.interceptor.ts index 094b6b6..0a3071c 100644 --- a/src/app/core/interceptors/error.interceptor.ts +++ b/src/app/core/interceptors/error.interceptor.ts @@ -43,7 +43,7 @@ export const errorInterceptor: HttpInterceptorFn = (req, next) => { errorMessage = 'منبع مورد نظر یافت نشد'; break; case 412: - errorMessage = error.error?.detail || 'اطلاعات ارسالی نامعتبر است'; + errorMessage = error.error?.message || ''; break; case 422: errorMessage = error.error?.message || 'اطلاعات ارسالی نامعتبر است'; @@ -118,6 +118,7 @@ function showErrorNotification(message: string, status: number): void { * Error types for better error handling */ export enum ErrorType { + PRE_CONDITION = 'PRE_CONDITION', NETWORK = 'NETWORK', SERVER = 'SERVER', CLIENT = 'CLIENT', @@ -136,9 +137,10 @@ export function getErrorType(error: HttpErrorResponse): ErrorType { switch (error.status) { case 400: - case 412: case 422: return ErrorType.VALIDATION; + case 412: + return ErrorType.PRE_CONDITION; case 401: return ErrorType.AUTHENTICATION; case 403: diff --git a/src/app/core/services/auth.service.ts b/src/app/core/services/auth.service.ts index 6b64042..dc4e693 100644 --- a/src/app/core/services/auth.service.ts +++ b/src/app/core/services/auth.service.ts @@ -5,9 +5,10 @@ import { HttpClient } from '@angular/common/http'; import { computed, inject, Injectable, signal } from '@angular/core'; import { Router } from '@angular/router'; +import { CookieService } from 'ngx-cookie-service'; import { BehaviorSubject, Observable, throwError } from 'rxjs'; import { catchError, finalize, tap } from 'rxjs/operators'; -import { LOCAL_STORAGE_KEYS } from '../../../assets/constants'; +import { COOKIE_KEYS, LOCAL_STORAGE_KEYS } from '../../../assets/constants'; import { IAuthAccountResponse, IAuthResponse, @@ -28,6 +29,7 @@ export class AuthService { private readonly http = inject(HttpClient); private readonly router = inject(Router); + private readonly cookieService = inject(CookieService); private captchaService = inject(CaptchaService); private readonly currentAccountSubject = new BehaviorSubject>(null); @@ -81,6 +83,7 @@ export class AuthService { .pipe( tap((response) => { this.handleAuthSuccess(response); + this.refreshCookies(); return response; }), catchError((error) => { @@ -98,11 +101,17 @@ export class AuthService { localStorage.removeItem(LOCAL_STORAGE_KEYS.AUTH_TOKEN); localStorage.removeItem(LOCAL_STORAGE_KEYS.USER_DATA); localStorage.removeItem(LOCAL_STORAGE_KEYS.REFRESH_TOKEN); + this.refreshCookies(); this.setCurrentUser(null); 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 { const refreshToken = this.getRefreshToken(); if (!refreshToken) { diff --git a/src/app/core/services/error-handler.service.ts b/src/app/core/services/error-handler.service.ts index cd6ce9d..5e06f3c 100644 --- a/src/app/core/services/error-handler.service.ts +++ b/src/app/core/services/error-handler.service.ts @@ -26,33 +26,33 @@ export class ErrorHandlerService { */ private handleHttpError(error: HttpErrorResponse): void { const errorType = getErrorType(error); + const userMessage = this.getUserMessage(error); - if (userMessage) { - this.toastService.error({ - title: error.error?.title || 'خطا', - text: userMessage, - }); - } else { - switch (errorType) { - case ErrorType.NETWORK: - this.showNetworkError(userMessage); - break; - case ErrorType.AUTHENTICATION: - this.showAuthError(userMessage); - break; - case ErrorType.AUTHORIZATION: - this.showAuthorizationError(userMessage); - break; - case ErrorType.VALIDATION: - this.showValidationError(userMessage, error); - break; - case ErrorType.SERVER: - this.showServerError(userMessage); - break; - default: - this.showGenericError(userMessage); - } + switch (errorType) { + case ErrorType.NETWORK: + this.showNetworkError(userMessage); + break; + case ErrorType.PRE_CONDITION: + this.showPreConditionError(userMessage); + break; + case ErrorType.AUTHENTICATION: + this.showAuthError(userMessage); + break; + case ErrorType.AUTHORIZATION: + this.showAuthorizationError(userMessage); + break; + case ErrorType.VALIDATION: + this.showValidationError(userMessage, error); + break; + case ErrorType.SERVER: + this.showServerError(userMessage); + break; + case ErrorType.SERVER: + this.showServerError(userMessage); + break; + default: + this.showGenericError(userMessage); } } @@ -60,7 +60,6 @@ export class ErrorHandlerService { * Handle generic JavaScript errors */ private handleGenericError(error: any): void { - console.error('Generic error:', error); this.toastService.error({ 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 */ diff --git a/src/app/core/state/base-store.ts b/src/app/core/state/base-store.ts index 0ba4feb..1c9cc04 100644 --- a/src/app/core/state/base-store.ts +++ b/src/app/core/state/base-store.ts @@ -1,3 +1,4 @@ +import { HttpErrorResponse } from '@angular/common/http'; import { Signal, WritableSignal, computed, signal } from '@angular/core'; import { BehaviorSubject, Observable } from 'rxjs'; import { Maybe } from '../models'; @@ -8,7 +9,7 @@ import { IPaginatedQuery, IResponseMetadata } from '../models/service.model'; */ export interface BaseState { loading: boolean; - error: Maybe; + error: Maybe; isRefreshing?: boolean; initialized: boolean; } @@ -72,6 +73,15 @@ export interface StateChange { timestamp: number; } +export const defaultBaseStateData = { + loading: false, + error: null, + errorStatus: null, + entity: null, + initialized: false, + isRefreshing: false, +}; + /** * Base store class with common functionality */ @@ -82,7 +92,7 @@ export abstract class BaseStore { // Public readonly signals readonly state: Signal; readonly loading: Signal; - readonly error: Signal>; + readonly error: Signal>; readonly initialized: Signal; // Observable for RxJS compatibility @@ -135,7 +145,7 @@ export abstract class BaseStore { /** * Set error state */ - protected setError(error: string): void { + protected setError(error: HttpErrorResponse): void { this.patchState({ loading: false, error, @@ -180,6 +190,7 @@ export abstract class EntityStore< setEntity(entity: Maybe): void { this.patchState({ entity, + error: null, } as Partial); } override reset(): void { diff --git a/src/app/domains/consumer/components/invoices/single.component.html b/src/app/domains/consumer/components/invoices/single.component.html new file mode 100644 index 0000000..fc5b7d7 --- /dev/null +++ b/src/app/domains/consumer/components/invoices/single.component.html @@ -0,0 +1,49 @@ +
+ +
+
+ + + + + + +
+ +
+
+ اطلاعات پرداخت +
+ + @for (payment of invoice()?.payments; track $index) { + + } +
+ + اطلاعات صادر کننده +
+ + + + +
+ + @if (variant !== "customer") { + اطلاعات مشتری +
+ @if (invoice()?.customer) {} + +
+ } +
+
+
diff --git a/src/app/domains/consumer/components/invoices/single.component.ts b/src/app/domains/consumer/components/invoices/single.component.ts new file mode 100644 index 0000000..1b545cb --- /dev/null +++ b/src/app/domains/consumer/components/invoices/single.component.ts @@ -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(false); +} diff --git a/src/app/domains/consumer/layouts/layout.component.ts b/src/app/domains/consumer/layouts/layout.component.ts index 5ab9694..6f369d7 100644 --- a/src/app/domains/consumer/layouts/layout.component.ts +++ b/src/app/domains/consumer/layouts/layout.component.ts @@ -31,6 +31,8 @@ export class LayoutComponent { }); ngOnInit() { + console.log('first'); + this.layoutService.setMenuItems(CONSUMER_MENU_ITEMS); this.store.getData(); } diff --git a/src/app/domains/consumer/modules/accounts/store/account.store.ts b/src/app/domains/consumer/modules/accounts/store/account.store.ts index ccdf44d..b92b34b 100644 --- a/src/app/domains/consumer/modules/accounts/store/account.store.ts +++ b/src/app/domains/consumer/modules/accounts/store/account.store.ts @@ -1,7 +1,7 @@ import { EntityState, EntityStore } from '@/core/state'; import { computed, inject, Injectable } from '@angular/core'; import { MenuItem } from 'primeng/api'; -import { catchError, finalize, throwError } from 'rxjs'; +import { catchError, finalize } from 'rxjs'; import { consumerAccountsNamedRoutes } from '../constants'; import { IAccountResponse } from '../models'; import { AccountsService } from '../services/main.service'; @@ -51,11 +51,9 @@ export class AccountStore extends EntityStore { finalize(() => { this.patchState({ loading: false }); }), - catchError(() => { - this.patchState({ - error: '', - }); - return throwError(''); + catchError((error) => { + this.setError(error); + throw error; }), ) .subscribe((entity) => { diff --git a/src/app/domains/consumer/modules/businessActivities/store/businessActivity.store.ts b/src/app/domains/consumer/modules/businessActivities/store/businessActivity.store.ts index bc8e1ff..8cd8d8f 100644 --- a/src/app/domains/consumer/modules/businessActivities/store/businessActivity.store.ts +++ b/src/app/domains/consumer/modules/businessActivities/store/businessActivity.store.ts @@ -1,7 +1,7 @@ import { EntityState, EntityStore } from '@/core/state'; import { computed, inject, Injectable } from '@angular/core'; import { MenuItem } from 'primeng/api'; -import { catchError, finalize, throwError } from 'rxjs'; +import { catchError, finalize } from 'rxjs'; import { consumerBusinessActivityNamedRoutes } from '../constants'; import { IBusinessActivityResponse } from '../models'; import { BusinessActivitiesService } from '../services/main.service'; @@ -55,11 +55,9 @@ export class BusinessActivityStore extends EntityStore< finalize(() => { this.patchState({ loading: false }); }), - catchError(() => { - this.patchState({ - error: '', - }); - return throwError(''); + catchError((error) => { + this.setError(error); + throw error; }), ) .subscribe((entity) => { diff --git a/src/app/domains/consumer/modules/businessActivities/store/complex.store.ts b/src/app/domains/consumer/modules/businessActivities/store/complex.store.ts index 02d6172..f7c7649 100644 --- a/src/app/domains/consumer/modules/businessActivities/store/complex.store.ts +++ b/src/app/domains/consumer/modules/businessActivities/store/complex.store.ts @@ -1,7 +1,7 @@ import { EntityState, EntityStore } from '@/core/state'; import { computed, inject, Injectable } from '@angular/core'; import { MenuItem } from 'primeng/api'; -import { catchError, finalize, throwError } from 'rxjs'; +import { catchError, finalize } from 'rxjs'; import { consumerComplexesNamedRoutes } from '../constants/routes/complexes'; import { IComplexResponse } from '../models'; import { ConsumerComplexesService } from '../services/complexes.service'; @@ -50,11 +50,9 @@ export class ConsumerComplexStore extends EntityStore { this.patchState({ loading: false }); }), - catchError(() => { - this.patchState({ - error: '', - }); - return throwError(''); + catchError((error) => { + this.setError(error); + throw error; }), ) .subscribe((entity) => { diff --git a/src/app/domains/consumer/modules/businessActivities/store/pos.store.ts b/src/app/domains/consumer/modules/businessActivities/store/pos.store.ts index 0ba1d34..b181771 100644 --- a/src/app/domains/consumer/modules/businessActivities/store/pos.store.ts +++ b/src/app/domains/consumer/modules/businessActivities/store/pos.store.ts @@ -1,7 +1,7 @@ import { EntityState, EntityStore } from '@/core/state'; import { computed, inject, Injectable } from '@angular/core'; import { MenuItem } from 'primeng/api'; -import { catchError, finalize, throwError } from 'rxjs'; +import { catchError, finalize } from 'rxjs'; import { consumerPosesNamedRoutes } from '../constants/routes/poses'; import { IPosResponse } from '../models'; import { ConsumerPosesService } from '../services/poses.service'; @@ -51,11 +51,9 @@ export class PosStore extends EntityStore { finalize(() => { this.patchState({ loading: false }); }), - catchError(() => { - this.patchState({ - error: '', - }); - return throwError(''); + catchError((error) => { + this.setError(error); + throw error; }), ) .subscribe((entity) => { diff --git a/src/app/domains/consumer/modules/businessActivities/views/poses/single.component.ts b/src/app/domains/consumer/modules/businessActivities/views/poses/single.component.ts index 6182fd6..62fcd64 100644 --- a/src/app/domains/consumer/modules/businessActivities/views/poses/single.component.ts +++ b/src/app/domains/consumer/modules/businessActivities/views/poses/single.component.ts @@ -5,6 +5,7 @@ import { Component, computed, effect, inject, signal } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { CookieService } from 'ngx-cookie-service'; import { Button } from 'primeng/button'; +import { COOKIE_KEYS } from 'src/assets/constants'; import { ConsumerPosFormComponent } from '../../components/poses/form.component'; import { ConsumerSalesInvoicesComponent } from '../../components/salesInvoices/list.component'; import { BusinessActivityStore } from '../../store/businessActivity.store'; @@ -53,8 +54,8 @@ export class SuperAdminUserPosComponent { } toPosLanding() { - // this.cookieService.delete('posId', '/', 'localhost', false, 'Lax'); - this.cookieService.set('posId', this.posId(), { + this.cookieService.set(COOKIE_KEYS.POS_ID, '', new Date()); + this.cookieService.set(COOKIE_KEYS.POS_ID, this.posId(), { sameSite: 'Lax', // or 'Strict' for same-site requests only secure: false, path: '/', diff --git a/src/app/domains/consumer/modules/customers/store/customer.store.ts b/src/app/domains/consumer/modules/customers/store/customer.store.ts index b78c34e..95f4ee0 100644 --- a/src/app/domains/consumer/modules/customers/store/customer.store.ts +++ b/src/app/domains/consumer/modules/customers/store/customer.store.ts @@ -1,7 +1,7 @@ import { EntityState, EntityStore } from '@/core/state'; import { computed, inject, Injectable } from '@angular/core'; import { MenuItem } from 'primeng/api'; -import { catchError, finalize, throwError } from 'rxjs'; +import { catchError, finalize } from 'rxjs'; import { consumerCustomersNamedRoutes } from '../constants'; import { ICustomerResponse } from '../models'; import { CustomersService } from '../services/main.service'; @@ -54,11 +54,9 @@ export class ConsumerCustomerStore extends EntityStore { this.patchState({ loading: false }); }), - catchError(() => { - this.patchState({ - error: '', - }); - return throwError(''); + catchError((error) => { + this.setError(error); + throw error; }), ) .subscribe((entity) => { diff --git a/src/app/domains/consumer/modules/customers/store/saleInvoice.store.ts b/src/app/domains/consumer/modules/customers/store/saleInvoice.store.ts index 638b0fe..5004e1f 100644 --- a/src/app/domains/consumer/modules/customers/store/saleInvoice.store.ts +++ b/src/app/domains/consumer/modules/customers/store/saleInvoice.store.ts @@ -1,7 +1,7 @@ import { EntityState, EntityStore } from '@/core/state'; import { computed, inject, Injectable } from '@angular/core'; import { MenuItem } from 'primeng/api'; -import { catchError, finalize, throwError } from 'rxjs'; +import { catchError, finalize } from 'rxjs'; import { consumerCustomerSaleInvoicesNamedRoutes } from '../constants/routes/saleInvoices'; import { ICustomerSaleInvoicesResponse } from '../models'; import { CustomerSaleInvoicesService } from '../services/saleInvoices.service'; @@ -58,11 +58,9 @@ export class ConsumerCustomerSaleInvoiceStore extends EntityStore< finalize(() => { this.patchState({ loading: false }); }), - catchError(() => { - this.patchState({ - error: '', - }); - return throwError(''); + catchError((error) => { + this.setError(error); + throw error; }), ) .subscribe((entity) => { diff --git a/src/app/domains/consumer/modules/dashboard/components/statistics/latestInvoices/latest-Invoices.component.html b/src/app/domains/consumer/modules/dashboard/components/statistics/latestInvoices/latest-Invoices.component.html new file mode 100644 index 0000000..be2712e --- /dev/null +++ b/src/app/domains/consumer/modules/dashboard/components/statistics/latestInvoices/latest-Invoices.component.html @@ -0,0 +1,13 @@ + + + تمامی فاکتورها + + diff --git a/src/app/domains/consumer/modules/dashboard/components/statistics/latestInvoices/latest-Invoices.component.ts b/src/app/domains/consumer/modules/dashboard/components/statistics/latestInvoices/latest-Invoices.component.ts new file mode 100644 index 0000000..5454242 --- /dev/null +++ b/src/app/domains/consumer/modules/dashboard/components/statistics/latestInvoices/latest-Invoices.component.ts @@ -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 { + 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), + ); + } +} diff --git a/src/app/domains/consumer/modules/dashboard/constants/apiRoutes/index.ts b/src/app/domains/consumer/modules/dashboard/constants/apiRoutes/index.ts new file mode 100644 index 0000000..dd03465 --- /dev/null +++ b/src/app/domains/consumer/modules/dashboard/constants/apiRoutes/index.ts @@ -0,0 +1,5 @@ +const baseUrl = '/api/v1/consumer/statistics'; + +export const CONSUMER_STATISTICS_API_ROUTES = { + invoices: () => `${baseUrl}/invoices`, +}; diff --git a/src/app/domains/consumer/modules/dashboard/constants/index.ts b/src/app/domains/consumer/modules/dashboard/constants/index.ts new file mode 100644 index 0000000..b853783 --- /dev/null +++ b/src/app/domains/consumer/modules/dashboard/constants/index.ts @@ -0,0 +1 @@ +export * from './apiRoutes'; diff --git a/src/app/domains/consumer/modules/dashboard/models/index.ts b/src/app/domains/consumer/modules/dashboard/models/index.ts new file mode 100644 index 0000000..1afdfe1 --- /dev/null +++ b/src/app/domains/consumer/modules/dashboard/models/index.ts @@ -0,0 +1 @@ +export * from './saleInvoices.io'; diff --git a/src/app/domains/consumer/modules/dashboard/models/saleInvoices.io.d.ts b/src/app/domains/consumer/modules/dashboard/models/saleInvoices.io.d.ts new file mode 100644 index 0000000..115b06b --- /dev/null +++ b/src/app/domains/consumer/modules/dashboard/models/saleInvoices.io.d.ts @@ -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; +} diff --git a/src/app/domains/consumer/modules/dashboard/services/main.service.ts b/src/app/domains/consumer/modules/dashboard/services/main.service.ts new file mode 100644 index 0000000..f1ef6c8 --- /dev/null +++ b/src/app/domains/consumer/modules/dashboard/services/main.service.ts @@ -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> { + return this.http.get>( + this.apiRoutes.invoices(), + ); + } +} diff --git a/src/app/domains/consumer/modules/dashboard/views/index.component.html b/src/app/domains/consumer/modules/dashboard/views/index.component.html index 1424343..b9d3ca8 100644 --- a/src/app/domains/consumer/modules/dashboard/views/index.component.html +++ b/src/app/domains/consumer/modules/dashboard/views/index.component.html @@ -1,3 +1,5 @@ -
- به پنل کسب و کار خوش آمدید +
+
+ +
diff --git a/src/app/domains/consumer/modules/dashboard/views/index.component.ts b/src/app/domains/consumer/modules/dashboard/views/index.component.ts index 3456d67..1829224 100644 --- a/src/app/domains/consumer/modules/dashboard/views/index.component.ts +++ b/src/app/domains/consumer/modules/dashboard/views/index.component.ts @@ -1,8 +1,10 @@ import { Component } from '@angular/core'; +import { ConsumerStatisticsLatestInvoicesComponent } from '../components/statistics/latestInvoices/latest-Invoices.component'; @Component({ selector: 'consumer-dashboard', templateUrl: './index.component.html', + imports: [ConsumerStatisticsLatestInvoicesComponent], }) export class DashboardComponent { constructor() {} diff --git a/src/app/domains/consumer/modules/saleInvoices/components/layout.component.html b/src/app/domains/consumer/modules/saleInvoices/components/layout.component.html new file mode 100644 index 0000000..5416fe1 --- /dev/null +++ b/src/app/domains/consumer/modules/saleInvoices/components/layout.component.html @@ -0,0 +1,5 @@ +@if (loading()) { + +} @else { + +} diff --git a/src/app/domains/consumer/modules/saleInvoices/components/layout.component.ts b/src/app/domains/consumer/modules/saleInvoices/components/layout.component.ts new file mode 100644 index 0000000..97cc446 --- /dev/null +++ b/src/app/domains/consumer/modules/saleInvoices/components/layout.component.ts @@ -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(this.route.snapshot.paramMap.get('invoiceId')!); + + readonly loading = computed(() => this.store.loading()); + + getData() { + this.store.getData(this.invoiceId()); + } + + ngOnInit() { + this.getData(); + } +} diff --git a/src/app/domains/consumer/modules/saleInvoices/components/list.component.html b/src/app/domains/consumer/modules/saleInvoices/components/list.component.html new file mode 100644 index 0000000..a264dff --- /dev/null +++ b/src/app/domains/consumer/modules/saleInvoices/components/list.component.html @@ -0,0 +1,9 @@ + diff --git a/src/app/domains/consumer/modules/saleInvoices/components/list.component.ts b/src/app/domains/consumer/modules/saleInvoices/components/list.component.ts new file mode 100644 index 0000000..49f205e --- /dev/null +++ b/src/app/domains/consumer/modules/saleInvoices/components/list.component.ts @@ -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 { + @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)); + } +} diff --git a/src/app/domains/consumer/modules/saleInvoices/constants/apiRoutes/index.ts b/src/app/domains/consumer/modules/saleInvoices/constants/apiRoutes/index.ts new file mode 100644 index 0000000..14d4af5 --- /dev/null +++ b/src/app/domains/consumer/modules/saleInvoices/constants/apiRoutes/index.ts @@ -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}`, +}; diff --git a/src/app/domains/consumer/modules/saleInvoices/constants/index.ts b/src/app/domains/consumer/modules/saleInvoices/constants/index.ts new file mode 100644 index 0000000..ee61bd7 --- /dev/null +++ b/src/app/domains/consumer/modules/saleInvoices/constants/index.ts @@ -0,0 +1,2 @@ +export * from './apiRoutes'; +export * from './routes'; diff --git a/src/app/domains/consumer/modules/saleInvoices/constants/routes/index.ts b/src/app/domains/consumer/modules/saleInvoices/constants/routes/index.ts new file mode 100644 index 0000000..4aa73aa --- /dev/null +++ b/src/app/domains/consumer/modules/saleInvoices/constants/routes/index.ts @@ -0,0 +1,30 @@ +import { NamedRoutes } from '@/core'; +import { Routes } from '@angular/router'; + +export type TConsumerSaleInvoicesRouteNames = 'saleInvoices' | 'saleInvoice'; + +export const consumerSaleInvoicesNamedRoutes: NamedRoutes = { + 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, +]; diff --git a/src/app/domains/consumer/modules/saleInvoices/models/index.ts b/src/app/domains/consumer/modules/saleInvoices/models/index.ts new file mode 100644 index 0000000..61a518a --- /dev/null +++ b/src/app/domains/consumer/modules/saleInvoices/models/index.ts @@ -0,0 +1 @@ +export * from './io'; diff --git a/src/app/domains/consumer/modules/saleInvoices/models/io.d.ts b/src/app/domains/consumer/modules/saleInvoices/models/io.d.ts new file mode 100644 index 0000000..2221860 --- /dev/null +++ b/src/app/domains/consumer/modules/saleInvoices/models/io.d.ts @@ -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; +} diff --git a/src/app/domains/consumer/modules/saleInvoices/services/main.service.ts b/src/app/domains/consumer/modules/saleInvoices/services/main.service.ts new file mode 100644 index 0000000..e335667 --- /dev/null +++ b/src/app/domains/consumer/modules/saleInvoices/services/main.service.ts @@ -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> { + return this.http.get>( + this.apiRoutes.list(), + ); + } + getSingle(invoiceId: string): Observable { + return this.http.get(this.apiRoutes.single(invoiceId)); + } +} diff --git a/src/app/domains/consumer/modules/saleInvoices/store/main.store.ts b/src/app/domains/consumer/modules/saleInvoices/store/main.store.ts new file mode 100644 index 0000000..ea42a85 --- /dev/null +++ b/src/app/domains/consumer/modules/saleInvoices/store/main.store.ts @@ -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 { + 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: [], + }); + } +} diff --git a/src/app/domains/consumer/modules/saleInvoices/views/index.ts b/src/app/domains/consumer/modules/saleInvoices/views/index.ts new file mode 100644 index 0000000..bc9dfc9 --- /dev/null +++ b/src/app/domains/consumer/modules/saleInvoices/views/index.ts @@ -0,0 +1,2 @@ +export * from './list.component'; +export * from './single.component'; diff --git a/src/app/domains/consumer/modules/saleInvoices/views/list.component.html b/src/app/domains/consumer/modules/saleInvoices/views/list.component.html new file mode 100644 index 0000000..568c5a1 --- /dev/null +++ b/src/app/domains/consumer/modules/saleInvoices/views/list.component.html @@ -0,0 +1 @@ + diff --git a/src/app/domains/consumer/modules/saleInvoices/views/list.component.ts b/src/app/domains/consumer/modules/saleInvoices/views/list.component.ts new file mode 100644 index 0000000..96ece84 --- /dev/null +++ b/src/app/domains/consumer/modules/saleInvoices/views/list.component.ts @@ -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 {} diff --git a/src/app/domains/consumer/modules/saleInvoices/views/single.component.html b/src/app/domains/consumer/modules/saleInvoices/views/single.component.html new file mode 100644 index 0000000..1a9ea8a --- /dev/null +++ b/src/app/domains/consumer/modules/saleInvoices/views/single.component.html @@ -0,0 +1 @@ + diff --git a/src/app/domains/consumer/modules/saleInvoices/views/single.component.ts b/src/app/domains/consumer/modules/saleInvoices/views/single.component.ts new file mode 100644 index 0000000..2baaa73 --- /dev/null +++ b/src/app/domains/consumer/modules/saleInvoices/views/single.component.ts @@ -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(this.pageParams()['invoiceId']); + editMode = signal(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()]); + } +} diff --git a/src/app/domains/consumer/routes.ts b/src/app/domains/consumer/routes.ts index 4373992..22496aa 100644 --- a/src/app/domains/consumer/routes.ts +++ b/src/app/domains/consumer/routes.ts @@ -2,6 +2,7 @@ import { Route } from '@angular/router'; import { CONSUMER_ACCOUNTS_ROUTES } from './modules/accounts/constants'; import { CONSUMER_BUSINESS_ACTIVITIES_ROUTES } from './modules/businessActivities/constants'; import { CONSUMER_CUSTOMERS_ROUTES } from './modules/customers/constants'; +import { CONSUMER_SALE_INVOICES_ROUTES } from './modules/saleInvoices/constants'; export const CONSUMER_ROUTES = { path: 'consumer', @@ -15,5 +16,6 @@ export const CONSUMER_ROUTES = { ...CONSUMER_ACCOUNTS_ROUTES, ...CONSUMER_BUSINESS_ACTIVITIES_ROUTES, ...CONSUMER_CUSTOMERS_ROUTES, + ...CONSUMER_SALE_INVOICES_ROUTES, ], } as Route; diff --git a/src/app/domains/consumer/store/main.store.ts b/src/app/domains/consumer/store/main.store.ts index 461d0f7..b6275db 100644 --- a/src/app/domains/consumer/store/main.store.ts +++ b/src/app/domains/consumer/store/main.store.ts @@ -1,7 +1,7 @@ import { EntityState, EntityStore } from '@/core/state'; import { LayoutService } from '@/layout/service/layout.service'; import { inject, Injectable } from '@angular/core'; -import { catchError, finalize, throwError } from 'rxjs'; +import { catchError, finalize } from 'rxjs'; import { IConsumerInfoResponse } from '../models'; import { ConsumerService } from '../services/main.service'; @@ -32,11 +32,9 @@ export class ConsumerStore extends EntityStore { this.patchState({ loading: false }); }), - catchError(() => { - this.patchState({ - error: '', - }); - return throwError(''); + catchError((error) => { + this.setError(error); + throw error; }), ) .subscribe((entity) => { diff --git a/src/app/domains/pos/layouts/choose-pos.component.html b/src/app/domains/pos/layouts/choose-pos.component.html new file mode 100644 index 0000000..aeee04a --- /dev/null +++ b/src/app/domains/pos/layouts/choose-pos.component.html @@ -0,0 +1,24 @@ +@if (loading()) { + +} @else if (items()) { +
+ برای ادامه می‌بایست یکی از پایانه‌های زیر را انتخاب کنید. +
+ @for (item of items(); track $index) { + +
+ + {{ item.name }} + + {{ item.complex.business_activity.name }} - {{ item.complex.name }} + + +
+
+ } +
+
+} diff --git a/src/app/domains/pos/layouts/choose-pos.component.ts b/src/app/domains/pos/layouts/choose-pos.component.ts new file mode 100644 index 0000000..2b525b3 --- /dev/null +++ b/src/app/domains/pos/layouts/choose-pos.component.ts @@ -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([]); + error = signal>(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(); + } +} diff --git a/src/app/domains/pos/layouts/layout.component.html b/src/app/domains/pos/layouts/layout.component.html index 4be8121..f7ee9ad 100644 --- a/src/app/domains/pos/layouts/layout.component.html +++ b/src/app/domains/pos/layouts/layout.component.html @@ -7,17 +7,42 @@
Logo
- {{ posInfo()?.name }} - فروشگاه {{ posInfo()?.complex?.name }} + @if (posInfo()) { + {{ posInfo()?.name }} - فروشگاه {{ posInfo()?.complex?.name }} + }
-
+
-
- {{ userInfo()?.username }} +
+ +
- + @if (error()) { + @switch (error()?.status) { + @case (412) { + + } + @default { +
+ +
+ + عدم دسترسی +

متاسفانه امکان دسترسی برای کاربر شما فراهم نیست

+ +
+
+
+ } + } + } @else { + + }
} diff --git a/src/app/domains/pos/layouts/layout.component.ts b/src/app/domains/pos/layouts/layout.component.ts index ffcb6f1..58d91b2 100644 --- a/src/app/domains/pos/layouts/layout.component.ts +++ b/src/app/domains/pos/layouts/layout.component.ts @@ -3,13 +3,26 @@ import { PageLoadingComponent } from '@/shared/components/page-loading.component import { JalaliDateDirective } from '@/shared/directives'; import { Component, computed, inject } from '@angular/core'; 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 { PosStore } from '../pos.store'; +import { PosChooseCardsComponent } from './choose-pos.component'; @Component({ selector: 'pos-layout', templateUrl: './layout.component.html', - imports: [PageLoadingComponent, RouterOutlet, JalaliDateDirective], + imports: [ + PageLoadingComponent, + RouterOutlet, + JalaliDateDirective, + Menu, + ButtonDirective, + Card, + PosChooseCardsComponent, + ], }) export class PosLayoutComponent { constructor() {} @@ -19,8 +32,26 @@ export class PosLayoutComponent { readonly loading = computed(() => this.store.loading()); readonly posInfo = computed(() => this.store.entity()); + readonly error = computed(() => this.store.error()); 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; now = new Date(); @@ -29,6 +60,10 @@ export class PosLayoutComponent { this.store.getData().subscribe(); } + onChoosePos() { + this.getData(); + } + ngOnInit() { this.getData(); } diff --git a/src/app/domains/pos/models/pos.io.ts b/src/app/domains/pos/models/pos.io.ts index ffc4d25..295d728 100644 --- a/src/app/domains/pos/models/pos.io.ts +++ b/src/app/domains/pos/models/pos.io.ts @@ -1,3 +1,5 @@ +import ISummary from '@/core/models/summary'; + export interface IPosInfoRawResponse { name: true; complex: { @@ -16,3 +18,12 @@ export interface 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; +} diff --git a/src/app/domains/pos/modules/landing/constants/apiRoutes/index.ts b/src/app/domains/pos/modules/landing/constants/apiRoutes/index.ts index 08706b6..f5eddb4 100644 --- a/src/app/domains/pos/modules/landing/constants/apiRoutes/index.ts +++ b/src/app/domains/pos/modules/landing/constants/apiRoutes/index.ts @@ -2,6 +2,7 @@ const baseUrl = '/api/v1/pos'; export const POS_API_ROUTES = { info: () => `${baseUrl}`, + accessible: () => `${baseUrl}/accessible`, goods: () => `${baseUrl}/goods`, goodCategories: () => `${baseUrl}/good_categories`, submitOrder: () => `${baseUrl}/sales_invoices`, diff --git a/src/app/domains/pos/modules/landing/services/main.service.ts b/src/app/domains/pos/modules/landing/services/main.service.ts index 512d51e..299af22 100644 --- a/src/app/domains/pos/modules/landing/services/main.service.ts +++ b/src/app/domains/pos/modules/landing/services/main.service.ts @@ -5,7 +5,12 @@ import { IGoodRawResponse, IGoodResponse, } 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 { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; @@ -21,6 +26,11 @@ export class PosService { getInfo(): Observable { return this.http.get(this.apiRoutes.info()); } + + getAccessible(): Observable> { + return this.http.get>(this.apiRoutes.accessible()); + } + getGoods(searchQuery: string): Observable> { return this.http.get>(this.apiRoutes.goods()); } diff --git a/src/app/domains/pos/modules/landing/views/root.component.html b/src/app/domains/pos/modules/landing/views/root.component.html index 615529c..1bcb707 100644 --- a/src/app/domains/pos/modules/landing/views/root.component.html +++ b/src/app/domains/pos/modules/landing/views/root.component.html @@ -1,8 +1,10 @@
-
- -
-
- -
+ @if (posInfo()) { +
+ +
+
+ +
+ }
diff --git a/src/app/domains/pos/modules/landing/views/root.component.ts b/src/app/domains/pos/modules/landing/views/root.component.ts index 208eaef..416fef6 100644 --- a/src/app/domains/pos/modules/landing/views/root.component.ts +++ b/src/app/domains/pos/modules/landing/views/root.component.ts @@ -1,5 +1,6 @@ // 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 { PosOrderSectionComponent } from '../components/order/order-section.component'; @@ -10,4 +11,8 @@ import { PosOrderSectionComponent } from '../components/order/order-section.comp imports: [PosGoodsComponent, PosOrderSectionComponent], }) -export class PosLandingComponent {} +export class PosLandingComponent { + private readonly posStore = inject(PosStore); + + readonly posInfo = computed(() => this.posStore.entity()); +} diff --git a/src/app/domains/pos/pos.store.ts b/src/app/domains/pos/pos.store.ts index a24ef80..01f17e6 100644 --- a/src/app/domains/pos/pos.store.ts +++ b/src/app/domains/pos/pos.store.ts @@ -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 { 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 { PosService } from './modules/landing/services/main.service'; @@ -17,12 +19,8 @@ export class PosStore extends EntityStore { constructor(private readonly cookieService: CookieService) { super({ - loading: false, - error: null, - entity: null, - initialized: false, - isRefreshing: false, - posId: cookieService.get('posId'), + ...defaultBaseStateData, + posId: cookieService.get(COOKIE_KEYS.POS_ID), }); } @@ -35,9 +33,15 @@ export class PosStore extends EntityStore { this.patchState({ loading: false }); }), + catchError((err: HttpErrorResponse) => { + this.setError(err); + // if (err.status === 403) debugger; + throw err; + }), + map((entity: IPosInfoResponse) => { if (entity) { - this.patchState({ entity: entity }); + this.setEntity(entity); } return entity; }), @@ -46,12 +50,8 @@ export class PosStore extends EntityStore { override reset(): void { this.setState({ - loading: false, - error: null, - entity: null, - initialized: false, - isRefreshing: false, - posId: this.cookieService.get('posId'), + ...defaultBaseStateData, + posId: this.cookieService.get(COOKIE_KEYS.POS_ID), }); } } diff --git a/src/app/domains/superAdmin/modules/consumers/components/licenses/form.component.html b/src/app/domains/superAdmin/modules/consumers/components/licenses/form.component.html index be2e914..449bac2 100644 --- a/src/app/domains/superAdmin/modules/consumers/components/licenses/form.component.html +++ b/src/app/domains/superAdmin/modules/consumers/components/licenses/form.component.html @@ -14,7 +14,7 @@ hint="مدت زمان لایسنس‌ها ۱ ساله هستند." /> - + diff --git a/src/app/domains/superAdmin/modules/consumers/components/poses/layout.component.ts b/src/app/domains/superAdmin/modules/consumers/components/poses/layout.component.ts index 8a13e4a..2d5f9d1 100644 --- a/src/app/domains/superAdmin/modules/consumers/components/poses/layout.component.ts +++ b/src/app/domains/superAdmin/modules/consumers/components/poses/layout.component.ts @@ -16,12 +16,13 @@ export class SuperAdminConsumerPosLayoutComponent { readonly loading = computed(() => this.store.loading()); readonly pageParams = computed(() => pageParamsUtils(this.route)); + readonly consumerId = computed(() => this.pageParams()['consumerId']!); readonly businessId = computed(() => this.pageParams()['businessActivityId']!); readonly complexId = computed(() => this.pageParams()['complexId']!); readonly posId = computed(() => this.pageParams()['posId']!); getData() { - this.store.getData(this.businessId(), this.complexId(), this.posId()); + this.store.getData(this.consumerId(), this.businessId(), this.complexId(), this.posId()); } ngOnInit() { diff --git a/src/app/domains/superAdmin/modules/consumers/store/businessActivity.store.ts b/src/app/domains/superAdmin/modules/consumers/store/businessActivity.store.ts index 554efa5..0f7c367 100644 --- a/src/app/domains/superAdmin/modules/consumers/store/businessActivity.store.ts +++ b/src/app/domains/superAdmin/modules/consumers/store/businessActivity.store.ts @@ -1,10 +1,14 @@ import { EntityState, EntityStore } from '@/core/state'; -import { inject, Injectable } from '@angular/core'; -import { catchError, finalize, throwError } from 'rxjs'; +import { computed, inject, Injectable } from '@angular/core'; +import { MenuItem } from 'primeng/api'; +import { catchError, finalize } from 'rxjs'; +import { superAdminConsumerBusinessActivitiesNamedRoutes } from '../constants/routes/businessActivities'; import { IBusinessActivityResponse } from '../models'; import { AdminConsumerBusinessActivitiesService } from '../services/businessActivities.service'; -interface BusinessActivityState extends EntityState {} +interface BusinessActivityState extends EntityState { + breadcrumbItems: MenuItem[]; +} @Injectable({ providedIn: 'root', @@ -21,26 +25,47 @@ export class BusinessActivityStore extends EntityStore< entity: null, initialized: 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.service - .getSingle(consumerId, business_id) + .getSingle(consumerId, businessId) .pipe( finalize(() => { this.patchState({ loading: false }); }), - catchError(() => { - this.patchState({ - error: '', - }); - return throwError(''); + catchError((error) => { + this.setError(error); + throw error; }), ) .subscribe((entity) => { this.patchState({ entity }); + this.setBreadcrumb(consumerId, businessId); }); } @@ -51,6 +76,7 @@ export class BusinessActivityStore extends EntityStore< entity: null, initialized: false, isRefreshing: false, + breadcrumbItems: [], }); } } diff --git a/src/app/domains/superAdmin/modules/consumers/store/complex.store.ts b/src/app/domains/superAdmin/modules/consumers/store/complex.store.ts index 351545e..742c540 100644 --- a/src/app/domains/superAdmin/modules/consumers/store/complex.store.ts +++ b/src/app/domains/superAdmin/modules/consumers/store/complex.store.ts @@ -1,10 +1,14 @@ import { EntityState, EntityStore } from '@/core/state'; -import { inject, Injectable } from '@angular/core'; -import { catchError, finalize, throwError } from 'rxjs'; +import { computed, inject, Injectable } from '@angular/core'; +import { MenuItem } from 'primeng/api'; +import { catchError, finalize } from 'rxjs'; +import { superAdminConsumerComplexesNamedRoutes } from '../constants/routes/complexes'; import { IComplexResponse } from '../models'; import { AdminComplexesService } from '../services/complexes.service'; -interface ComplexState extends EntityState {} +interface ComplexState extends EntityState { + breadcrumbItems: MenuItem[]; +} @Injectable({ providedIn: 'root', @@ -18,6 +22,31 @@ export class ComplexStore extends EntityStore { entity: null, initialized: 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 { finalize(() => { this.patchState({ loading: false }); }), - catchError(() => { - this.patchState({ - error: '', - }); - return throwError(''); + catchError((error) => { + this.setError(error); + throw error; }), ) .subscribe((entity) => { this.patchState({ entity }); + this.setBreadcrumb(consumerId, businessId, complexId); }); } @@ -48,6 +76,7 @@ export class ComplexStore extends EntityStore { entity: null, initialized: false, isRefreshing: false, + breadcrumbItems: [], }); } } diff --git a/src/app/domains/superAdmin/modules/consumers/store/consumer.store.ts b/src/app/domains/superAdmin/modules/consumers/store/consumer.store.ts index 8b89c42..f65d9a7 100644 --- a/src/app/domains/superAdmin/modules/consumers/store/consumer.store.ts +++ b/src/app/domains/superAdmin/modules/consumers/store/consumer.store.ts @@ -1,10 +1,14 @@ import { EntityState, EntityStore } from '@/core/state'; -import { inject, Injectable } from '@angular/core'; -import { catchError, finalize, throwError } from 'rxjs'; +import { computed, inject, Injectable } from '@angular/core'; +import { MenuItem } from 'primeng/api'; +import { catchError, finalize } from 'rxjs'; +import { superAdminConsumersNamedRoutes } from '../constants'; import { IConsumerResponse } from '../models'; import { ConsumersService } from '../services/main.service'; -interface ConsumerState extends EntityState {} +interface ConsumerState extends EntityState { + breadcrumbItems: MenuItem[]; +} @Injectable({ providedIn: 'root', @@ -18,26 +22,43 @@ export class ConsumerStore extends EntityStore entity: null, initialized: 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.service - .getSingle(partnerId) + .getSingle(consumerId) .pipe( finalize(() => { this.patchState({ loading: false }); }), - catchError(() => { - this.patchState({ - error: '', - }); - return throwError(''); + catchError((error) => { + this.setError(error); + throw error; }), ) .subscribe((entity) => { this.patchState({ entity }); + this.setBreadcrumb(consumerId); }); } } diff --git a/src/app/domains/superAdmin/modules/consumers/store/pos.store.ts b/src/app/domains/superAdmin/modules/consumers/store/pos.store.ts index e401363..70c37fb 100644 --- a/src/app/domains/superAdmin/modules/consumers/store/pos.store.ts +++ b/src/app/domains/superAdmin/modules/consumers/store/pos.store.ts @@ -1,10 +1,14 @@ import { EntityState, EntityStore } from '@/core/state'; -import { inject, Injectable } from '@angular/core'; -import { catchError, finalize, throwError } from 'rxjs'; +import { computed, inject, Injectable } from '@angular/core'; +import { MenuItem } from 'primeng/api'; +import { catchError, finalize } from 'rxjs'; +import { superAdminConsumerPosesNamedRoutes } from '../constants/routes/poses'; import { IPosResponse } from '../models'; import { AdminPosesService } from '../services/poses.service'; -interface PosState extends EntityState {} +interface PosState extends EntityState { + breadcrumbItems: MenuItem[]; +} @Injectable({ providedIn: 'root', @@ -18,10 +22,38 @@ export class PosStore extends EntityStore { entity: null, initialized: 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.service .getSingle(businessId, complexId, posId) @@ -29,15 +61,14 @@ export class PosStore extends EntityStore { finalize(() => { this.patchState({ loading: false }); }), - catchError(() => { - this.patchState({ - error: '', - }); - return throwError(''); + catchError((error) => { + this.setError(error); + throw error; }), ) .subscribe((entity) => { this.patchState({ entity }); + this.setBreadcrumb(consumerId, businessId, complexId, posId); }); } @@ -48,6 +79,7 @@ export class PosStore extends EntityStore { entity: null, initialized: false, isRefreshing: false, + breadcrumbItems: [], }); } } diff --git a/src/app/domains/superAdmin/modules/consumers/views/accounts/list.component.ts b/src/app/domains/superAdmin/modules/consumers/views/accounts/list.component.ts index 15d05d7..510572d 100644 --- a/src/app/domains/superAdmin/modules/consumers/views/accounts/list.component.ts +++ b/src/app/domains/superAdmin/modules/consumers/views/accounts/list.component.ts @@ -3,7 +3,6 @@ import { BreadcrumbService } from '@/core/services'; import { Component, inject, signal } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { ConsumerAccountListComponent } from '../../components/accounts/list.component'; -import { superAdminConsumersNamedRoutes } from '../../constants'; import { superAdminConsumerAccountsNamedRoutes } from '../../constants/routes/accounts'; import { ConsumerStore } from '../../store/consumer.store'; @@ -25,14 +24,7 @@ export class ConsumerAccountsComponent { setBreadcrumb() { this.breadcrumbService.setItems([ - { - ...superAdminConsumersNamedRoutes.consumers.meta, - routerLink: superAdminConsumersNamedRoutes.consumers.meta.pagePath!(), - }, - { - title: this.store.entity()?.fullname, - routerLink: superAdminConsumersNamedRoutes.consumer.meta.pagePath!(this.consumerId()), - }, + ...this.store.breadcrumbItems(), { title: superAdminConsumerAccountsNamedRoutes.accounts.meta.title, }, diff --git a/src/app/domains/superAdmin/modules/consumers/views/businessActivities/list.component.ts b/src/app/domains/superAdmin/modules/consumers/views/businessActivities/list.component.ts index d2479d5..beff297 100644 --- a/src/app/domains/superAdmin/modules/consumers/views/businessActivities/list.component.ts +++ b/src/app/domains/superAdmin/modules/consumers/views/businessActivities/list.component.ts @@ -4,7 +4,6 @@ import pageParamsUtils from '@/utils/page-params.utils'; import { Component, computed, inject, signal } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { ConsumerBusinessActivitiesComponent } from '../../components/businessActivities/list.component'; -import { superAdminConsumersNamedRoutes } from '../../constants'; import { superAdminConsumerBusinessActivitiesNamedRoutes } from '../../constants/routes/businessActivities'; import { ConsumerStore } from '../../store/consumer.store'; @@ -27,14 +26,7 @@ export class SuperAdminUserBusinessActivitiesComponent { setBreadcrumb() { this.breadcrumbService.setItems([ - { - ...superAdminConsumersNamedRoutes.consumers.meta, - routerLink: superAdminConsumersNamedRoutes.consumers.meta.pagePath!(), - }, - { - title: this.consumerStore.entity()?.fullname, - routerLink: superAdminConsumersNamedRoutes.consumer.meta.pagePath!(this.consumerId()), - }, + ...this.consumerStore.breadcrumbItems(), { title: superAdminConsumerBusinessActivitiesNamedRoutes.businessActivities.meta.title, }, diff --git a/src/app/domains/superAdmin/modules/consumers/views/businessActivities/single.component.ts b/src/app/domains/superAdmin/modules/consumers/views/businessActivities/single.component.ts index 4fdea83..ea3b426 100644 --- a/src/app/domains/superAdmin/modules/consumers/views/businessActivities/single.component.ts +++ b/src/app/domains/superAdmin/modules/consumers/views/businessActivities/single.component.ts @@ -6,8 +6,6 @@ import { ActivatedRoute } from '@angular/router'; import { ConsumerBusinessActivitiesFormComponent } from '../../components/businessActivities/form.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 { ConsumerStore } from '../../store/consumer.store'; @@ -50,26 +48,8 @@ export class SuperAdminUserBusinessActivityComponent { setBreadcrumb() { this.breadcrumbService.setItems([ - { - ...superAdminConsumersNamedRoutes.consumers.meta, - 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(), - ), - }, + ...this.consumerStore.breadcrumbItems(), + ...this.store.breadcrumbItems(), ]); } } diff --git a/src/app/domains/superAdmin/modules/consumers/views/complexes/list.component.ts b/src/app/domains/superAdmin/modules/consumers/views/complexes/list.component.ts index 32112e7..70b8b6b 100644 --- a/src/app/domains/superAdmin/modules/consumers/views/complexes/list.component.ts +++ b/src/app/domains/superAdmin/modules/consumers/views/complexes/list.component.ts @@ -4,8 +4,6 @@ import pageParamsUtils from '@/utils/page-params.utils'; import { Component, computed, inject, signal } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { ConsumerComplexesComponent } from '../../components/complexes/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 { ConsumerStore } from '../../store/consumer.store'; @@ -31,26 +29,8 @@ export class SuperAdminUserComplexesComponent { setBreadcrumb() { this.breadcrumbService.setItems([ - { - ...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, - routerLink: superAdminConsumerBusinessActivitiesNamedRoutes.businessActivities.meta - .pagePath!(this.consumerId()), - }, - { - title: this.businessStore.entity()?.name, - routerLink: superAdminConsumerBusinessActivitiesNamedRoutes.businessActivity.meta.pagePath!( - this.consumerId(), - this.businessId(), - ), - }, + ...this.consumerStore.breadcrumbItems(), + ...this.businessStore.breadcrumbItems(), { title: superAdminConsumerComplexesNamedRoutes.complexes.meta.title, routerLink: superAdminConsumerComplexesNamedRoutes.complexes.meta.pagePath!( diff --git a/src/app/domains/superAdmin/modules/consumers/views/complexes/single.component.ts b/src/app/domains/superAdmin/modules/consumers/views/complexes/single.component.ts index c756190..b33e595 100644 --- a/src/app/domains/superAdmin/modules/consumers/views/complexes/single.component.ts +++ b/src/app/domains/superAdmin/modules/consumers/views/complexes/single.component.ts @@ -5,9 +5,6 @@ import { Component, computed, effect, inject, signal } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { ConsumerComplexFormComponent } from '../../components/complexes/form.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 { ComplexStore } from '../../store/complex.store'; import { ConsumerStore } from '../../store/consumer.store'; @@ -54,41 +51,9 @@ export class SuperAdminUserComplexComponent { setBreadcrumb() { this.breadcrumbService.setItems([ - { - ...superAdminConsumersNamedRoutes.consumers.meta, - routerLink: superAdminConsumersNamedRoutes.consumers.meta.pagePath!(), - }, - { - 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(), - ), - }, + ...this.consumerStore.breadcrumbItems(), + ...this.businessStore.breadcrumbItems(), + ...this.store.breadcrumbItems(), ]); } } diff --git a/src/app/domains/superAdmin/modules/consumers/views/poses/list.component.ts b/src/app/domains/superAdmin/modules/consumers/views/poses/list.component.ts index b8f594d..72158c8 100644 --- a/src/app/domains/superAdmin/modules/consumers/views/poses/list.component.ts +++ b/src/app/domains/superAdmin/modules/consumers/views/poses/list.component.ts @@ -4,9 +4,6 @@ import pageParamsUtils from '@/utils/page-params.utils'; import { Component, computed, inject, signal } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; 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 { BusinessActivityStore } from '../../store/businessActivity.store'; import { ComplexStore } from '../../store/complex.store'; @@ -35,43 +32,9 @@ export class SuperAdminUserPosesComponent { setBreadcrumb() { this.breadcrumbService.setItems([ - { - ...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, - 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(), - ), - }, - + ...this.consumerStore.breadcrumbItems(), + ...this.businessStore.breadcrumbItems(), + ...this.complexStore.breadcrumbItems(), { title: superAdminConsumerPosesNamedRoutes.poses.meta.title, routerLink: superAdminConsumerPosesNamedRoutes.poses.meta.pagePath!( diff --git a/src/app/domains/superAdmin/modules/consumers/views/poses/single.component.ts b/src/app/domains/superAdmin/modules/consumers/views/poses/single.component.ts index fb43d81..c17d825 100644 --- a/src/app/domains/superAdmin/modules/consumers/views/poses/single.component.ts +++ b/src/app/domains/superAdmin/modules/consumers/views/poses/single.component.ts @@ -4,10 +4,6 @@ import pageParamsUtils from '@/utils/page-params.utils'; import { Component, computed, effect, inject, signal } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; 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 { ComplexStore } from '../../store/complex.store'; import { ConsumerStore } from '../../store/consumer.store'; @@ -46,72 +42,15 @@ export class SuperAdminUserPosComponent { readonly pos = computed(() => this.store.entity()); getData() { - this.store.getData(this.businessId(), this.complexId(), this.posId()); - } - - toPosLanding() { - // @ts-ignore - window.cookieStore.set('posId', this.posId()); - // window.open('pos') + this.store.getData(this.consumerId(), this.businessId(), this.complexId(), this.posId()); } setBreadcrumb() { this.breadcrumbService.setItems([ - { - ...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, - 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(), - ), - }, + ...this.consumerStore.breadcrumbItems(), + ...this.businessStore.breadcrumbItems(), + ...this.complexStore.breadcrumbItems(), + ...this.store.breadcrumbItems(), ]); } } diff --git a/src/app/domains/superAdmin/modules/consumers/views/single.component.ts b/src/app/domains/superAdmin/modules/consumers/views/single.component.ts index 7d9fb58..4af750a 100644 --- a/src/app/domains/superAdmin/modules/consumers/views/single.component.ts +++ b/src/app/domains/superAdmin/modules/consumers/views/single.component.ts @@ -9,7 +9,6 @@ import { ConsumerAccountListComponent } from '../components/accounts/list.compon import { ConsumerBusinessActivitiesComponent } from '../components/businessActivities/list.component'; import { ConsumerUserFormComponent } from '../components/form.component'; import { ConsumerLicenseFormComponent } from '../components/licenses/form.component'; -import { superAdminConsumersNamedRoutes } from '../constants'; import { ConsumerStore } from '../store/consumer.store'; @Component({ @@ -62,16 +61,7 @@ export class ConsumerComponent { } setBreadcrumb() { - this.breadcrumbService.setItems([ - { - ...superAdminConsumersNamedRoutes.consumers.meta, - routerLink: superAdminConsumersNamedRoutes.consumers.meta.pagePath!(), - }, - { - title: this.consumer()?.fullname, - routerLink: superAdminConsumersNamedRoutes.consumer.meta.pagePath!(this.consumerId()), - }, - ]); + this.breadcrumbService.setItems(this.store.breadcrumbItems()); } openLicenseForm() { diff --git a/src/app/domains/superAdmin/modules/guilds/store/guild.store.ts b/src/app/domains/superAdmin/modules/guilds/store/guild.store.ts index 9156e2e..ce1377a 100644 --- a/src/app/domains/superAdmin/modules/guilds/store/guild.store.ts +++ b/src/app/domains/superAdmin/modules/guilds/store/guild.store.ts @@ -1,6 +1,6 @@ import { EntityState, EntityStore } from '@/core/state'; import { inject, Injectable } from '@angular/core'; -import { catchError, finalize, throwError } from 'rxjs'; +import { catchError, finalize } from 'rxjs'; import { IGuildResponse } from '../models'; import { GuildsService } from '../services/main.service'; @@ -29,11 +29,9 @@ export class GuildStore extends EntityStore { finalize(() => { this.patchState({ loading: false }); }), - catchError(() => { - this.patchState({ - error: '', - }); - return throwError(''); + catchError((error) => { + this.setError(error); + throw error; }), ) .subscribe((entity) => { diff --git a/src/app/domains/superAdmin/modules/guilds/views/single.component.html b/src/app/domains/superAdmin/modules/guilds/views/single.component.html index c5d29aa..3c9235f 100644 --- a/src/app/domains/superAdmin/modules/guilds/views/single.component.html +++ b/src/app/domains/superAdmin/modules/guilds/views/single.component.html @@ -8,8 +8,12 @@ - - +
+ +
+
+ +
{ finalize(() => { this.patchState({ loading: false }); }), - catchError(() => { - this.patchState({ - error: '', - }); - return throwError(''); + catchError((error) => { + this.setError(error); + throw error; }), ) .subscribe((entity) => { diff --git a/src/app/domains/superAdmin/modules/users/store/user.store.ts b/src/app/domains/superAdmin/modules/users/store/user.store.ts index da12bf5..1dbaa34 100644 --- a/src/app/domains/superAdmin/modules/users/store/user.store.ts +++ b/src/app/domains/superAdmin/modules/users/store/user.store.ts @@ -1,6 +1,6 @@ import { EntityState, EntityStore } from '@/core/state'; import { inject, Injectable } from '@angular/core'; -import { catchError, finalize, throwError } from 'rxjs'; +import { catchError, finalize } from 'rxjs'; import { IUserResponse } from '../models'; import { UsersService } from '../services/main.service'; @@ -29,11 +29,9 @@ export class UserStore extends EntityStore { finalize(() => { this.patchState({ loading: false }); }), - catchError(() => { - this.patchState({ - error: '', - }); - return throwError(''); + catchError((error) => { + this.setError(error); + throw error; }), ) .subscribe((entity) => { diff --git a/src/app/layout/default/app.layout.component.html b/src/app/layout/default/app.layout.component.html index 92605fc..c890d5b 100644 --- a/src/app/layout/default/app.layout.component.html +++ b/src/app/layout/default/app.layout.component.html @@ -3,14 +3,14 @@ @if (fullLoading) { -
+
} @else { @if (showMenu()) { } -
+
@if (showBreadcrumb) { diff --git a/src/app/layout/default/app.topbar.component.html b/src/app/layout/default/app.topbar.component.html index c1655b9..0dcf4e0 100644 --- a/src/app/layout/default/app.topbar.component.html +++ b/src/app/layout/default/app.topbar.component.html @@ -1,4 +1,4 @@ -
+
@if (showMenu) {