From 20be6534998e685b19506354ea61083cd047a94c Mon Sep 17 00:00:00 2001 From: ahasani194 Date: Sat, 14 Mar 2026 16:26:22 +0330 Subject: [PATCH] update superAdmin users business --- src/app/core/constants/menuItems.const.ts | 66 +++-------- src/app/core/models/namedRoutes.model.ts | 2 +- src/app/core/models/summary.ts | 2 +- src/app/core/services/breadcrumb.service.ts | 4 +- src/app/core/state/base-store.ts | 11 ++ src/app/core/validators/password.validator.ts | 3 +- .../components/form.component.html | 13 ++ .../deviceBrands/components/form.component.ts | 44 +++++++ .../deviceBrands/constants/apiRoutes/index.ts | 6 + .../deviceBrands/constants/index.ts | 2 + .../deviceBrands/constants/routes/index.ts | 17 +++ .../superAdmin/deviceBrands/models/index.ts | 1 + .../superAdmin/deviceBrands/models/io.d.ts | 9 ++ .../deviceBrands/services/main.service.ts | 28 +++++ .../superAdmin/deviceBrands/views/index.ts | 1 + .../deviceBrands/views/list.component.html | 21 ++++ .../deviceBrands/views/list.component.ts | 36 ++++++ .../devices/components/form.component.html | 14 +++ .../devices/components/form.component.ts | 52 ++++++++ .../devices/constants/apiRoutes/index.ts | 6 + .../superAdmin/devices/constants/index.ts | 2 + .../devices/constants/routes/index.ts | 17 +++ .../superAdmin/devices/models/index.ts | 1 + .../domains/superAdmin/devices/models/io.d.ts | 13 ++ .../devices/services/main.service.ts | 28 +++++ .../domains/superAdmin/devices/views/index.ts | 1 + .../devices/views/list.component.html | 21 ++++ .../devices/views/list.component.ts | 37 ++++++ .../guilds/components/form.component.html | 2 +- .../partners/components/form.component.html | 12 +- .../partners/components/form.component.ts | 19 ++- .../partners/components/layout.component.html | 5 + .../partners/components/layout.component.ts | 50 ++++++++ .../partners/constants/routes/index.ts | 22 +++- .../superAdmin/partners/models/io.d.ts | 3 + .../partners/store/partner.store.ts | 43 +++++++ .../partners/views/list.component.html | 25 ++-- .../partners/views/list.component.ts | 8 ++ .../partners/views/single.component.html | 22 +++- .../partners/views/single.component.ts | 20 +++- .../providers/components/form.component.html | 4 +- .../providers/components/form.component.ts | 20 +++- .../providers/views/list.component.html | 22 ++-- src/app/domains/superAdmin/routes.ts | 4 + .../components/accounts/form.component.ts | 6 +- .../components/accounts/list.component.html | 9 +- .../businessActivities/form.component.html | 14 +++ .../businessActivities/form.component.ts | 57 +++++++++ .../businessActivities/layout.component.html | 5 + .../businessActivities/layout.component.ts | 33 ++++++ .../businessActivities/list.component.html | 25 ++++ .../businessActivities/list.component.ts | 52 ++++++++ .../components/complexes/form.component.html | 15 +++ .../components/complexes/form.component.ts | 51 ++++++++ .../complexes/layout.component.html | 5 + .../components/complexes/layout.component.ts | 30 +++++ .../components/complexes/list.component.html | 26 ++++ .../components/complexes/list.component.ts | 53 +++++++++ .../users/components/form.component.html | 2 +- .../users/components/form.component.ts | 22 ++-- .../users/components/layout.component.html | 5 + .../users/components/layout.component.ts | 30 +++++ .../components/poses/form.component.html | 20 ++++ .../users/components/poses/form.component.ts | 89 ++++++++++++++ .../components/poses/layout.component.html | 5 + .../components/poses/layout.component.ts | 31 +++++ .../components/poses/list.component.html | 27 +++++ .../users/components/poses/list.component.ts | 60 ++++++++++ .../constants/apiRoutes/businessActivities.ts | 7 ++ .../apiRoutes/businessActivityComplexes.ts | 9 ++ .../users/constants/apiRoutes/complexPoses.ts | 9 ++ .../users/constants/apiRoutes/index.ts | 4 + .../users/constants/apiRoutes/posAccounts.ts | 8 ++ .../users/constants/routes/accounts.ts | 52 ++++++++ .../constants/routes/businessActivities.ts | 52 ++++++++ .../users/constants/routes/complexes.ts | 54 +++++++++ .../users/constants/routes/index.ts | 17 ++- .../users/constants/routes/poses.ts | 49 ++++++++ .../superAdmin/users/models/accounts_io.d.ts | 2 +- .../users/models/businessActivities_io.d.ts | 13 ++ .../superAdmin/users/models/complexes_io.d.ts | 13 ++ .../domains/superAdmin/users/models/index.ts | 3 + .../superAdmin/users/models/poses_io.d.ts | 24 ++++ .../services/businessActivities.service.ts | 45 +++++++ .../users/services/complexes.service.ts | 54 +++++++++ .../users/services/posAccounts.service.ts | 38 ++++++ .../users/services/poses.service.ts | 54 +++++++++ .../users/store/businessActivity.store.ts | 56 +++++++++ .../superAdmin/users/store/complex.store.ts | 53 +++++++++ .../superAdmin/users/store/pos.store.ts | 53 +++++++++ .../users/views/businessActivities/index.ts | 1 + .../businessActivities/list.component.html | 1 + .../businessActivities/list.component.ts | 43 +++++++ .../businessActivities/single.component.html | 21 ++++ .../businessActivities/single.component.ts | 76 ++++++++++++ .../superAdmin/users/views/complexes/index.ts | 1 + .../users/views/complexes/list.component.html | 1 + .../users/views/complexes/list.component.ts | 64 ++++++++++ .../views/complexes/single.component.html | 23 ++++ .../users/views/complexes/single.component.ts | 90 ++++++++++++++ .../superAdmin/users/views/poses/index.ts | 1 + .../users/views/poses/list.component.html | 1 + .../users/views/poses/list.component.ts | 86 ++++++++++++++ .../users/views/poses/single.component.html | 20 ++++ .../users/views/poses/single.component.ts | 112 ++++++++++++++++++ .../users/views/single.component.html | 1 + .../users/views/single.component.ts | 19 +-- src/app/shared/catalog/apiRoutes.ts | 8 ++ .../components/select.component.ts | 34 ++++++ src/app/shared/catalog/deviceBrands/index.ts | 1 + .../devices/components/select.component.ts | 34 ++++++ src/app/shared/catalog/devices/index.ts | 1 + .../guild/components/select.component.html | 13 ++ .../guild/components/select.component.ts | 30 +++++ src/app/shared/catalog/guild/index.ts | 1 + src/app/shared/catalog/index.ts | 3 + .../providers/components/select.component.ts | 34 ++++++ src/app/shared/catalog/providers/index.ts | 1 + src/app/shared/catalog/service.ts | 29 +++++ src/app/shared/catalog/template.html | 13 ++ .../components/input/input.component.html | 76 ++++++------ .../components/input/input.component.ts | 109 ++++++++++++++--- .../page-data-list.component.html | 7 +- .../pageDataList/page-data-list.component.ts | 5 +- src/app/utils/index.ts | 1 + src/app/utils/page-params.utils.ts | 19 +++ 126 files changed, 2891 insertions(+), 169 deletions(-) create mode 100644 src/app/domains/superAdmin/deviceBrands/components/form.component.html create mode 100644 src/app/domains/superAdmin/deviceBrands/components/form.component.ts create mode 100644 src/app/domains/superAdmin/deviceBrands/constants/apiRoutes/index.ts create mode 100644 src/app/domains/superAdmin/deviceBrands/constants/index.ts create mode 100644 src/app/domains/superAdmin/deviceBrands/constants/routes/index.ts create mode 100644 src/app/domains/superAdmin/deviceBrands/models/index.ts create mode 100644 src/app/domains/superAdmin/deviceBrands/models/io.d.ts create mode 100644 src/app/domains/superAdmin/deviceBrands/services/main.service.ts create mode 100644 src/app/domains/superAdmin/deviceBrands/views/index.ts create mode 100644 src/app/domains/superAdmin/deviceBrands/views/list.component.html create mode 100644 src/app/domains/superAdmin/deviceBrands/views/list.component.ts create mode 100644 src/app/domains/superAdmin/devices/components/form.component.html create mode 100644 src/app/domains/superAdmin/devices/components/form.component.ts create mode 100644 src/app/domains/superAdmin/devices/constants/apiRoutes/index.ts create mode 100644 src/app/domains/superAdmin/devices/constants/index.ts create mode 100644 src/app/domains/superAdmin/devices/constants/routes/index.ts create mode 100644 src/app/domains/superAdmin/devices/models/index.ts create mode 100644 src/app/domains/superAdmin/devices/models/io.d.ts create mode 100644 src/app/domains/superAdmin/devices/services/main.service.ts create mode 100644 src/app/domains/superAdmin/devices/views/index.ts create mode 100644 src/app/domains/superAdmin/devices/views/list.component.html create mode 100644 src/app/domains/superAdmin/devices/views/list.component.ts create mode 100644 src/app/domains/superAdmin/partners/components/layout.component.html create mode 100644 src/app/domains/superAdmin/partners/components/layout.component.ts create mode 100644 src/app/domains/superAdmin/partners/store/partner.store.ts create mode 100644 src/app/domains/superAdmin/users/components/businessActivities/form.component.html create mode 100644 src/app/domains/superAdmin/users/components/businessActivities/form.component.ts create mode 100644 src/app/domains/superAdmin/users/components/businessActivities/layout.component.html create mode 100644 src/app/domains/superAdmin/users/components/businessActivities/layout.component.ts create mode 100644 src/app/domains/superAdmin/users/components/businessActivities/list.component.html create mode 100644 src/app/domains/superAdmin/users/components/businessActivities/list.component.ts create mode 100644 src/app/domains/superAdmin/users/components/complexes/form.component.html create mode 100644 src/app/domains/superAdmin/users/components/complexes/form.component.ts create mode 100644 src/app/domains/superAdmin/users/components/complexes/layout.component.html create mode 100644 src/app/domains/superAdmin/users/components/complexes/layout.component.ts create mode 100644 src/app/domains/superAdmin/users/components/complexes/list.component.html create mode 100644 src/app/domains/superAdmin/users/components/complexes/list.component.ts create mode 100644 src/app/domains/superAdmin/users/components/layout.component.html create mode 100644 src/app/domains/superAdmin/users/components/layout.component.ts create mode 100644 src/app/domains/superAdmin/users/components/poses/form.component.html create mode 100644 src/app/domains/superAdmin/users/components/poses/form.component.ts create mode 100644 src/app/domains/superAdmin/users/components/poses/layout.component.html create mode 100644 src/app/domains/superAdmin/users/components/poses/layout.component.ts create mode 100644 src/app/domains/superAdmin/users/components/poses/list.component.html create mode 100644 src/app/domains/superAdmin/users/components/poses/list.component.ts create mode 100644 src/app/domains/superAdmin/users/constants/apiRoutes/businessActivities.ts create mode 100644 src/app/domains/superAdmin/users/constants/apiRoutes/businessActivityComplexes.ts create mode 100644 src/app/domains/superAdmin/users/constants/apiRoutes/complexPoses.ts create mode 100644 src/app/domains/superAdmin/users/constants/apiRoutes/posAccounts.ts create mode 100644 src/app/domains/superAdmin/users/constants/routes/accounts.ts create mode 100644 src/app/domains/superAdmin/users/constants/routes/businessActivities.ts create mode 100644 src/app/domains/superAdmin/users/constants/routes/complexes.ts create mode 100644 src/app/domains/superAdmin/users/constants/routes/poses.ts create mode 100644 src/app/domains/superAdmin/users/models/businessActivities_io.d.ts create mode 100644 src/app/domains/superAdmin/users/models/complexes_io.d.ts create mode 100644 src/app/domains/superAdmin/users/models/poses_io.d.ts create mode 100644 src/app/domains/superAdmin/users/services/businessActivities.service.ts create mode 100644 src/app/domains/superAdmin/users/services/complexes.service.ts create mode 100644 src/app/domains/superAdmin/users/services/posAccounts.service.ts create mode 100644 src/app/domains/superAdmin/users/services/poses.service.ts create mode 100644 src/app/domains/superAdmin/users/store/businessActivity.store.ts create mode 100644 src/app/domains/superAdmin/users/store/complex.store.ts create mode 100644 src/app/domains/superAdmin/users/store/pos.store.ts create mode 100644 src/app/domains/superAdmin/users/views/businessActivities/index.ts create mode 100644 src/app/domains/superAdmin/users/views/businessActivities/list.component.html create mode 100644 src/app/domains/superAdmin/users/views/businessActivities/list.component.ts create mode 100644 src/app/domains/superAdmin/users/views/businessActivities/single.component.html create mode 100644 src/app/domains/superAdmin/users/views/businessActivities/single.component.ts create mode 100644 src/app/domains/superAdmin/users/views/complexes/index.ts create mode 100644 src/app/domains/superAdmin/users/views/complexes/list.component.html create mode 100644 src/app/domains/superAdmin/users/views/complexes/list.component.ts create mode 100644 src/app/domains/superAdmin/users/views/complexes/single.component.html create mode 100644 src/app/domains/superAdmin/users/views/complexes/single.component.ts create mode 100644 src/app/domains/superAdmin/users/views/poses/index.ts create mode 100644 src/app/domains/superAdmin/users/views/poses/list.component.html create mode 100644 src/app/domains/superAdmin/users/views/poses/list.component.ts create mode 100644 src/app/domains/superAdmin/users/views/poses/single.component.html create mode 100644 src/app/domains/superAdmin/users/views/poses/single.component.ts create mode 100644 src/app/shared/catalog/apiRoutes.ts create mode 100644 src/app/shared/catalog/deviceBrands/components/select.component.ts create mode 100644 src/app/shared/catalog/deviceBrands/index.ts create mode 100644 src/app/shared/catalog/devices/components/select.component.ts create mode 100644 src/app/shared/catalog/devices/index.ts create mode 100644 src/app/shared/catalog/guild/components/select.component.html create mode 100644 src/app/shared/catalog/guild/components/select.component.ts create mode 100644 src/app/shared/catalog/guild/index.ts create mode 100644 src/app/shared/catalog/providers/components/select.component.ts create mode 100644 src/app/shared/catalog/providers/index.ts create mode 100644 src/app/shared/catalog/service.ts create mode 100644 src/app/shared/catalog/template.html create mode 100644 src/app/utils/page-params.utils.ts diff --git a/src/app/core/constants/menuItems.const.ts b/src/app/core/constants/menuItems.const.ts index bc1dab8..36b4f72 100644 --- a/src/app/core/constants/menuItems.const.ts +++ b/src/app/core/constants/menuItems.const.ts @@ -9,58 +9,28 @@ export const MENU_ITEMS = [ }, ], }, - // { - // label: 'انبارها', - // icon: 'pi pi-fw pi-box', - // items: [ - // { - // label: 'لیست انبارها', - // icon: 'pi pi-fw pi-list', - // routerLink: ['/inventories'], - // }, - // ], - // }, - // { - // label: 'کالاها', - // icon: 'pi pi-fw pi-tags', - // items: [ - // { - // label: 'لیست کالاها', - // icon: 'pi pi-fw pi-list', - // routerLink: ['/products'], - // }, - // { - // label: 'برندهای کالا', - // icon: 'pi pi-fw pi-tags', - // routerLink: ['/product-brands'], - // }, - // { - // label: 'دسته‌بندی‌های کالا', - // icon: 'pi pi-fw pi-list', - // routerLink: ['/product-categories'], - // }, - // ], - // }, - // { - // label: 'تامین‌کنندگان', - // icon: 'pi pi-fw pi-users', - // items: [ - // { - // label: 'لیست تامین‌کنندگان', - // icon: 'pi pi-fw pi-list', - // routerLink: ['/suppliers'], - // }, - // ], - // }, + + { + label: 'مدیریت اطلاعات مرجع', + icon: 'pi pi-fw pi-cog', + items: [ + { + label: 'برندهای دستگاه', + icon: 'pi pi-fw pi-list', + routerLink: ['/super_admin/device_brands'], + }, + { + label: 'دستگاه‌ها', + icon: 'pi pi-fw pi-list', + routerLink: ['/super_admin/devices'], + }, + ], + }, + { label: 'مدیریت سیستم', icon: 'pi pi-fw pi-cog', items: [ - // { - // label: 'حساب‌های بانکی', - // icon: 'pi pi-fw pi-credit-card', - // routerLink: ['/bankAccounts'], - // }, { label: 'کاربران', icon: 'pi pi-fw pi-user', diff --git a/src/app/core/models/namedRoutes.model.ts b/src/app/core/models/namedRoutes.model.ts index 2c7b941..3698a5a 100644 --- a/src/app/core/models/namedRoutes.model.ts +++ b/src/app/core/models/namedRoutes.model.ts @@ -19,7 +19,7 @@ export interface RouteInfo { meta: { title: string; icon?: string; - pagePath?: (params?: any) => string; + pagePath?: (...params: any) => string; }; } diff --git a/src/app/core/models/summary.ts b/src/app/core/models/summary.ts index 5818ed0..92a9fc8 100644 --- a/src/app/core/models/summary.ts +++ b/src/app/core/models/summary.ts @@ -1,4 +1,4 @@ export default interface ISummary { - id: number; + id: string; name: string; } diff --git a/src/app/core/services/breadcrumb.service.ts b/src/app/core/services/breadcrumb.service.ts index a5c7af6..2887b27 100644 --- a/src/app/core/services/breadcrumb.service.ts +++ b/src/app/core/services/breadcrumb.service.ts @@ -34,7 +34,9 @@ export class BreadcrumbService { })); addItems(items: MenuItem[]) { - this._items.update((value) => ({ ...value, ...this.mapItems(items) })); + this._items.update((value) => { + return [...value, ...this.mapItems(items)]; + }); } clear() { diff --git a/src/app/core/state/base-store.ts b/src/app/core/state/base-store.ts index 580cef0..0ba4feb 100644 --- a/src/app/core/state/base-store.ts +++ b/src/app/core/state/base-store.ts @@ -182,6 +182,17 @@ export abstract class EntityStore< entity, } as Partial); } + override reset(): void { + // @ts-ignore + // @TODO: check to familiar with ts + this.setState({ + loading: false, + error: null, + entity: null, + initialized: false, + isRefreshing: false, + }); + } } /** diff --git a/src/app/core/validators/password.validator.ts b/src/app/core/validators/password.validator.ts index f0760e9..ed520a4 100644 --- a/src/app/core/validators/password.validator.ts +++ b/src/app/core/validators/password.validator.ts @@ -2,7 +2,8 @@ import { ValidatorFn } from '@angular/forms'; // Password must be minimum 8 characters, include at least one uppercase, // one lowercase, one number and one special character -export const PASSWORD_PATTERN = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^A-Za-z0-9]).{8,}$/; +// export const PASSWORD_PATTERN = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^A-Za-z0-9]).{8,}$/; +export const PASSWORD_PATTERN = /^[0-9]{6,}$/; // Validator factory named `password` as requested. Returns `null` for empty // values so `Validators.required` can be used alongside it when needed. diff --git a/src/app/domains/superAdmin/deviceBrands/components/form.component.html b/src/app/domains/superAdmin/deviceBrands/components/form.component.html new file mode 100644 index 0000000..ad9ed30 --- /dev/null +++ b/src/app/domains/superAdmin/deviceBrands/components/form.component.html @@ -0,0 +1,13 @@ + +
+ + + +
diff --git a/src/app/domains/superAdmin/deviceBrands/components/form.component.ts b/src/app/domains/superAdmin/deviceBrands/components/form.component.ts new file mode 100644 index 0000000..0663180 --- /dev/null +++ b/src/app/domains/superAdmin/deviceBrands/components/form.component.ts @@ -0,0 +1,44 @@ +import { AbstractFormDialog } from '@/shared/abstractClasses'; +import { InputComponent } from '@/shared/components'; +import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component'; +import { Component, computed, inject, Input } from '@angular/core'; +import { ReactiveFormsModule, Validators } from '@angular/forms'; +import { Dialog } from 'primeng/dialog'; +import { IDeviceBrandRequest, IDeviceBrandResponse } from '../models'; +import { DeviceBrandsService } from '../services/main.service'; + +@Component({ + selector: 'deviceBrand-form', + templateUrl: './form.component.html', + imports: [ReactiveFormsModule, Dialog, InputComponent, FormFooterActionsComponent], +}) +export class DeviceBrandFormComponent extends AbstractFormDialog< + IDeviceBrandRequest, + IDeviceBrandResponse +> { + @Input() brandId?: string; + private service = inject(DeviceBrandsService); + + form = this.fb.group({ + name: this.fb.control(this.initialValues?.name || '', { + nonNullable: true, + validators: [Validators.required], + }), + }); + + preparedTitle = computed(() => `${this.editMode ? 'ویرایش' : 'ایجاد'} برند دستگاه`); + + override ngOnChanges() { + this.form.patchValue(this.initialValues ?? {}); + if (this.editMode && !this.brandId) { + throw 'missing some arguments'; + } + } + + override submitForm(payload: IDeviceBrandRequest) { + if (this.editMode) { + return this.service.update(this.brandId!, payload); + } + return this.service.create(payload); + } +} diff --git a/src/app/domains/superAdmin/deviceBrands/constants/apiRoutes/index.ts b/src/app/domains/superAdmin/deviceBrands/constants/apiRoutes/index.ts new file mode 100644 index 0000000..ebd9624 --- /dev/null +++ b/src/app/domains/superAdmin/deviceBrands/constants/apiRoutes/index.ts @@ -0,0 +1,6 @@ +const baseUrl = '/api/v1/admin/device_brands'; + +export const DEVICE_BRANDS_API_ROUTES = { + list: () => `${baseUrl}`, + single: (id: string) => `${baseUrl}/${id}`, +}; diff --git a/src/app/domains/superAdmin/deviceBrands/constants/index.ts b/src/app/domains/superAdmin/deviceBrands/constants/index.ts new file mode 100644 index 0000000..ee61bd7 --- /dev/null +++ b/src/app/domains/superAdmin/deviceBrands/constants/index.ts @@ -0,0 +1,2 @@ +export * from './apiRoutes'; +export * from './routes'; diff --git a/src/app/domains/superAdmin/deviceBrands/constants/routes/index.ts b/src/app/domains/superAdmin/deviceBrands/constants/routes/index.ts new file mode 100644 index 0000000..1f11faf --- /dev/null +++ b/src/app/domains/superAdmin/deviceBrands/constants/routes/index.ts @@ -0,0 +1,17 @@ +import { NamedRoutes } from '@/core'; +import { Routes } from '@angular/router'; + +export type TDeviceBrandsRouteNames = 'deviceBrands'; + +export const deviceBrandsNamedRoutes: NamedRoutes = { + deviceBrands: { + path: 'device_brands', + loadComponent: () => import('../../views/list.component').then((m) => m.DeviceBrandsComponent), + meta: { + title: 'برندها', + pagePath: () => '/super_admin/deviceBrands', + }, + }, +}; + +export const DEVICE_BRANDS_ROUTES: Routes = Object.values(deviceBrandsNamedRoutes); diff --git a/src/app/domains/superAdmin/deviceBrands/models/index.ts b/src/app/domains/superAdmin/deviceBrands/models/index.ts new file mode 100644 index 0000000..61a518a --- /dev/null +++ b/src/app/domains/superAdmin/deviceBrands/models/index.ts @@ -0,0 +1 @@ +export * from './io'; diff --git a/src/app/domains/superAdmin/deviceBrands/models/io.d.ts b/src/app/domains/superAdmin/deviceBrands/models/io.d.ts new file mode 100644 index 0000000..32b343b --- /dev/null +++ b/src/app/domains/superAdmin/deviceBrands/models/io.d.ts @@ -0,0 +1,9 @@ +export interface IDeviceBrandRawResponse { + id: string; + name: string; +} +export interface IDeviceBrandResponse extends IDeviceBrandRawResponse {} + +export interface IDeviceBrandRequest { + name: string; +} diff --git a/src/app/domains/superAdmin/deviceBrands/services/main.service.ts b/src/app/domains/superAdmin/deviceBrands/services/main.service.ts new file mode 100644 index 0000000..14041a1 --- /dev/null +++ b/src/app/domains/superAdmin/deviceBrands/services/main.service.ts @@ -0,0 +1,28 @@ +import { IPaginatedResponse } from '@/core/models/service.model'; +import { HttpClient } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; +import { DEVICE_BRANDS_API_ROUTES } from '../constants'; +import { IDeviceBrandRawResponse, IDeviceBrandRequest, IDeviceBrandResponse } from '../models'; + +@Injectable({ providedIn: 'root' }) +export class DeviceBrandsService { + constructor(private http: HttpClient) {} + + private apiRoutes = DEVICE_BRANDS_API_ROUTES; + + getAll(): Observable> { + return this.http.get>(this.apiRoutes.list()); + } + // getSingle(userId: string): Observable { + // return this.http.get(this.apiRoutes.single(userId)); + // } + + create(userData: IDeviceBrandRequest): Observable { + return this.http.post(this.apiRoutes.list(), userData); + } + + update(userId: string, userData: IDeviceBrandRequest): Observable { + return this.http.patch(this.apiRoutes.single(userId), userData); + } +} diff --git a/src/app/domains/superAdmin/deviceBrands/views/index.ts b/src/app/domains/superAdmin/deviceBrands/views/index.ts new file mode 100644 index 0000000..576a89e --- /dev/null +++ b/src/app/domains/superAdmin/deviceBrands/views/index.ts @@ -0,0 +1 @@ +export * from './list.component'; diff --git a/src/app/domains/superAdmin/deviceBrands/views/list.component.html b/src/app/domains/superAdmin/deviceBrands/views/list.component.html new file mode 100644 index 0000000..f862afd --- /dev/null +++ b/src/app/domains/superAdmin/deviceBrands/views/list.component.html @@ -0,0 +1,21 @@ + + diff --git a/src/app/domains/superAdmin/deviceBrands/views/list.component.ts b/src/app/domains/superAdmin/deviceBrands/views/list.component.ts new file mode 100644 index 0000000..a01a6de --- /dev/null +++ b/src/app/domains/superAdmin/deviceBrands/views/list.component.ts @@ -0,0 +1,36 @@ +// import { CatalogRoleTagComponent } from '@/shared/catalog/roles'; +import { AbstractList } from '@/shared/abstractClasses/abstract-list'; +import { PageDataListComponent } from '@/shared/components/pageDataList/page-data-list.component'; +import { Component, inject } from '@angular/core'; +import { DeviceBrandFormComponent } from '../components/form.component'; +import { IDeviceBrandResponse } from '../models'; +import { DeviceBrandsService } from '../services/main.service'; + +@Component({ + selector: 'superAdmin-deviceBrands', + templateUrl: './list.component.html', + imports: [PageDataListComponent, DeviceBrandFormComponent], +}) +export class DeviceBrandsComponent extends AbstractList { + private readonly service = inject(DeviceBrandsService); + + override setColumns(): void { + this.columns = [ + { field: 'id', header: 'شناسه' }, + { field: 'name', header: 'عنوان' }, + { + field: 'created_at', + header: 'تاریخ ایجاد', + type: 'date', + }, + ]; + } + + override getDataRequest() { + return this.service.getAll(); + } + + // toSinglePage(partner: IDeviceBrandResponse) { + // this.router.navigateByUrl(partnersNamedRoutes.partner.meta.pagePath!(partner.id)); + // } +} diff --git a/src/app/domains/superAdmin/devices/components/form.component.html b/src/app/domains/superAdmin/devices/components/form.component.html new file mode 100644 index 0000000..15586bd --- /dev/null +++ b/src/app/domains/superAdmin/devices/components/form.component.html @@ -0,0 +1,14 @@ + +
+ + + + +
diff --git a/src/app/domains/superAdmin/devices/components/form.component.ts b/src/app/domains/superAdmin/devices/components/form.component.ts new file mode 100644 index 0000000..5fa4c80 --- /dev/null +++ b/src/app/domains/superAdmin/devices/components/form.component.ts @@ -0,0 +1,52 @@ +// import { CatalogRolesComponent } from '@/shared/catalog/roles'; +import { AbstractFormDialog } from '@/shared/abstractClasses'; +import { CatalogDeviceBrandSelectComponent } from '@/shared/catalog/deviceBrands'; +import { InputComponent } from '@/shared/components'; +import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component'; +import { Component, inject, Input } from '@angular/core'; +import { ReactiveFormsModule, Validators } from '@angular/forms'; +import { Dialog } from 'primeng/dialog'; +import { IDeviceRequest, IDeviceResponse } from '../models'; +import { SuperAdminDeviceService } from '../services/main.service'; + +@Component({ + selector: 'superAdmin-device-form', + templateUrl: './form.component.html', + imports: [ + ReactiveFormsModule, + Dialog, + InputComponent, + FormFooterActionsComponent, + CatalogDeviceBrandSelectComponent, + ], +}) +export class UserComplexFormComponent extends AbstractFormDialog { + private readonly service = inject(SuperAdminDeviceService); + + @Input() deviceId?: string; + + initForm = () => { + return this.fb.group({ + name: [this.initialValues?.name || '', [Validators.required]], + brand_id: [this.initialValues?.brand.id || '', [Validators.required]], + }); + }; + + form = this.initForm(); + + get preparedTitle() { + return `${this.editMode ? 'ویرایش' : 'ایجاد'} دستگاه`; + } + + override ngOnChanges(): void { + this.form = this.initForm(); + } + + submitForm() { + const formValue = this.form.value as IDeviceRequest; + if (this.editMode) { + return this.service.update(this.deviceId!, formValue); + } + return this.service.create(formValue); + } +} diff --git a/src/app/domains/superAdmin/devices/constants/apiRoutes/index.ts b/src/app/domains/superAdmin/devices/constants/apiRoutes/index.ts new file mode 100644 index 0000000..e304e66 --- /dev/null +++ b/src/app/domains/superAdmin/devices/constants/apiRoutes/index.ts @@ -0,0 +1,6 @@ +const baseUrl = '/api/v1/admin/devices'; + +export const DEVICES_API_ROUTES = { + list: () => `${baseUrl}`, + single: (id: string) => `${baseUrl}/${id}`, +}; diff --git a/src/app/domains/superAdmin/devices/constants/index.ts b/src/app/domains/superAdmin/devices/constants/index.ts new file mode 100644 index 0000000..ee61bd7 --- /dev/null +++ b/src/app/domains/superAdmin/devices/constants/index.ts @@ -0,0 +1,2 @@ +export * from './apiRoutes'; +export * from './routes'; diff --git a/src/app/domains/superAdmin/devices/constants/routes/index.ts b/src/app/domains/superAdmin/devices/constants/routes/index.ts new file mode 100644 index 0000000..afcc135 --- /dev/null +++ b/src/app/domains/superAdmin/devices/constants/routes/index.ts @@ -0,0 +1,17 @@ +import { NamedRoutes } from '@/core'; +import { Routes } from '@angular/router'; + +export type TDevicesRouteNames = 'devices'; + +export const devicesRoutes: NamedRoutes = { + devices: { + path: 'devices', + loadComponent: () => import('../../views/list.component').then((m) => m.DevicesComponent), + meta: { + title: 'دستگاه‌ها', + pagePath: () => '/super_admin/devices', + }, + }, +}; + +export const DEVICES_ROUTES: Routes = Object.values(devicesRoutes); diff --git a/src/app/domains/superAdmin/devices/models/index.ts b/src/app/domains/superAdmin/devices/models/index.ts new file mode 100644 index 0000000..61a518a --- /dev/null +++ b/src/app/domains/superAdmin/devices/models/index.ts @@ -0,0 +1 @@ +export * from './io'; diff --git a/src/app/domains/superAdmin/devices/models/io.d.ts b/src/app/domains/superAdmin/devices/models/io.d.ts new file mode 100644 index 0000000..b458c0c --- /dev/null +++ b/src/app/domains/superAdmin/devices/models/io.d.ts @@ -0,0 +1,13 @@ +import ISummary from '@/core/models/summary'; + +export interface IDeviceRawResponse { + id: string; + name: string; + brand: ISummary; +} +export interface IDeviceResponse extends IDeviceRawResponse {} + +export interface IDeviceRequest { + name: string; + brand_id: string; +} diff --git a/src/app/domains/superAdmin/devices/services/main.service.ts b/src/app/domains/superAdmin/devices/services/main.service.ts new file mode 100644 index 0000000..59793eb --- /dev/null +++ b/src/app/domains/superAdmin/devices/services/main.service.ts @@ -0,0 +1,28 @@ +import { IPaginatedResponse } from '@/core/models/service.model'; +import { HttpClient } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; +import { DEVICES_API_ROUTES } from '../constants'; +import { IDeviceRawResponse, IDeviceRequest, IDeviceResponse } from '../models'; + +@Injectable({ providedIn: 'root' }) +export class SuperAdminDeviceService { + constructor(private http: HttpClient) {} + + private apiRoutes = DEVICES_API_ROUTES; + + getAll(): Observable> { + return this.http.get>(this.apiRoutes.list()); + } + // getSingle(userId: string): Observable { + // return this.http.get(this.apiRoutes.single(userId)); + // } + + create(userData: IDeviceRequest): Observable { + return this.http.post(this.apiRoutes.list(), userData); + } + + update(userId: string, userData: IDeviceRequest): Observable { + return this.http.patch(this.apiRoutes.single(userId), userData); + } +} diff --git a/src/app/domains/superAdmin/devices/views/index.ts b/src/app/domains/superAdmin/devices/views/index.ts new file mode 100644 index 0000000..576a89e --- /dev/null +++ b/src/app/domains/superAdmin/devices/views/index.ts @@ -0,0 +1 @@ +export * from './list.component'; diff --git a/src/app/domains/superAdmin/devices/views/list.component.html b/src/app/domains/superAdmin/devices/views/list.component.html new file mode 100644 index 0000000..eebe308 --- /dev/null +++ b/src/app/domains/superAdmin/devices/views/list.component.html @@ -0,0 +1,21 @@ + + diff --git a/src/app/domains/superAdmin/devices/views/list.component.ts b/src/app/domains/superAdmin/devices/views/list.component.ts new file mode 100644 index 0000000..5e502ac --- /dev/null +++ b/src/app/domains/superAdmin/devices/views/list.component.ts @@ -0,0 +1,37 @@ +// import { CatalogRoleTagComponent } from '@/shared/catalog/roles'; +import { AbstractList } from '@/shared/abstractClasses/abstract-list'; +import { PageDataListComponent } from '@/shared/components/pageDataList/page-data-list.component'; +import { Component, inject } from '@angular/core'; +import { UserComplexFormComponent } from '../components/form.component'; +import { IDeviceResponse } from '../models'; +import { SuperAdminDeviceService } from '../services/main.service'; + +@Component({ + selector: 'superAdmin-deviceBrands', + templateUrl: './list.component.html', + imports: [PageDataListComponent, UserComplexFormComponent], +}) +export class DevicesComponent extends AbstractList { + private readonly service = inject(SuperAdminDeviceService); + + override setColumns(): void { + this.columns = [ + { field: 'id', header: 'شناسه' }, + { field: 'name', header: 'عنوان' }, + { field: 'brand', header: 'برند دستگاه', type: 'nested', nestedPath: 'name' }, + { + field: 'created_at', + header: 'تاریخ ایجاد', + type: 'date', + }, + ]; + } + + override getDataRequest() { + return this.service.getAll(); + } + + // toSinglePage(partner: IDeviceBrandResponse) { + // this.router.navigateByUrl(partnersNamedRoutes.partner.meta.pagePath!(partner.id)); + // } +} diff --git a/src/app/domains/superAdmin/guilds/components/form.component.html b/src/app/domains/superAdmin/guilds/components/form.component.html index c901801..b5743da 100644 --- a/src/app/domains/superAdmin/guilds/components/form.component.html +++ b/src/app/domains/superAdmin/guilds/components/form.component.html @@ -3,6 +3,6 @@ - + diff --git a/src/app/domains/superAdmin/partners/components/form.component.html b/src/app/domains/superAdmin/partners/components/form.component.html index 43eda4a..18e95f1 100644 --- a/src/app/domains/superAdmin/partners/components/form.component.html +++ b/src/app/domains/superAdmin/partners/components/form.component.html @@ -1,5 +1,5 @@ - + + diff --git a/src/app/domains/superAdmin/partners/components/form.component.ts b/src/app/domains/superAdmin/partners/components/form.component.ts index c6e1afb..16b7660 100644 --- a/src/app/domains/superAdmin/partners/components/form.component.ts +++ b/src/app/domains/superAdmin/partners/components/form.component.ts @@ -1,7 +1,7 @@ import { AbstractFormDialog } from '@/shared/abstractClasses'; import { InputComponent } from '@/shared/components'; import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component'; -import { Component, inject } from '@angular/core'; +import { Component, computed, inject, Input } from '@angular/core'; import { ReactiveFormsModule, Validators } from '@angular/forms'; import { Dialog } from 'primeng/dialog'; import { IPartnerRequest, IPartnerResponse } from '../models'; @@ -13,6 +13,7 @@ import { PartnersService } from '../services/main.service'; imports: [ReactiveFormsModule, Dialog, InputComponent, FormFooterActionsComponent], }) export class GuildFormComponent extends AbstractFormDialog { + @Input() partnerId?: string; private service = inject(PartnersService); form = this.fb.group({ @@ -24,9 +25,25 @@ export class GuildFormComponent extends AbstractFormDialog(this.initialValues?.license_quota || 0, { + nonNullable: true, + validators: [Validators.required], + }), }); + preparedTitle = computed(() => `${this.editMode ? 'ویرایش' : 'ایجاد'} شریک تجاری`); + + override ngOnChanges() { + this.form.patchValue(this.initialValues ?? {}); + if (this.editMode && !this.partnerId) { + throw 'missing some arguments'; + } + } + override submitForm(payload: IPartnerRequest) { + if (this.editMode) { + return this.service.update(this.partnerId!, payload); + } return this.service.create(payload); } } diff --git a/src/app/domains/superAdmin/partners/components/layout.component.html b/src/app/domains/superAdmin/partners/components/layout.component.html new file mode 100644 index 0000000..5416fe1 --- /dev/null +++ b/src/app/domains/superAdmin/partners/components/layout.component.html @@ -0,0 +1,5 @@ +@if (loading()) { + +} @else { + +} diff --git a/src/app/domains/superAdmin/partners/components/layout.component.ts b/src/app/domains/superAdmin/partners/components/layout.component.ts new file mode 100644 index 0000000..7f335e1 --- /dev/null +++ b/src/app/domains/superAdmin/partners/components/layout.component.ts @@ -0,0 +1,50 @@ +import { BreadcrumbService } from '@/core/services'; +import { PageLoadingComponent } from '@/shared/components/page-loading.component'; +import { Component, computed, effect, inject, signal } from '@angular/core'; +import { ActivatedRoute, RouterOutlet } from '@angular/router'; +import { partnersNamedRoutes } from '../constants'; +import { PartnerStore } from '../store/partner.store'; + +@Component({ + selector: 'superAdmin-guild-layout', + templateUrl: './layout.component.html', + imports: [PageLoadingComponent, RouterOutlet], +}) +export class GuildLayoutComponent { + private readonly store = inject(PartnerStore); + private readonly route = inject(ActivatedRoute); + private readonly breadcrumbService = inject(BreadcrumbService); + + readonly partnerId = signal(this.route.snapshot.paramMap.get('partnerId')!); + + readonly loading = computed(() => this.store.loading()); + readonly partner = computed(() => this.store.entity()); + + constructor() { + effect(() => { + if (this.partner()?.id) { + this.setBreadcrumb(); + } + }); + } + + getData() { + this.store.getData(this.partnerId()); + } + + ngOnInit() { + this.getData(); + } + + setBreadcrumb() { + this.breadcrumbService.setItems([ + { + ...partnersNamedRoutes.partners.meta, + routerLink: partnersNamedRoutes.partners.meta.pagePath!(), + }, + { + title: this.partner()?.name, + }, + ]); + } +} diff --git a/src/app/domains/superAdmin/partners/constants/routes/index.ts b/src/app/domains/superAdmin/partners/constants/routes/index.ts index a2027d8..de3de6d 100644 --- a/src/app/domains/superAdmin/partners/constants/routes/index.ts +++ b/src/app/domains/superAdmin/partners/constants/routes/index.ts @@ -8,7 +8,7 @@ export const partnersNamedRoutes: NamedRoutes = { path: 'partners', loadComponent: () => import('../../views/list.component').then((m) => m.PartnersComponent), meta: { - title: 'کاربران', + title: 'شرکای تجاری', pagePath: () => '/super_admin/partners', }, }, @@ -16,10 +16,24 @@ export const partnersNamedRoutes: NamedRoutes = { path: 'partners/:partnerId', loadComponent: () => import('../../views/single.component').then((m) => m.PartnerComponent), meta: { - title: 'کاربر', - pagePath: () => '/super_admin/partners/:partnerId', + title: 'شریک تجاری', + pagePath: (guildId: string) => `/super_admin/partners/${guildId}`, }, }, }; -export const PARTNERS_ROUTES: Routes = Object.values(partnersNamedRoutes); +export const PARTNERS_ROUTES: Routes = [ + partnersNamedRoutes.partners, + { + path: 'partners/:partnerId', + loadComponent: () => + import('../../components/layout.component').then((m) => m.GuildLayoutComponent), + + children: [ + { + path: '', + loadComponent: () => import('../../views/single.component').then((m) => m.PartnerComponent), + }, + ], + }, +]; diff --git a/src/app/domains/superAdmin/partners/models/io.d.ts b/src/app/domains/superAdmin/partners/models/io.d.ts index bdda44a..91b42f6 100644 --- a/src/app/domains/superAdmin/partners/models/io.d.ts +++ b/src/app/domains/superAdmin/partners/models/io.d.ts @@ -2,10 +2,13 @@ export interface IPartnerRawResponse { id: string; name: string; code: string; + remained_license: number; + license_quota: number; } export interface IPartnerResponse extends IPartnerRawResponse {} export interface IPartnerRequest { name: string; code: string; + license_quota: number; } diff --git a/src/app/domains/superAdmin/partners/store/partner.store.ts b/src/app/domains/superAdmin/partners/store/partner.store.ts new file mode 100644 index 0000000..a930584 --- /dev/null +++ b/src/app/domains/superAdmin/partners/store/partner.store.ts @@ -0,0 +1,43 @@ +import { EntityState, EntityStore } from '@/core/state'; +import { inject, Injectable } from '@angular/core'; +import { catchError, finalize, throwError } from 'rxjs'; +import { IPartnerResponse } from '../models'; +import { PartnersService } from '../services/main.service'; + +interface PartnerState extends EntityState {} + +@Injectable({ + providedIn: 'root', +}) +export class PartnerStore extends EntityStore { + private readonly service = inject(PartnersService); + constructor() { + super({ + loading: false, + error: null, + entity: null, + initialized: false, + isRefreshing: false, + }); + } + + getData(partnerId: string) { + this.patchState({ loading: true }); + this.service + .getSingle(partnerId) + .pipe( + finalize(() => { + this.patchState({ loading: false }); + }), + catchError(() => { + this.patchState({ + error: '', + }); + return throwError(''); + }), + ) + .subscribe((entity) => { + this.patchState({ entity }); + }); + } +} diff --git a/src/app/domains/superAdmin/partners/views/list.component.html b/src/app/domains/superAdmin/partners/views/list.component.html index df60cc1..8590e30 100644 --- a/src/app/domains/superAdmin/partners/views/list.component.html +++ b/src/app/domains/superAdmin/partners/views/list.component.html @@ -1,18 +1,23 @@ - - - + (onDetails)="toSinglePage($event)" + (onEdit)="onEditClick($event)" +/> + diff --git a/src/app/domains/superAdmin/partners/views/list.component.ts b/src/app/domains/superAdmin/partners/views/list.component.ts index 4410599..2012b34 100644 --- a/src/app/domains/superAdmin/partners/views/list.component.ts +++ b/src/app/domains/superAdmin/partners/views/list.component.ts @@ -2,7 +2,9 @@ import { AbstractList } from '@/shared/abstractClasses/abstract-list'; import { PageDataListComponent } from '@/shared/components/pageDataList/page-data-list.component'; import { Component, inject } from '@angular/core'; +import { Router } from '@angular/router'; import { GuildFormComponent } from '../components/form.component'; +import { partnersNamedRoutes } from '../constants'; import { IPartnerResponse } from '../models'; import { PartnersService } from '../services/main.service'; @@ -13,12 +15,14 @@ import { PartnersService } from '../services/main.service'; }) export class PartnersComponent extends AbstractList { private readonly service = inject(PartnersService); + private readonly router = inject(Router); override setColumns(): void { this.columns = [ { field: 'id', header: 'شناسه' }, { field: 'name', header: 'نام' }, { field: 'code', header: 'کد' }, + { field: 'license_quota', header: 'تعداد لایسنس خریداری شده' }, { field: 'created_at', header: 'تاریخ ایجاد', @@ -30,4 +34,8 @@ export class PartnersComponent extends AbstractList { override getDataRequest() { return this.service.getAll(); } + + toSinglePage(partner: IPartnerResponse) { + this.router.navigateByUrl(partnersNamedRoutes.partner.meta.pagePath!(partner.id)); + } } diff --git a/src/app/domains/superAdmin/partners/views/single.component.html b/src/app/domains/superAdmin/partners/views/single.component.html index 7144e26..89b3f4f 100644 --- a/src/app/domains/superAdmin/partners/views/single.component.html +++ b/src/app/domains/superAdmin/partners/views/single.component.html @@ -1 +1,21 @@ -
+
+ + +
+
+ + + + +
+
+
+ + +
diff --git a/src/app/domains/superAdmin/partners/views/single.component.ts b/src/app/domains/superAdmin/partners/views/single.component.ts index 074bbec..70f0a5c 100644 --- a/src/app/domains/superAdmin/partners/views/single.component.ts +++ b/src/app/domains/superAdmin/partners/views/single.component.ts @@ -1,9 +1,25 @@ -import { Component } from '@angular/core'; +import { AppCardComponent, KeyValueComponent } from '@/shared/components'; +import { Component, computed, inject, signal } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { GuildFormComponent } from '../components/form.component'; +import { PartnerStore } from '../store/partner.store'; @Component({ selector: 'app-user', templateUrl: './single.component.html', + imports: [AppCardComponent, KeyValueComponent, GuildFormComponent], }) export class PartnerComponent { - constructor() {} + private readonly store = inject(PartnerStore); + private readonly route = inject(ActivatedRoute); + + readonly partnerId = signal(this.route.snapshot.paramMap.get('partnerId')!); + editMode = signal(false); + + readonly loading = computed(() => this.store.loading()); + readonly partner = computed(() => this.store.entity()); + + getData() { + this.store.getData(this.partnerId()); + } } diff --git a/src/app/domains/superAdmin/providers/components/form.component.html b/src/app/domains/superAdmin/providers/components/form.component.html index c79416b..ad9ed30 100644 --- a/src/app/domains/superAdmin/providers/components/form.component.html +++ b/src/app/domains/superAdmin/providers/components/form.component.html @@ -1,5 +1,5 @@
- +
diff --git a/src/app/domains/superAdmin/providers/components/form.component.ts b/src/app/domains/superAdmin/providers/components/form.component.ts index b6bf7f7..ebe3ddd 100644 --- a/src/app/domains/superAdmin/providers/components/form.component.ts +++ b/src/app/domains/superAdmin/providers/components/form.component.ts @@ -1,7 +1,7 @@ import { AbstractFormDialog } from '@/shared/abstractClasses'; import { InputComponent } from '@/shared/components'; import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component'; -import { Component, inject } from '@angular/core'; +import { Component, computed, inject, Input } from '@angular/core'; import { ReactiveFormsModule, Validators } from '@angular/forms'; import { Dialog } from 'primeng/dialog'; import { IProviderRequest, IProviderResponse } from '../models'; @@ -13,13 +13,29 @@ import { ProvidersService } from '../services/main.service'; imports: [ReactiveFormsModule, Dialog, InputComponent, FormFooterActionsComponent], }) export class GuildFormComponent extends AbstractFormDialog { + @Input() providerId?: string; private service = inject(ProvidersService); form = this.fb.group({ - name: [this.initialValues?.name || '', [Validators.required]], + name: this.fb.control(this.initialValues?.name || '', { + nonNullable: true, + validators: [Validators.required], + }), }); + preparedTitle = computed(() => `${this.editMode ? 'ویرایش' : 'ایجاد'} ارایه‌دهنده`); + + override ngOnChanges() { + this.form.patchValue(this.initialValues ?? {}); + if (this.editMode && !this.providerId) { + throw 'missing some arguments'; + } + } + override submitForm(payload: IProviderRequest) { + if (this.editMode) { + return this.service.update(this.providerId!, payload); + } return this.service.create(payload); } } diff --git a/src/app/domains/superAdmin/providers/views/list.component.html b/src/app/domains/superAdmin/providers/views/list.component.html index 5d15bb2..e6969f9 100644 --- a/src/app/domains/superAdmin/providers/views/list.component.html +++ b/src/app/domains/superAdmin/providers/views/list.component.html @@ -1,18 +1,20 @@ - - - +/> + diff --git a/src/app/domains/superAdmin/routes.ts b/src/app/domains/superAdmin/routes.ts index 4c4a971..9f202e8 100644 --- a/src/app/domains/superAdmin/routes.ts +++ b/src/app/domains/superAdmin/routes.ts @@ -1,4 +1,6 @@ import { Route } from '@angular/router'; +import { DEVICE_BRANDS_ROUTES } from './deviceBrands/constants'; +import { DEVICES_ROUTES } from './devices/constants'; import { GUILDS_ROUTES } from './guilds/constants'; import { LICENSES_ROUTES } from './licenses/constants'; import { PARTNERS_ROUTES } from './partners/constants'; @@ -14,5 +16,7 @@ export const SUPER_ADMIN_ROUTES = { ...PARTNERS_ROUTES, ...PROVIDERS_ROUTES, ...LICENSES_ROUTES, + ...DEVICE_BRANDS_ROUTES, + ...DEVICES_ROUTES, ], } as Route; diff --git a/src/app/domains/superAdmin/users/components/accounts/form.component.ts b/src/app/domains/superAdmin/users/components/accounts/form.component.ts index 37684d0..3e65475 100644 --- a/src/app/domains/superAdmin/users/components/accounts/form.component.ts +++ b/src/app/domains/superAdmin/users/components/accounts/form.component.ts @@ -73,9 +73,11 @@ export class UserAccountFormComponent extends AbstractFormDialog< submitForm() { const formValue = this.form.value as IAccountRequest; + // @ts-ignore + const { confirmPassword, ...rest } = formValue; if (this.editMode) { - return this.service.update(this.userId, this.accountId, formValue); + return this.service.update(this.userId, this.accountId, rest); } - return this.service.create(this.userId, formValue); + return this.service.create(this.userId, rest); } } diff --git a/src/app/domains/superAdmin/users/components/accounts/list.component.html b/src/app/domains/superAdmin/users/components/accounts/list.component.html index d594c53..38bf857 100644 --- a/src/app/domains/superAdmin/users/components/accounts/list.component.html +++ b/src/app/domains/superAdmin/users/components/accounts/list.component.html @@ -12,4 +12,11 @@ (onAdd)="openAddForm()" >
- + diff --git a/src/app/domains/superAdmin/users/components/businessActivities/form.component.html b/src/app/domains/superAdmin/users/components/businessActivities/form.component.html new file mode 100644 index 0000000..cb0d0e4 --- /dev/null +++ b/src/app/domains/superAdmin/users/components/businessActivities/form.component.html @@ -0,0 +1,14 @@ + +
+ + + + +
diff --git a/src/app/domains/superAdmin/users/components/businessActivities/form.component.ts b/src/app/domains/superAdmin/users/components/businessActivities/form.component.ts new file mode 100644 index 0000000..b90ea08 --- /dev/null +++ b/src/app/domains/superAdmin/users/components/businessActivities/form.component.ts @@ -0,0 +1,57 @@ +// import { CatalogRolesComponent } from '@/shared/catalog/roles'; +import { AbstractFormDialog } from '@/shared/abstractClasses'; +import { CatalogGuildSelectComponent } from '@/shared/catalog/guild/components/select.component'; +import { InputComponent } from '@/shared/components'; +import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component'; +import { Component, inject, Input } from '@angular/core'; +import { ReactiveFormsModule, Validators } from '@angular/forms'; +import { Dialog } from 'primeng/dialog'; +import { IBusinessActivityRequest, IBusinessActivityResponse } from '../../models'; +import { AdminUserBusinessActivitiesService } from '../../services/businessActivities.service'; + +@Component({ + selector: 'superAdmin-user-businessActivities-form', + templateUrl: './form.component.html', + imports: [ + ReactiveFormsModule, + Dialog, + InputComponent, + FormFooterActionsComponent, + CatalogGuildSelectComponent, + ], +}) +export class UserBusinessActivitiesFormComponent extends AbstractFormDialog< + IBusinessActivityRequest, + IBusinessActivityResponse +> { + private readonly service = inject(AdminUserBusinessActivitiesService); + + @Input() userId!: string; + @Input() businessActivityId!: string; + + initForm = () => { + return this.fb.group({ + name: [this.initialValues?.name || '', [Validators.required]], + // @ts-ignore + guild_id: [this.initialValues?.guild?.id || '', [Validators.required]], + }); + }; + + form = this.initForm(); + + get preparedTitle() { + return `${this.editMode ? 'ویرایش' : 'ایجاد'} فعالیت اقتصادی`; + } + + override ngOnChanges(): void { + this.form = this.initForm(); + } + + submitForm() { + const formValue = this.form.value as IBusinessActivityRequest; + if (this.editMode) { + return this.service.update(this.userId, this.businessActivityId, formValue); + } + return this.service.create(this.userId, formValue); + } +} diff --git a/src/app/domains/superAdmin/users/components/businessActivities/layout.component.html b/src/app/domains/superAdmin/users/components/businessActivities/layout.component.html new file mode 100644 index 0000000..5416fe1 --- /dev/null +++ b/src/app/domains/superAdmin/users/components/businessActivities/layout.component.html @@ -0,0 +1,5 @@ +@if (loading()) { + +} @else { + +} diff --git a/src/app/domains/superAdmin/users/components/businessActivities/layout.component.ts b/src/app/domains/superAdmin/users/components/businessActivities/layout.component.ts new file mode 100644 index 0000000..2c38a98 --- /dev/null +++ b/src/app/domains/superAdmin/users/components/businessActivities/layout.component.ts @@ -0,0 +1,33 @@ +import { PageLoadingComponent } from '@/shared/components/page-loading.component'; +import pageParamsUtils from '@/utils/page-params.utils'; +import { Component, computed, inject } from '@angular/core'; +import { ActivatedRoute, RouterOutlet } from '@angular/router'; +import { BusinessActivityStore } from '../../store/businessActivity.store'; + +@Component({ + selector: 'superAdmin-user-businessActivity-layout', + templateUrl: './layout.component.html', + imports: [PageLoadingComponent, RouterOutlet], +}) +export class SuperAdminUserBusinessActivityLayoutComponent { + private readonly store = inject(BusinessActivityStore); + private readonly route = inject(ActivatedRoute); + + readonly loading = computed(() => this.store.loading()); + readonly businessActivity = computed(() => this.store.entity()); + readonly pageParams = computed(() => pageParamsUtils(this.route)); + + readonly userId = computed(() => this.pageParams()['userId']!); + readonly user = computed(() => this.pageParams()['userId']!); + readonly businessId = computed(() => this.pageParams()['businessActivityId']!); + + getData() { + console.log(this.pageParams()); + + this.store.getData(this.userId(), this.businessId()); + } + + ngOnInit() { + this.getData(); + } +} diff --git a/src/app/domains/superAdmin/users/components/businessActivities/list.component.html b/src/app/domains/superAdmin/users/components/businessActivities/list.component.html new file mode 100644 index 0000000..3b2fd37 --- /dev/null +++ b/src/app/domains/superAdmin/users/components/businessActivities/list.component.html @@ -0,0 +1,25 @@ + + + diff --git a/src/app/domains/superAdmin/users/components/businessActivities/list.component.ts b/src/app/domains/superAdmin/users/components/businessActivities/list.component.ts new file mode 100644 index 0000000..ae53ee4 --- /dev/null +++ b/src/app/domains/superAdmin/users/components/businessActivities/list.component.ts @@ -0,0 +1,52 @@ +// 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 { superAdminUserBusinessActivitiesNamedRoutes } from '../../constants/routes/businessActivities'; +import { IBusinessActivityResponse } from '../../models'; +import { AdminUserBusinessActivitiesService } from '../../services/businessActivities.service'; +import { UserBusinessActivitiesFormComponent } from './form.component'; + +@Component({ + selector: 'superAdmin-user-businessActivities-list', + templateUrl: './list.component.html', + imports: [PageDataListComponent, UserBusinessActivitiesFormComponent], +}) +export class UserBusinessActivitiesComponent extends AbstractList { + @Input() userId!: string; + @Input() fullHeight?: boolean; + @Input() header: IColumn[] = [ + { field: 'id', header: 'شناسه' }, + { field: 'name', header: 'عنوان' }, + { field: 'guild', header: 'صنف', type: 'nested', nestedPath: 'name' }, + { + field: 'created_at', + header: 'تاریخ ایجاد', + type: 'date', + }, + ]; + + private readonly service = inject(AdminUserBusinessActivitiesService); + private readonly router = inject(Router); + + override setColumns(): void { + this.columns = this.header; + } + + override getDataRequest() { + return this.service.getAll(this.userId); + } + + toSinglePage(item: IBusinessActivityResponse) { + this.router.navigateByUrl( + superAdminUserBusinessActivitiesNamedRoutes.businessActivity.meta.pagePath!( + this.userId, + item.id, + ), + ); + } +} diff --git a/src/app/domains/superAdmin/users/components/complexes/form.component.html b/src/app/domains/superAdmin/users/components/complexes/form.component.html new file mode 100644 index 0000000..394ad56 --- /dev/null +++ b/src/app/domains/superAdmin/users/components/complexes/form.component.html @@ -0,0 +1,15 @@ + +
+ + + + + +
diff --git a/src/app/domains/superAdmin/users/components/complexes/form.component.ts b/src/app/domains/superAdmin/users/components/complexes/form.component.ts new file mode 100644 index 0000000..9d7a286 --- /dev/null +++ b/src/app/domains/superAdmin/users/components/complexes/form.component.ts @@ -0,0 +1,51 @@ +// import { CatalogRolesComponent } from '@/shared/catalog/roles'; +import { AbstractFormDialog } from '@/shared/abstractClasses'; +import { InputComponent } from '@/shared/components'; +import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component'; +import { Component, inject, Input } from '@angular/core'; +import { ReactiveFormsModule, Validators } from '@angular/forms'; +import { Dialog } from 'primeng/dialog'; +import { IComplexRequest, IComplexResponse } from '../../models'; +import { AdminComplexesService } from '../../services/complexes.service'; + +@Component({ + selector: 'superAdmin-user-complex-form', + templateUrl: './form.component.html', + imports: [ReactiveFormsModule, Dialog, InputComponent, FormFooterActionsComponent], +}) +export class UserComplexFormComponent extends AbstractFormDialog< + IComplexRequest, + IComplexResponse +> { + private readonly service = inject(AdminComplexesService); + + @Input() userId!: string; + @Input() businessActivityId!: string; + @Input() complexId!: string; + + initForm = () => { + return this.fb.group({ + name: [this.initialValues?.name || '', [Validators.required]], + tax_id: [this.initialValues?.tax_id || '', [Validators.required]], + address: [this.initialValues?.address || '', [Validators.required]], + }); + }; + + form = this.initForm(); + + get preparedTitle() { + return `${this.editMode ? 'ویرایش' : 'ایجاد'} فروشگاه`; + } + + override ngOnChanges(): void { + this.form = this.initForm(); + } + + submitForm() { + const formValue = this.form.value as IComplexRequest; + if (this.editMode) { + return this.service.update(this.userId, this.businessActivityId, this.complexId, formValue); + } + return this.service.create(this.userId, this.businessActivityId, formValue); + } +} diff --git a/src/app/domains/superAdmin/users/components/complexes/layout.component.html b/src/app/domains/superAdmin/users/components/complexes/layout.component.html new file mode 100644 index 0000000..5416fe1 --- /dev/null +++ b/src/app/domains/superAdmin/users/components/complexes/layout.component.html @@ -0,0 +1,5 @@ +@if (loading()) { + +} @else { + +} diff --git a/src/app/domains/superAdmin/users/components/complexes/layout.component.ts b/src/app/domains/superAdmin/users/components/complexes/layout.component.ts new file mode 100644 index 0000000..d1cc956 --- /dev/null +++ b/src/app/domains/superAdmin/users/components/complexes/layout.component.ts @@ -0,0 +1,30 @@ +import { PageLoadingComponent } from '@/shared/components/page-loading.component'; +import pageParamsUtils from '@/utils/page-params.utils'; +import { Component, computed, inject } from '@angular/core'; +import { ActivatedRoute, RouterOutlet } from '@angular/router'; +import { ComplexStore } from '../../store/complex.store'; + +@Component({ + selector: 'superAdmin-user-complex-layout', + templateUrl: './layout.component.html', + imports: [PageLoadingComponent, RouterOutlet], +}) +export class SuperAdminUserComplexLayoutComponent { + private readonly store = inject(ComplexStore); + private readonly route = inject(ActivatedRoute); + + readonly loading = computed(() => this.store.loading()); + readonly pageParams = computed(() => pageParamsUtils(this.route)); + + readonly userId = computed(() => this.pageParams()['userId']!); + readonly businessId = computed(() => this.pageParams()['businessActivityId']!); + readonly complexId = computed(() => this.pageParams()['complexId']!); + + getData() { + this.store.getData(this.userId(), this.businessId(), this.complexId()); + } + + ngOnInit() { + this.getData(); + } +} diff --git a/src/app/domains/superAdmin/users/components/complexes/list.component.html b/src/app/domains/superAdmin/users/components/complexes/list.component.html new file mode 100644 index 0000000..26724fb --- /dev/null +++ b/src/app/domains/superAdmin/users/components/complexes/list.component.html @@ -0,0 +1,26 @@ + + + diff --git a/src/app/domains/superAdmin/users/components/complexes/list.component.ts b/src/app/domains/superAdmin/users/components/complexes/list.component.ts new file mode 100644 index 0000000..a9ca762 --- /dev/null +++ b/src/app/domains/superAdmin/users/components/complexes/list.component.ts @@ -0,0 +1,53 @@ +// 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 { superAdminUserComplexesNamedRoutes } from '../../constants/routes/complexes'; +import { IComplexResponse } from '../../models'; +import { AdminComplexesService } from '../../services/complexes.service'; +import { UserComplexFormComponent } from './form.component'; + +@Component({ + selector: 'superAdmin-user-complexes-list', + templateUrl: './list.component.html', + imports: [PageDataListComponent, UserComplexFormComponent], +}) +export class UserComplexesComponent extends AbstractList { + @Input() userId!: string; + @Input() businessId!: string; + @Input() fullHeight?: boolean; + @Input() header: IColumn[] = [ + { field: 'id', header: 'شناسه' }, + { field: 'name', header: 'عنوان' }, + { + field: 'created_at', + header: 'تاریخ ایجاد', + type: 'date', + }, + ]; + + private readonly service = inject(AdminComplexesService); + private readonly router = inject(Router); + + override setColumns(): void { + this.columns = this.header; + } + + override getDataRequest() { + return this.service.getAll(this.userId, this.businessId); + } + + toSinglePage(item: IComplexResponse) { + this.router.navigateByUrl( + superAdminUserComplexesNamedRoutes.complex.meta.pagePath!( + this.userId, + this.businessId, + item.id, + ), + ); + } +} diff --git a/src/app/domains/superAdmin/users/components/form.component.html b/src/app/domains/superAdmin/users/components/form.component.html index 3452a54..de59214 100644 --- a/src/app/domains/superAdmin/users/components/form.component.html +++ b/src/app/domains/superAdmin/users/components/form.component.html @@ -40,6 +40,6 @@ [invalid]="form.get('confirmPassword')?.touched && form.get('confirmPassword')?.invalid" /> --> - + diff --git a/src/app/domains/superAdmin/users/components/form.component.ts b/src/app/domains/superAdmin/users/components/form.component.ts index 8d60654..1c7091e 100644 --- a/src/app/domains/superAdmin/users/components/form.component.ts +++ b/src/app/domains/superAdmin/users/components/form.component.ts @@ -1,4 +1,4 @@ -import { MustMatch, password } from '@/core/validators'; +import { mobileValidator } from '@/core/validators'; // import { CatalogRolesComponent } from '@/shared/catalog/roles'; import { AbstractFormDialog } from '@/shared/abstractClasses'; import { EnumSelectComponent } from '@/shared/apiEnum/select.component'; @@ -37,7 +37,10 @@ export class UserAccountFormComponent extends AbstractFormDialog +} @else { + +} diff --git a/src/app/domains/superAdmin/users/components/layout.component.ts b/src/app/domains/superAdmin/users/components/layout.component.ts new file mode 100644 index 0000000..fed51d6 --- /dev/null +++ b/src/app/domains/superAdmin/users/components/layout.component.ts @@ -0,0 +1,30 @@ +import { PageLoadingComponent } from '@/shared/components/page-loading.component'; +import pageParamsUtils from '@/utils/page-params.utils'; +import { Component, computed, inject, signal } from '@angular/core'; +import { ActivatedRoute, RouterOutlet } from '@angular/router'; +import { UserStore } from '../store/user.store'; + +@Component({ + selector: 'superAdmin-user-layout', + templateUrl: './layout.component.html', + imports: [PageLoadingComponent, RouterOutlet], +}) +export class UserLayoutComponent { + private readonly store = inject(UserStore); + private readonly route = inject(ActivatedRoute); + + readonly pageParams = computed(() => pageParamsUtils(this.route)); + readonly userId = signal(this.route.snapshot.paramMap.get('userId')!); + + readonly loading = computed(() => this.store.loading()); + readonly user = computed(() => this.store.entity()); + + getData() { + this.store.getData(this.userId()); + } + + ngOnInit() { + this.getData(); + // this.setBreadcrumb(); + } +} diff --git a/src/app/domains/superAdmin/users/components/poses/form.component.html b/src/app/domains/superAdmin/users/components/poses/form.component.html new file mode 100644 index 0000000..d902c50 --- /dev/null +++ b/src/app/domains/superAdmin/users/components/poses/form.component.html @@ -0,0 +1,20 @@ + +
+ + + + + @if (form.controls.pos_type.value === "PSP") { + + + } + + +
diff --git a/src/app/domains/superAdmin/users/components/poses/form.component.ts b/src/app/domains/superAdmin/users/components/poses/form.component.ts new file mode 100644 index 0000000..04c2ddf --- /dev/null +++ b/src/app/domains/superAdmin/users/components/poses/form.component.ts @@ -0,0 +1,89 @@ +// import { CatalogRolesComponent } from '@/shared/catalog/roles'; +import { AbstractFormDialog } from '@/shared/abstractClasses'; +import { EnumSelectComponent } from '@/shared/apiEnum/select.component'; +import { CatalogProviderSelectComponent } from '@/shared/catalog'; +import { CatalogDeviceSelectComponent } from '@/shared/catalog/devices'; +import { InputComponent } from '@/shared/components'; +import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component'; +import { Component, inject, Input } from '@angular/core'; +import { ReactiveFormsModule, Validators } from '@angular/forms'; +import { Dialog } from 'primeng/dialog'; +import { IPosRequest, IPosResponse } from '../../models'; +import { AdminPosesService } from '../../services/poses.service'; + +@Component({ + selector: 'superAdmin-user-pos-form', + templateUrl: './form.component.html', + imports: [ + ReactiveFormsModule, + Dialog, + InputComponent, + FormFooterActionsComponent, + CatalogDeviceSelectComponent, + CatalogProviderSelectComponent, + EnumSelectComponent, + ], +}) +export class UserPosFormComponent extends AbstractFormDialog { + private readonly service = inject(AdminPosesService); + + @Input({ required: true }) userId!: string; + @Input({ required: true }) businessActivityId!: string; + @Input({ required: true }) complexId!: string; + @Input() posId!: string; + + initForm = () => { + console.log('posId', this.posId); + + const form = this.fb.group({ + name: [this.initialValues?.name || '', [Validators.required]], + serial: [this.initialValues?.serial || '', [Validators.required]], + // model: [this.initialValues?.model || '', [Validators.required]], + pos_type: [this.initialValues?.pos_type || '', [Validators.required]], + device_id: [this.initialValues?.device?.id || ''], + provider_id: [this.initialValues?.provider?.id || ''], + }); + form.controls.pos_type.valueChanges.subscribe((value) => { + if (value === 'PSP') { + form.addControl( + 'device_id', + this.fb.control(this.initialValues?.device?.id ?? '', { + nonNullable: true, + validators: [Validators.required], + }), + ); + form.addControl( + 'provider_id', + this.fb.control(this.initialValues?.provider?.id ?? '', { + nonNullable: true, + validators: [Validators.required], + }), + ); + } else { + // @ts-ignore + form.removeControl('device_id'); + // @ts-ignore + form.removeControl('provider_id'); + } + }); + return form; + }; + + form = this.initForm(); + + get preparedTitle() { + return `${this.editMode ? 'ویرایش' : 'ایجاد'} پایانه فروش`; + } + + override ngOnChanges(): void { + this.form = this.initForm(); + } + + submitForm() { + const formValue = this.form.value as IPosRequest; + if (this.editMode) { + return this.service.update(this.businessActivityId, this.complexId, this.posId, formValue); + } + return this.service.create(this.businessActivityId, this.complexId, formValue); + } +} diff --git a/src/app/domains/superAdmin/users/components/poses/layout.component.html b/src/app/domains/superAdmin/users/components/poses/layout.component.html new file mode 100644 index 0000000..5416fe1 --- /dev/null +++ b/src/app/domains/superAdmin/users/components/poses/layout.component.html @@ -0,0 +1,5 @@ +@if (loading()) { + +} @else { + +} diff --git a/src/app/domains/superAdmin/users/components/poses/layout.component.ts b/src/app/domains/superAdmin/users/components/poses/layout.component.ts new file mode 100644 index 0000000..0b92588 --- /dev/null +++ b/src/app/domains/superAdmin/users/components/poses/layout.component.ts @@ -0,0 +1,31 @@ +import { PageLoadingComponent } from '@/shared/components/page-loading.component'; +import pageParamsUtils from '@/utils/page-params.utils'; +import { Component, computed, inject } from '@angular/core'; +import { ActivatedRoute, RouterOutlet } from '@angular/router'; +import { PosStore } from '../../store/pos.store'; + +@Component({ + selector: 'superAdmin-user-pos-layout', + templateUrl: './layout.component.html', + imports: [PageLoadingComponent, RouterOutlet], +}) +export class SuperAdminUserPosLayoutComponent { + private readonly store = inject(PosStore); + private readonly route = inject(ActivatedRoute); + + readonly loading = computed(() => this.store.loading()); + readonly pageParams = computed(() => pageParamsUtils(this.route)); + + readonly userId = computed(() => this.pageParams()['userId']!); + 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()); + } + + ngOnInit() { + this.getData(); + } +} diff --git a/src/app/domains/superAdmin/users/components/poses/list.component.html b/src/app/domains/superAdmin/users/components/poses/list.component.html new file mode 100644 index 0000000..ffd89d7 --- /dev/null +++ b/src/app/domains/superAdmin/users/components/poses/list.component.html @@ -0,0 +1,27 @@ + + + diff --git a/src/app/domains/superAdmin/users/components/poses/list.component.ts b/src/app/domains/superAdmin/users/components/poses/list.component.ts new file mode 100644 index 0000000..40543d4 --- /dev/null +++ b/src/app/domains/superAdmin/users/components/poses/list.component.ts @@ -0,0 +1,60 @@ +// 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 { superAdminUserPosesNamedRoutes } from '../../constants/routes/poses'; +import { IPosResponse } from '../../models'; +import { AdminPosesService } from '../../services/poses.service'; +import { UserPosFormComponent } from './form.component'; + +@Component({ + selector: 'superAdmin-user-poses-list', + templateUrl: './list.component.html', + imports: [PageDataListComponent, UserPosFormComponent], +}) +export class UserPosesComponent extends AbstractList { + @Input() userId!: string; + @Input() businessId!: string; + @Input() complexId!: string; + @Input() fullHeight?: boolean; + @Input() header: IColumn[] = [ + { field: 'id', header: 'شناسه' }, + { field: 'name', header: 'عنوان' }, + { field: 'serial', header: 'شماره سریال' }, + { field: 'device', header: 'دستگاه', type: 'nested', nestedPath: 'device.name' }, + { field: 'pos_type', header: 'نوع دستگاه' }, + { field: 'provider', header: 'ارایه‌دهنده', type: 'nested', nestedPath: 'provider.name' }, + { field: 'status', header: 'وضعیت' }, + { + field: 'created_at', + header: 'تاریخ ایجاد', + type: 'date', + }, + ]; + + private readonly service = inject(AdminPosesService); + private readonly router = inject(Router); + + override setColumns(): void { + this.columns = this.header; + } + + override getDataRequest() { + return this.service.getAll(this.businessId, this.complexId); + } + + toSinglePage(item: IPosResponse) { + this.router.navigateByUrl( + superAdminUserPosesNamedRoutes.pos.meta.pagePath!( + this.userId, + this.businessId, + this.complexId, + item.id, + ), + ); + } +} diff --git a/src/app/domains/superAdmin/users/constants/apiRoutes/businessActivities.ts b/src/app/domains/superAdmin/users/constants/apiRoutes/businessActivities.ts new file mode 100644 index 0000000..6eacfd0 --- /dev/null +++ b/src/app/domains/superAdmin/users/constants/apiRoutes/businessActivities.ts @@ -0,0 +1,7 @@ +const baseUrl = (userId: string) => `/api/v1/admin/users/${userId}/business_activities`; + +export const BUSINESS_ACTIVITIES_API_ROUTES = { + list: (userId: string) => `${baseUrl(userId)}`, + single: (userId: string, business_activity_id: string) => + `${baseUrl(userId)}/${business_activity_id}`, +}; diff --git a/src/app/domains/superAdmin/users/constants/apiRoutes/businessActivityComplexes.ts b/src/app/domains/superAdmin/users/constants/apiRoutes/businessActivityComplexes.ts new file mode 100644 index 0000000..e4a5fec --- /dev/null +++ b/src/app/domains/superAdmin/users/constants/apiRoutes/businessActivityComplexes.ts @@ -0,0 +1,9 @@ +const baseUrl = (userId: string, business_activity_id: string) => + `/api/v1/admin/users/${userId}/business_activities/${business_activity_id}/complexes`; + +export const BUSINESS_ACTIVITY_COMPLEXES_API_ROUTES = { + list: (userId: string, business_activity_id: string) => + `${baseUrl(userId, business_activity_id)}`, + single: (userId: string, business_activity_id: string, complex_id: string) => + `${baseUrl(userId, business_activity_id)}/${complex_id}`, +}; diff --git a/src/app/domains/superAdmin/users/constants/apiRoutes/complexPoses.ts b/src/app/domains/superAdmin/users/constants/apiRoutes/complexPoses.ts new file mode 100644 index 0000000..62410cb --- /dev/null +++ b/src/app/domains/superAdmin/users/constants/apiRoutes/complexPoses.ts @@ -0,0 +1,9 @@ +const baseUrl = (business_activity_id: string, complex_id: string) => + `/api/v1/admin/business_activities/${business_activity_id}/complexes/${complex_id}/poses`; + +export const COMPLEX_POSES_API_ROUTES = { + list: (business_activity_id: string, complex_id: string) => + `${baseUrl(business_activity_id, complex_id)}`, + single: (business_activity_id: string, complex_id: string, posId: string) => + `${baseUrl(business_activity_id, complex_id)}/${posId}`, +}; diff --git a/src/app/domains/superAdmin/users/constants/apiRoutes/index.ts b/src/app/domains/superAdmin/users/constants/apiRoutes/index.ts index 46d5de5..1cf294a 100644 --- a/src/app/domains/superAdmin/users/constants/apiRoutes/index.ts +++ b/src/app/domains/superAdmin/users/constants/apiRoutes/index.ts @@ -1,4 +1,8 @@ export * from './accounts'; +export * from './businessActivities'; +export * from './businessActivityComplexes'; +export * from './complexPoses'; +export * from './posAccounts'; const baseUrl = '/api/v1/admin/users'; diff --git a/src/app/domains/superAdmin/users/constants/apiRoutes/posAccounts.ts b/src/app/domains/superAdmin/users/constants/apiRoutes/posAccounts.ts new file mode 100644 index 0000000..8d83b06 --- /dev/null +++ b/src/app/domains/superAdmin/users/constants/apiRoutes/posAccounts.ts @@ -0,0 +1,8 @@ +const baseUrl = (complexId: string, posId: string) => + `/api/v1/admin/complexes/${complexId}/poses/${posId}/accounts`; + +export const POS_ACCOUNTS_API_ROUTES = { + list: (complexId: string, posId: string) => `${baseUrl(complexId, posId)}`, + single: (complexId: string, posId: string, accountId: string) => + `${baseUrl(complexId, posId)}/${accountId}`, +}; diff --git a/src/app/domains/superAdmin/users/constants/routes/accounts.ts b/src/app/domains/superAdmin/users/constants/routes/accounts.ts new file mode 100644 index 0000000..899deeb --- /dev/null +++ b/src/app/domains/superAdmin/users/constants/routes/accounts.ts @@ -0,0 +1,52 @@ +import { NamedRoutes } from '@/core'; +import { Routes } from '@angular/router'; +import { SUPER_ADMIN_USER_COMPLEXES_ROUTES } from './complexes'; + +export type TBusinessActivitiesRouteNames = 'businessActivities' | 'businessActivity'; + +export const superAdminUserBusinessActivitiesNamedRoutes: NamedRoutes = + { + businessActivities: { + path: 'business_activities', + loadComponent: () => + import('../../views/businessActivities/list.component').then( + (m) => m.SuperAdminUserBusinessActivitiesComponent, + ), + // @ts-ignore + meta: { + title: 'فعالیت‌های اقتصادی', + pagePath: (userId: string) => `/super_admin/users/${userId}/business_activities`, + }, + }, + businessActivity: { + path: 'business_activities/:businessActivityId', + loadComponent: () => + import('../../views/businessActivities/single.component').then( + (m) => m.SuperAdminUserBusinessActivityComponent, + ), + // @ts-ignore + meta: { + title: 'فعالیت اقتصادی', + pagePath: (userId: string, businessId: string) => + `/super_admin/users/${userId}/business_activities/${businessId}`, + }, + }, + }; + +export const SUPER_ADMIN_USER_BUSINESS_ACTIVITIES_ROUTES: Routes = [ + superAdminUserBusinessActivitiesNamedRoutes.businessActivities, + { + path: superAdminUserBusinessActivitiesNamedRoutes.businessActivity.path, + loadComponent: () => + import('../../components/businessActivities/layout.component').then( + (m) => m.SuperAdminUserBusinessActivityLayoutComponent, + ), + children: [ + { + path: '', + loadComponent: superAdminUserBusinessActivitiesNamedRoutes.businessActivity.loadComponent, + }, + ...SUPER_ADMIN_USER_COMPLEXES_ROUTES, + ], + }, +]; diff --git a/src/app/domains/superAdmin/users/constants/routes/businessActivities.ts b/src/app/domains/superAdmin/users/constants/routes/businessActivities.ts new file mode 100644 index 0000000..899deeb --- /dev/null +++ b/src/app/domains/superAdmin/users/constants/routes/businessActivities.ts @@ -0,0 +1,52 @@ +import { NamedRoutes } from '@/core'; +import { Routes } from '@angular/router'; +import { SUPER_ADMIN_USER_COMPLEXES_ROUTES } from './complexes'; + +export type TBusinessActivitiesRouteNames = 'businessActivities' | 'businessActivity'; + +export const superAdminUserBusinessActivitiesNamedRoutes: NamedRoutes = + { + businessActivities: { + path: 'business_activities', + loadComponent: () => + import('../../views/businessActivities/list.component').then( + (m) => m.SuperAdminUserBusinessActivitiesComponent, + ), + // @ts-ignore + meta: { + title: 'فعالیت‌های اقتصادی', + pagePath: (userId: string) => `/super_admin/users/${userId}/business_activities`, + }, + }, + businessActivity: { + path: 'business_activities/:businessActivityId', + loadComponent: () => + import('../../views/businessActivities/single.component').then( + (m) => m.SuperAdminUserBusinessActivityComponent, + ), + // @ts-ignore + meta: { + title: 'فعالیت اقتصادی', + pagePath: (userId: string, businessId: string) => + `/super_admin/users/${userId}/business_activities/${businessId}`, + }, + }, + }; + +export const SUPER_ADMIN_USER_BUSINESS_ACTIVITIES_ROUTES: Routes = [ + superAdminUserBusinessActivitiesNamedRoutes.businessActivities, + { + path: superAdminUserBusinessActivitiesNamedRoutes.businessActivity.path, + loadComponent: () => + import('../../components/businessActivities/layout.component').then( + (m) => m.SuperAdminUserBusinessActivityLayoutComponent, + ), + children: [ + { + path: '', + loadComponent: superAdminUserBusinessActivitiesNamedRoutes.businessActivity.loadComponent, + }, + ...SUPER_ADMIN_USER_COMPLEXES_ROUTES, + ], + }, +]; diff --git a/src/app/domains/superAdmin/users/constants/routes/complexes.ts b/src/app/domains/superAdmin/users/constants/routes/complexes.ts new file mode 100644 index 0000000..b34cf85 --- /dev/null +++ b/src/app/domains/superAdmin/users/constants/routes/complexes.ts @@ -0,0 +1,54 @@ +import { NamedRoutes } from '@/core'; +import { Routes } from '@angular/router'; +import { SUPER_ADMIN_USER_POSES_ROUTES } from './poses'; + +export type TComplexesRouteNames = 'complexes' | 'complex'; + +const baseUrl = (userId: string, businessId: string) => + `/super_admin/users/${userId}/business_activities/${businessId}/complexes`; + +export const superAdminUserComplexesNamedRoutes: NamedRoutes = { + complexes: { + path: 'complexes', + loadComponent: () => + import('../../views/complexes/list.component').then( + (m) => m.SuperAdminUserComplexesComponent, + ), + // @ts-ignore + meta: { + title: 'فروشگاه‌ها', + pagePath: (userId: string, businessId: string) => baseUrl(userId, businessId), + }, + }, + complex: { + path: 'complexes/:complexId', + loadComponent: () => + import('../../views/complexes/single.component').then( + (m) => m.SuperAdminUserComplexComponent, + ), + // @ts-ignore + meta: { + title: 'فروشگاه', + pagePath: (userId: string, businessId: string, complexId: string) => + `${baseUrl(userId, businessId)}/${complexId}`, + }, + }, +}; + +export const SUPER_ADMIN_USER_COMPLEXES_ROUTES: Routes = [ + superAdminUserComplexesNamedRoutes.complexes, + { + path: superAdminUserComplexesNamedRoutes.complex.path, + loadComponent: () => + import('../../components/complexes/layout.component').then( + (m) => m.SuperAdminUserComplexLayoutComponent, + ), + children: [ + { + path: '', + loadComponent: superAdminUserComplexesNamedRoutes.complex.loadComponent, + }, + ...SUPER_ADMIN_USER_POSES_ROUTES, + ], + }, +]; diff --git a/src/app/domains/superAdmin/users/constants/routes/index.ts b/src/app/domains/superAdmin/users/constants/routes/index.ts index 9be8bed..627a636 100644 --- a/src/app/domains/superAdmin/users/constants/routes/index.ts +++ b/src/app/domains/superAdmin/users/constants/routes/index.ts @@ -1,5 +1,6 @@ import { NamedRoutes } from '@/core'; import { Routes } from '@angular/router'; +import { SUPER_ADMIN_USER_BUSINESS_ACTIVITIES_ROUTES } from './businessActivities'; export type TUsersRouteNames = 'users' | 'user'; @@ -22,4 +23,18 @@ export const usersNamedRoutes: NamedRoutes = { }, }; -export const USERS_ROUTES: Routes = Object.values(usersNamedRoutes); +export const USERS_ROUTES: Routes = [ + usersNamedRoutes.users, + { + path: usersNamedRoutes.user.path, + loadComponent: () => + import('../../components/layout.component').then((m) => m.UserLayoutComponent), + children: [ + { + path: '', + loadComponent: usersNamedRoutes.user.loadComponent, + }, + ...SUPER_ADMIN_USER_BUSINESS_ACTIVITIES_ROUTES, + ], + }, +]; diff --git a/src/app/domains/superAdmin/users/constants/routes/poses.ts b/src/app/domains/superAdmin/users/constants/routes/poses.ts new file mode 100644 index 0000000..ee2e5e6 --- /dev/null +++ b/src/app/domains/superAdmin/users/constants/routes/poses.ts @@ -0,0 +1,49 @@ +import { NamedRoutes } from '@/core'; +import { Routes } from '@angular/router'; + +export type TPosesRouteNames = 'poses' | 'pos'; + +const baseUrl = (userId: string, businessId: string, complexId: string) => + `/super_admin/users/${userId}/business_activities/${businessId}/complexes/${complexId}/poses`; + +export const superAdminUserPosesNamedRoutes: NamedRoutes = { + poses: { + path: 'poses', + loadComponent: () => + import('../../views/poses/list.component').then((m) => m.SuperAdminUserPosesComponent), + // @ts-ignore + meta: { + title: 'پایانه‌های فروش', + pagePath: (userId: string, businessId: string, complexId: string) => + baseUrl(userId, businessId, complexId), + }, + }, + pos: { + path: 'poses/:posId', + loadComponent: () => + import('../../views/poses/single.component').then((m) => m.SuperAdminUserPosComponent), + // @ts-ignore + meta: { + title: 'پایانه‌ی فروش', + pagePath: (userId: string, businessId: string, complexId: string, posId: string) => + `${baseUrl(userId, businessId, complexId)}/${posId}`, + }, + }, +}; + +export const SUPER_ADMIN_USER_POSES_ROUTES: Routes = [ + superAdminUserPosesNamedRoutes.poses, + { + path: superAdminUserPosesNamedRoutes.pos.path, + loadComponent: () => + import('../../components/poses/layout.component').then( + (m) => m.SuperAdminUserPosLayoutComponent, + ), + children: [ + { + path: '', + loadComponent: superAdminUserPosesNamedRoutes.pos.loadComponent, + }, + ], + }, +]; diff --git a/src/app/domains/superAdmin/users/models/accounts_io.d.ts b/src/app/domains/superAdmin/users/models/accounts_io.d.ts index f8aad6f..54bdb83 100644 --- a/src/app/domains/superAdmin/users/models/accounts_io.d.ts +++ b/src/app/domains/superAdmin/users/models/accounts_io.d.ts @@ -2,7 +2,7 @@ import { TAccountType } from '@/core/constants/accountTypes.const'; export interface IAccountRawResponse { username: string; - id: number; + id: string; } export interface IAccountResponse extends IAccountRawResponse {} diff --git a/src/app/domains/superAdmin/users/models/businessActivities_io.d.ts b/src/app/domains/superAdmin/users/models/businessActivities_io.d.ts new file mode 100644 index 0000000..a97a076 --- /dev/null +++ b/src/app/domains/superAdmin/users/models/businessActivities_io.d.ts @@ -0,0 +1,13 @@ +import ISummary from '@/core/models/summary'; + +export interface IBusinessActivityRawResponse { + name: string; + guild: ISummary; + id: string; +} +export interface IBusinessActivityResponse extends IBusinessActivityRawResponse {} + +export interface IBusinessActivityRequest { + name: string; + guild_id: string; +} diff --git a/src/app/domains/superAdmin/users/models/complexes_io.d.ts b/src/app/domains/superAdmin/users/models/complexes_io.d.ts new file mode 100644 index 0000000..ba9ebe0 --- /dev/null +++ b/src/app/domains/superAdmin/users/models/complexes_io.d.ts @@ -0,0 +1,13 @@ +export interface IComplexRawResponse { + name: string; + address: string; + tax_id: string; + id: string; +} +export interface IComplexResponse extends IComplexRawResponse {} + +export interface IComplexRequest { + name: string; + address: string; + tax_id: string; +} diff --git a/src/app/domains/superAdmin/users/models/index.ts b/src/app/domains/superAdmin/users/models/index.ts index 388437e..2a44ca6 100644 --- a/src/app/domains/superAdmin/users/models/index.ts +++ b/src/app/domains/superAdmin/users/models/index.ts @@ -1,2 +1,5 @@ export * from './accounts_io'; +export * from './businessActivities_io'; +export * from './complexes_io'; export * from './io'; +export * from './poses_io'; diff --git a/src/app/domains/superAdmin/users/models/poses_io.d.ts b/src/app/domains/superAdmin/users/models/poses_io.d.ts new file mode 100644 index 0000000..1c76cae --- /dev/null +++ b/src/app/domains/superAdmin/users/models/poses_io.d.ts @@ -0,0 +1,24 @@ +import ISummary from '@/core/models/summary'; + +export interface IPosRawResponse { + id: string; + name: string; + serial: string; + model?: string; + status: string; + pos_type: string; + complex: ISummary; + device?: ISummary; + provider?: ISummary; +} +export interface IPosResponse extends IPosRawResponse {} + +export interface IPosRequest { + name: string; + serial: string; + model?: string; + status: string; + pos_type: string; + device_id: string; + provider_id: string; +} diff --git a/src/app/domains/superAdmin/users/services/businessActivities.service.ts b/src/app/domains/superAdmin/users/services/businessActivities.service.ts new file mode 100644 index 0000000..4fb9223 --- /dev/null +++ b/src/app/domains/superAdmin/users/services/businessActivities.service.ts @@ -0,0 +1,45 @@ +import { IPaginatedResponse } from '@/core/models/service.model'; +import { HttpClient } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; +import { BUSINESS_ACTIVITIES_API_ROUTES } from '../constants/apiRoutes/businessActivities'; +import { + IBusinessActivityRawResponse, + IBusinessActivityRequest, + IBusinessActivityResponse, +} from '../models'; + +@Injectable({ providedIn: 'root' }) +export class AdminUserBusinessActivitiesService { + constructor(private http: HttpClient) {} + + private apiRoutes = BUSINESS_ACTIVITIES_API_ROUTES; + + getAll(userId: string): Observable> { + return this.http.get>( + this.apiRoutes.list(userId), + ); + } + getSingle(userId: string, businessActivityId: string): Observable { + console.log(userId, businessActivityId); + + return this.http.get( + this.apiRoutes.single(userId, businessActivityId), + ); + } + + create(userId: string, data: IBusinessActivityRequest): Observable { + return this.http.post(this.apiRoutes.list(userId), data); + } + + update( + userId: string, + businessActivityId: string, + data: IBusinessActivityRequest, + ): Observable { + return this.http.patch( + this.apiRoutes.single(userId, businessActivityId), + data, + ); + } +} diff --git a/src/app/domains/superAdmin/users/services/complexes.service.ts b/src/app/domains/superAdmin/users/services/complexes.service.ts new file mode 100644 index 0000000..8558956 --- /dev/null +++ b/src/app/domains/superAdmin/users/services/complexes.service.ts @@ -0,0 +1,54 @@ +import { IPaginatedResponse } from '@/core/models/service.model'; +import { HttpClient } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; +import { BUSINESS_ACTIVITY_COMPLEXES_API_ROUTES } from '../constants/apiRoutes/businessActivityComplexes'; +import { IComplexRawResponse, IComplexRequest, IComplexResponse } from '../models'; + +@Injectable({ providedIn: 'root' }) +export class AdminComplexesService { + constructor(private http: HttpClient) {} + + private apiRoutes = BUSINESS_ACTIVITY_COMPLEXES_API_ROUTES; + + getAll( + userId: string, + businessActivityId: string, + ): Observable> { + return this.http.get>( + this.apiRoutes.list(userId, businessActivityId), + ); + } + getSingle( + userId: string, + businessActivityId: string, + complexId: string, + ): Observable { + return this.http.get( + this.apiRoutes.single(userId, businessActivityId, complexId), + ); + } + + create( + userId: string, + businessActivityId: string, + data: IComplexRequest, + ): Observable { + return this.http.post( + this.apiRoutes.list(userId, businessActivityId), + data, + ); + } + + update( + userId: string, + businessActivityId: string, + complexId: string, + data: IComplexRequest, + ): Observable { + return this.http.patch( + this.apiRoutes.single(userId, businessActivityId, complexId), + data, + ); + } +} diff --git a/src/app/domains/superAdmin/users/services/posAccounts.service.ts b/src/app/domains/superAdmin/users/services/posAccounts.service.ts new file mode 100644 index 0000000..c71b9c7 --- /dev/null +++ b/src/app/domains/superAdmin/users/services/posAccounts.service.ts @@ -0,0 +1,38 @@ +import { IPaginatedResponse } from '@/core/models/service.model'; +import { HttpClient } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; +import { POS_ACCOUNTS_API_ROUTES } from '../constants'; +import { IAccountRawResponse, IAccountRequest, IAccountResponse } from '../models'; + +@Injectable({ providedIn: 'root' }) +export class AdminPosesService { + constructor(private http: HttpClient) {} + + private apiRoutes = POS_ACCOUNTS_API_ROUTES; + + getAll(complexId: string, posId: string): Observable> { + return this.http.get>( + this.apiRoutes.list(complexId, posId), + ); + } + getSingle(complexId: string, posId: string, accountId: string): Observable { + return this.http.get(this.apiRoutes.single(complexId, posId, accountId)); + } + + create(complexId: string, posId: string, data: IAccountRequest): Observable { + return this.http.post(this.apiRoutes.list(complexId, posId), data); + } + + update( + complexId: string, + posId: string, + accountId: string, + data: IAccountRequest, + ): Observable { + return this.http.patch( + this.apiRoutes.single(complexId, posId, accountId), + data, + ); + } +} diff --git a/src/app/domains/superAdmin/users/services/poses.service.ts b/src/app/domains/superAdmin/users/services/poses.service.ts new file mode 100644 index 0000000..73ebf80 --- /dev/null +++ b/src/app/domains/superAdmin/users/services/poses.service.ts @@ -0,0 +1,54 @@ +import { IPaginatedResponse } from '@/core/models/service.model'; +import { HttpClient } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; +import { COMPLEX_POSES_API_ROUTES } from '../constants'; +import { IPosRawResponse, IPosRequest, IPosResponse } from '../models'; + +@Injectable({ providedIn: 'root' }) +export class AdminPosesService { + constructor(private http: HttpClient) {} + + private apiRoutes = COMPLEX_POSES_API_ROUTES; + + getAll( + businessActivityId: string, + complexId: string, + ): Observable> { + return this.http.get>( + this.apiRoutes.list(businessActivityId, complexId), + ); + } + getSingle( + businessActivityId: string, + complexId: string, + posId: string, + ): Observable { + return this.http.get( + this.apiRoutes.single(businessActivityId, complexId, posId), + ); + } + + create( + businessActivityId: string, + complexId: string, + data: IPosRequest, + ): Observable { + return this.http.post( + this.apiRoutes.list(businessActivityId, complexId), + data, + ); + } + + update( + businessActivityId: string, + complexId: string, + posId: string, + data: IPosRequest, + ): Observable { + return this.http.patch( + this.apiRoutes.single(businessActivityId, complexId, posId), + data, + ); + } +} diff --git a/src/app/domains/superAdmin/users/store/businessActivity.store.ts b/src/app/domains/superAdmin/users/store/businessActivity.store.ts new file mode 100644 index 0000000..6adba15 --- /dev/null +++ b/src/app/domains/superAdmin/users/store/businessActivity.store.ts @@ -0,0 +1,56 @@ +import { EntityState, EntityStore } from '@/core/state'; +import { inject, Injectable } from '@angular/core'; +import { catchError, finalize, throwError } from 'rxjs'; +import { IBusinessActivityResponse } from '../models'; +import { AdminUserBusinessActivitiesService } from '../services/businessActivities.service'; + +interface BusinessActivityState extends EntityState {} + +@Injectable({ + providedIn: 'root', +}) +export class BusinessActivityStore extends EntityStore< + IBusinessActivityResponse, + BusinessActivityState +> { + private readonly service = inject(AdminUserBusinessActivitiesService); + constructor() { + super({ + loading: false, + error: null, + entity: null, + initialized: false, + isRefreshing: false, + }); + } + + getData(userId: string, business_id: string) { + this.patchState({ loading: true }); + this.service + .getSingle(userId, business_id) + .pipe( + finalize(() => { + this.patchState({ loading: false }); + }), + catchError(() => { + this.patchState({ + error: '', + }); + return throwError(''); + }), + ) + .subscribe((entity) => { + this.patchState({ entity }); + }); + } + + override reset(): void { + this.setState({ + loading: false, + error: null, + entity: null, + initialized: false, + isRefreshing: false, + }); + } +} diff --git a/src/app/domains/superAdmin/users/store/complex.store.ts b/src/app/domains/superAdmin/users/store/complex.store.ts new file mode 100644 index 0000000..9b17951 --- /dev/null +++ b/src/app/domains/superAdmin/users/store/complex.store.ts @@ -0,0 +1,53 @@ +import { EntityState, EntityStore } from '@/core/state'; +import { inject, Injectable } from '@angular/core'; +import { catchError, finalize, throwError } from 'rxjs'; +import { IComplexResponse } from '../models'; +import { AdminComplexesService } from '../services/complexes.service'; + +interface ComplexState extends EntityState {} + +@Injectable({ + providedIn: 'root', +}) +export class ComplexStore extends EntityStore { + private readonly service = inject(AdminComplexesService); + constructor() { + super({ + loading: false, + error: null, + entity: null, + initialized: false, + isRefreshing: false, + }); + } + + getData(userId: string, businessId: string, complexId: string) { + this.patchState({ loading: true }); + this.service + .getSingle(userId, businessId, complexId) + .pipe( + finalize(() => { + this.patchState({ loading: false }); + }), + catchError(() => { + this.patchState({ + error: '', + }); + return throwError(''); + }), + ) + .subscribe((entity) => { + this.patchState({ entity }); + }); + } + + override reset(): void { + this.setState({ + loading: false, + error: null, + entity: null, + initialized: false, + isRefreshing: false, + }); + } +} diff --git a/src/app/domains/superAdmin/users/store/pos.store.ts b/src/app/domains/superAdmin/users/store/pos.store.ts new file mode 100644 index 0000000..e401363 --- /dev/null +++ b/src/app/domains/superAdmin/users/store/pos.store.ts @@ -0,0 +1,53 @@ +import { EntityState, EntityStore } from '@/core/state'; +import { inject, Injectable } from '@angular/core'; +import { catchError, finalize, throwError } from 'rxjs'; +import { IPosResponse } from '../models'; +import { AdminPosesService } from '../services/poses.service'; + +interface PosState extends EntityState {} + +@Injectable({ + providedIn: 'root', +}) +export class PosStore extends EntityStore { + private readonly service = inject(AdminPosesService); + constructor() { + super({ + loading: false, + error: null, + entity: null, + initialized: false, + isRefreshing: false, + }); + } + + getData(businessId: string, complexId: string, posId: string) { + this.patchState({ loading: true }); + this.service + .getSingle(businessId, complexId, posId) + .pipe( + finalize(() => { + this.patchState({ loading: false }); + }), + catchError(() => { + this.patchState({ + error: '', + }); + return throwError(''); + }), + ) + .subscribe((entity) => { + this.patchState({ entity }); + }); + } + + override reset(): void { + this.setState({ + loading: false, + error: null, + entity: null, + initialized: false, + isRefreshing: false, + }); + } +} diff --git a/src/app/domains/superAdmin/users/views/businessActivities/index.ts b/src/app/domains/superAdmin/users/views/businessActivities/index.ts new file mode 100644 index 0000000..576a89e --- /dev/null +++ b/src/app/domains/superAdmin/users/views/businessActivities/index.ts @@ -0,0 +1 @@ +export * from './list.component'; diff --git a/src/app/domains/superAdmin/users/views/businessActivities/list.component.html b/src/app/domains/superAdmin/users/views/businessActivities/list.component.html new file mode 100644 index 0000000..b0e6dbc --- /dev/null +++ b/src/app/domains/superAdmin/users/views/businessActivities/list.component.html @@ -0,0 +1 @@ + diff --git a/src/app/domains/superAdmin/users/views/businessActivities/list.component.ts b/src/app/domains/superAdmin/users/views/businessActivities/list.component.ts new file mode 100644 index 0000000..c5ce944 --- /dev/null +++ b/src/app/domains/superAdmin/users/views/businessActivities/list.component.ts @@ -0,0 +1,43 @@ +// import { CatalogRoleTagComponent } from '@/shared/catalog/roles'; +import { BreadcrumbService } from '@/core/services'; +import pageParamsUtils from '@/utils/page-params.utils'; +import { Component, computed, inject, signal } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { UserBusinessActivitiesComponent } from '../../components/businessActivities/list.component'; +import { usersNamedRoutes } from '../../constants'; +import { superAdminUserBusinessActivitiesNamedRoutes } from '../../constants/routes/businessActivities'; +import { UserStore } from '../../store/user.store'; + +@Component({ + selector: 'superAdmin-user-businessActivities', + templateUrl: './list.component.html', + imports: [UserBusinessActivitiesComponent], +}) +export class SuperAdminUserBusinessActivitiesComponent { + private readonly route = inject(ActivatedRoute); + private readonly breadcrumbService = inject(BreadcrumbService); + private readonly userStore = inject(UserStore); + + pageParams = computed(() => pageParamsUtils(this.route)); + userId = signal(this.pageParams()['userId']); + + ngOnInit() { + this.setBreadcrumb(); + } + + setBreadcrumb() { + this.breadcrumbService.setItems([ + { + ...usersNamedRoutes.users.meta, + routerLink: usersNamedRoutes.users.meta.pagePath!(), + }, + { + title: this.userStore.entity()?.fullname, + routerLink: usersNamedRoutes.user.meta.pagePath!(this.userId()), + }, + { + title: superAdminUserBusinessActivitiesNamedRoutes.businessActivities.meta.title, + }, + ]); + } +} diff --git a/src/app/domains/superAdmin/users/views/businessActivities/single.component.html b/src/app/domains/superAdmin/users/views/businessActivities/single.component.html new file mode 100644 index 0000000..039e3d2 --- /dev/null +++ b/src/app/domains/superAdmin/users/views/businessActivities/single.component.html @@ -0,0 +1,21 @@ +
+ +
+
+ + +
+
+
+ + + + +
diff --git a/src/app/domains/superAdmin/users/views/businessActivities/single.component.ts b/src/app/domains/superAdmin/users/views/businessActivities/single.component.ts new file mode 100644 index 0000000..b6a33bd --- /dev/null +++ b/src/app/domains/superAdmin/users/views/businessActivities/single.component.ts @@ -0,0 +1,76 @@ +import { BreadcrumbService } from '@/core/services'; +import { AppCardComponent, KeyValueComponent } from '@/shared/components'; +import pageParamsUtils from '@/utils/page-params.utils'; +import { Component, computed, effect, inject, signal } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { UserBusinessActivitiesFormComponent } from '../../components/businessActivities/form.component'; +import { UserComplexesComponent } from '../../components/complexes/list.component'; +import { usersNamedRoutes } from '../../constants'; +import { superAdminUserBusinessActivitiesNamedRoutes } from '../../constants/routes/businessActivities'; +import { BusinessActivityStore } from '../../store/businessActivity.store'; +import { UserStore } from '../../store/user.store'; + +@Component({ + selector: 'superAdmin-user-businessActivity', + templateUrl: './single.component.html', + imports: [ + AppCardComponent, + KeyValueComponent, + UserBusinessActivitiesFormComponent, + UserComplexesComponent, + ], +}) +export class SuperAdminUserBusinessActivityComponent { + private readonly route = inject(ActivatedRoute); + private readonly breadcrumbService = inject(BreadcrumbService); + private readonly store = inject(BusinessActivityStore); + private readonly userStore = inject(UserStore); + + pageParams = computed(() => pageParamsUtils(this.route)); + + readonly userId = signal(this.pageParams()['userId']!); + readonly businessId = signal(this.pageParams()['businessActivityId']!); + editMode = signal(false); + + readonly loading = computed(() => this.store.loading()); + readonly businessActivity = computed(() => this.store.entity()); + + constructor() { + effect(() => { + if (this.businessActivity()?.id) { + console.log(this.businessActivity()?.id); + this.setBreadcrumb(); + } + }); + } + + getData() { + this.store.getData(this.userId(), this.businessId()); + } + + setBreadcrumb() { + this.breadcrumbService.setItems([ + { + ...usersNamedRoutes.users.meta, + routerLink: usersNamedRoutes.users.meta.pagePath!(), + }, + { + title: this.userStore.entity()?.fullname, + routerLink: usersNamedRoutes.user.meta.pagePath!(this.userId()), + }, + { + ...superAdminUserBusinessActivitiesNamedRoutes.businessActivities.meta, + routerLink: superAdminUserBusinessActivitiesNamedRoutes.businessActivities.meta.pagePath!( + this.userId(), + ), + }, + { + title: this.businessActivity()?.name, + routerLink: superAdminUserBusinessActivitiesNamedRoutes.businessActivity.meta.pagePath!( + this.userId(), + this.businessId(), + ), + }, + ]); + } +} diff --git a/src/app/domains/superAdmin/users/views/complexes/index.ts b/src/app/domains/superAdmin/users/views/complexes/index.ts new file mode 100644 index 0000000..576a89e --- /dev/null +++ b/src/app/domains/superAdmin/users/views/complexes/index.ts @@ -0,0 +1 @@ +export * from './list.component'; diff --git a/src/app/domains/superAdmin/users/views/complexes/list.component.html b/src/app/domains/superAdmin/users/views/complexes/list.component.html new file mode 100644 index 0000000..19502c0 --- /dev/null +++ b/src/app/domains/superAdmin/users/views/complexes/list.component.html @@ -0,0 +1 @@ + diff --git a/src/app/domains/superAdmin/users/views/complexes/list.component.ts b/src/app/domains/superAdmin/users/views/complexes/list.component.ts new file mode 100644 index 0000000..f5b8fc1 --- /dev/null +++ b/src/app/domains/superAdmin/users/views/complexes/list.component.ts @@ -0,0 +1,64 @@ +// import { CatalogRoleTagComponent } from '@/shared/catalog/roles'; +import { BreadcrumbService } from '@/core/services'; +import pageParamsUtils from '@/utils/page-params.utils'; +import { Component, computed, inject, signal } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { UserComplexesComponent } from '../../components/complexes/list.component'; +import { usersNamedRoutes } from '../../constants'; +import { superAdminUserBusinessActivitiesNamedRoutes } from '../../constants/routes/businessActivities'; +import { superAdminUserComplexesNamedRoutes } from '../../constants/routes/complexes'; +import { BusinessActivityStore } from '../../store/businessActivity.store'; +import { UserStore } from '../../store/user.store'; + +@Component({ + selector: 'superAdmin-user-complexes', + templateUrl: './list.component.html', + imports: [UserComplexesComponent], +}) +export class SuperAdminUserComplexesComponent { + private readonly route = inject(ActivatedRoute); + private readonly breadcrumbService = inject(BreadcrumbService); + private readonly userStore = inject(UserStore); + private readonly businessStore = inject(BusinessActivityStore); + + pageParams = computed(() => pageParamsUtils(this.route)); + userId = signal(this.pageParams()['userId']); + businessId = signal(this.pageParams()['businessActivityId']); + + ngAfterViewInit() { + this.setBreadcrumb(); + } + + setBreadcrumb() { + this.breadcrumbService.setItems([ + { + ...usersNamedRoutes.users.meta, + routerLink: usersNamedRoutes.users.meta.pagePath!(), + }, + { + title: this.userStore.entity()?.fullname, + routerLink: usersNamedRoutes.user.meta.pagePath!(this.userId()), + }, + { + title: superAdminUserBusinessActivitiesNamedRoutes.businessActivities.meta.title, + routerLink: superAdminUserBusinessActivitiesNamedRoutes.businessActivities.meta.pagePath!( + this.userId(), + ), + }, + { + title: this.businessStore.entity()?.name, + routerLink: superAdminUserBusinessActivitiesNamedRoutes.businessActivity.meta.pagePath!( + this.userId(), + this.businessId(), + ), + }, + { + title: superAdminUserComplexesNamedRoutes.complexes.meta.title, + routerLink: superAdminUserComplexesNamedRoutes.complexes.meta.pagePath!( + this.userId(), + this.businessId(), + ), + }, + ]); + } +} diff --git a/src/app/domains/superAdmin/users/views/complexes/single.component.html b/src/app/domains/superAdmin/users/views/complexes/single.component.html new file mode 100644 index 0000000..93cb804 --- /dev/null +++ b/src/app/domains/superAdmin/users/views/complexes/single.component.html @@ -0,0 +1,23 @@ +
+ +
+
+ + + +
+
+
+ + + + +
diff --git a/src/app/domains/superAdmin/users/views/complexes/single.component.ts b/src/app/domains/superAdmin/users/views/complexes/single.component.ts new file mode 100644 index 0000000..51530c0 --- /dev/null +++ b/src/app/domains/superAdmin/users/views/complexes/single.component.ts @@ -0,0 +1,90 @@ +import { BreadcrumbService } from '@/core/services'; +import { AppCardComponent, KeyValueComponent } from '@/shared/components'; +import pageParamsUtils from '@/utils/page-params.utils'; +import { Component, computed, effect, inject, signal } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { UserComplexFormComponent } from '../../components/complexes/form.component'; +import { UserPosesComponent } from '../../components/poses/list.component'; +import { usersNamedRoutes } from '../../constants'; +import { superAdminUserBusinessActivitiesNamedRoutes } from '../../constants/routes/businessActivities'; +import { superAdminUserComplexesNamedRoutes } from '../../constants/routes/complexes'; +import { BusinessActivityStore } from '../../store/businessActivity.store'; +import { ComplexStore } from '../../store/complex.store'; +import { UserStore } from '../../store/user.store'; + +@Component({ + selector: 'superAdmin-user-complex', + templateUrl: './single.component.html', + imports: [AppCardComponent, KeyValueComponent, UserComplexFormComponent, UserPosesComponent], +}) +export class SuperAdminUserComplexComponent { + private readonly route = inject(ActivatedRoute); + private readonly breadcrumbService = inject(BreadcrumbService); + private readonly store = inject(ComplexStore); + private readonly userStore = inject(UserStore); + private readonly businessStore = inject(BusinessActivityStore); + + pageParams = computed(() => pageParamsUtils(this.route)); + + readonly userId = signal(this.pageParams()['userId']!); + readonly businessId = signal(this.pageParams()['businessActivityId']!); + readonly complexId = signal(this.pageParams()['complexId']!); + + editMode = signal(false); + + readonly loading = computed(() => this.store.loading()); + readonly complex = computed(() => this.store.entity()); + + constructor() { + effect(() => { + if (this.complex()?.id) { + this.setBreadcrumb(); + } + }); + } + + getData() { + this.store.getData(this.userId(), this.businessId(), this.complexId()); + } + + setBreadcrumb() { + this.breadcrumbService.setItems([ + { + ...usersNamedRoutes.users.meta, + routerLink: usersNamedRoutes.users.meta.pagePath!(), + }, + { + title: this.userStore.entity()?.fullname, + routerLink: usersNamedRoutes.user.meta.pagePath!(this.userId()), + }, + { + ...superAdminUserBusinessActivitiesNamedRoutes.businessActivities.meta, + routerLink: superAdminUserBusinessActivitiesNamedRoutes.businessActivities.meta.pagePath!( + this.userId(), + ), + }, + { + title: this.businessStore.entity()?.name, + routerLink: superAdminUserBusinessActivitiesNamedRoutes.businessActivity.meta.pagePath!( + this.userId(), + this.businessId(), + ), + }, + { + ...superAdminUserComplexesNamedRoutes.complexes.meta, + routerLink: superAdminUserComplexesNamedRoutes.complexes.meta.pagePath!( + this.userId(), + this.businessId(), + ), + }, + { + title: this.complex()?.name, + routerLink: superAdminUserComplexesNamedRoutes.complex.meta.pagePath!( + this.userId(), + this.businessId(), + this.complexId(), + ), + }, + ]); + } +} diff --git a/src/app/domains/superAdmin/users/views/poses/index.ts b/src/app/domains/superAdmin/users/views/poses/index.ts new file mode 100644 index 0000000..576a89e --- /dev/null +++ b/src/app/domains/superAdmin/users/views/poses/index.ts @@ -0,0 +1 @@ +export * from './list.component'; diff --git a/src/app/domains/superAdmin/users/views/poses/list.component.html b/src/app/domains/superAdmin/users/views/poses/list.component.html new file mode 100644 index 0000000..8303f40 --- /dev/null +++ b/src/app/domains/superAdmin/users/views/poses/list.component.html @@ -0,0 +1 @@ + diff --git a/src/app/domains/superAdmin/users/views/poses/list.component.ts b/src/app/domains/superAdmin/users/views/poses/list.component.ts new file mode 100644 index 0000000..42c4597 --- /dev/null +++ b/src/app/domains/superAdmin/users/views/poses/list.component.ts @@ -0,0 +1,86 @@ +// import { CatalogRoleTagComponent } from '@/shared/catalog/roles'; +import { BreadcrumbService } from '@/core/services'; +import pageParamsUtils from '@/utils/page-params.utils'; +import { Component, computed, inject, signal } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { UserPosesComponent } from '../../components/poses/list.component'; +import { usersNamedRoutes } from '../../constants'; +import { superAdminUserBusinessActivitiesNamedRoutes } from '../../constants/routes/businessActivities'; +import { superAdminUserComplexesNamedRoutes } from '../../constants/routes/complexes'; +import { superAdminUserPosesNamedRoutes } from '../../constants/routes/poses'; +import { BusinessActivityStore } from '../../store/businessActivity.store'; +import { ComplexStore } from '../../store/complex.store'; +import { UserStore } from '../../store/user.store'; + +@Component({ + selector: 'superAdmin-user-poses', + templateUrl: './list.component.html', + imports: [UserPosesComponent], +}) +export class SuperAdminUserPosesComponent { + private readonly route = inject(ActivatedRoute); + private readonly breadcrumbService = inject(BreadcrumbService); + private readonly userStore = inject(UserStore); + private readonly businessStore = inject(BusinessActivityStore); + private readonly complexStore = inject(ComplexStore); + + pageParams = computed(() => pageParamsUtils(this.route)); + userId = signal(this.pageParams()['userId']); + businessId = signal(this.pageParams()['businessActivityId']); + complexId = signal(this.pageParams()['complexId']); + + ngOnInit() { + this.setBreadcrumb(); + } + + setBreadcrumb() { + this.breadcrumbService.setItems([ + { + ...usersNamedRoutes.users.meta, + routerLink: usersNamedRoutes.users.meta.pagePath!(), + }, + { + title: this.userStore.entity()?.fullname, + routerLink: usersNamedRoutes.user.meta.pagePath!(this.userId()), + }, + { + title: superAdminUserBusinessActivitiesNamedRoutes.businessActivities.meta.title, + routerLink: superAdminUserBusinessActivitiesNamedRoutes.businessActivities.meta.pagePath!( + this.userId(), + ), + }, + { + title: this.businessStore.entity()?.name, + routerLink: superAdminUserBusinessActivitiesNamedRoutes.businessActivity.meta.pagePath!( + this.userId(), + this.businessId(), + ), + }, + + { + title: superAdminUserComplexesNamedRoutes.complexes.meta.title, + routerLink: superAdminUserComplexesNamedRoutes.complexes.meta.pagePath!( + this.userId(), + this.businessId(), + ), + }, + { + title: this.complexStore.entity()?.name, + routerLink: superAdminUserComplexesNamedRoutes.complex.meta.pagePath!( + this.userId(), + this.businessId(), + this.complexId(), + ), + }, + + { + title: superAdminUserPosesNamedRoutes.poses.meta.title, + routerLink: superAdminUserPosesNamedRoutes.poses.meta.pagePath!( + this.userId(), + this.businessId(), + this.complexId(), + ), + }, + ]); + } +} diff --git a/src/app/domains/superAdmin/users/views/poses/single.component.html b/src/app/domains/superAdmin/users/views/poses/single.component.html new file mode 100644 index 0000000..a79a1d4 --- /dev/null +++ b/src/app/domains/superAdmin/users/views/poses/single.component.html @@ -0,0 +1,20 @@ +
+ +
+
+ +
+
+
+ + +
diff --git a/src/app/domains/superAdmin/users/views/poses/single.component.ts b/src/app/domains/superAdmin/users/views/poses/single.component.ts new file mode 100644 index 0000000..b8be82a --- /dev/null +++ b/src/app/domains/superAdmin/users/views/poses/single.component.ts @@ -0,0 +1,112 @@ +import { BreadcrumbService } from '@/core/services'; +import { AppCardComponent, KeyValueComponent } from '@/shared/components'; +import pageParamsUtils from '@/utils/page-params.utils'; +import { Component, computed, effect, inject, signal } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { UserPosFormComponent } from '../../components/poses/form.component'; +import { usersNamedRoutes } from '../../constants'; +import { superAdminUserBusinessActivitiesNamedRoutes } from '../../constants/routes/businessActivities'; +import { superAdminUserComplexesNamedRoutes } from '../../constants/routes/complexes'; +import { superAdminUserPosesNamedRoutes } from '../../constants/routes/poses'; +import { BusinessActivityStore } from '../../store/businessActivity.store'; +import { ComplexStore } from '../../store/complex.store'; +import { PosStore } from '../../store/pos.store'; +import { UserStore } from '../../store/user.store'; + +@Component({ + selector: 'superAdmin-user-pos', + templateUrl: './single.component.html', + imports: [AppCardComponent, KeyValueComponent, UserPosFormComponent], +}) +export class SuperAdminUserPosComponent { + private readonly userStore = inject(UserStore); + private readonly businessStore = inject(BusinessActivityStore); + private readonly complexStore = inject(ComplexStore); + private readonly store = inject(PosStore); + private readonly route = inject(ActivatedRoute); + private readonly breadcrumbService = inject(BreadcrumbService); + + pageParams = computed(() => pageParamsUtils(this.route)); + + readonly userId = signal(this.pageParams()['userId']!); + readonly businessId = signal(this.pageParams()['businessActivityId']!); + readonly complexId = signal(this.pageParams()['complexId']!); + readonly posId = signal(this.pageParams()['posId']!); + editMode = signal(false); + + constructor() { + effect(() => { + if (this.pos()?.id) { + this.setBreadcrumb(); + } + }); + } + + readonly loading = computed(() => this.store.loading()); + readonly pos = computed(() => this.store.entity()); + + getData() { + this.store.getData(this.businessId(), this.complexId(), this.posId()); + } + + setBreadcrumb() { + this.breadcrumbService.setItems([ + { + ...usersNamedRoutes.users.meta, + routerLink: usersNamedRoutes.users.meta.pagePath!(), + }, + { + title: this.userStore.entity()?.fullname, + routerLink: usersNamedRoutes.user.meta.pagePath!(this.userId()), + }, + { + title: superAdminUserBusinessActivitiesNamedRoutes.businessActivities.meta.title, + routerLink: superAdminUserBusinessActivitiesNamedRoutes.businessActivities.meta.pagePath!( + this.userId(), + ), + }, + { + title: this.businessStore.entity()?.name, + routerLink: superAdminUserBusinessActivitiesNamedRoutes.businessActivity.meta.pagePath!( + this.userId(), + this.businessId(), + ), + }, + + { + title: superAdminUserComplexesNamedRoutes.complexes.meta.title, + routerLink: superAdminUserComplexesNamedRoutes.complexes.meta.pagePath!( + this.userId(), + this.businessId(), + ), + }, + { + title: this.complexStore.entity()?.name, + routerLink: superAdminUserComplexesNamedRoutes.complex.meta.pagePath!( + this.userId(), + this.businessId(), + this.complexId(), + ), + }, + + { + title: superAdminUserPosesNamedRoutes.poses.meta.title, + routerLink: superAdminUserPosesNamedRoutes.poses.meta.pagePath!( + this.userId(), + this.businessId(), + this.complexId(), + ), + }, + + { + title: this.pos()?.name, + routerLink: superAdminUserPosesNamedRoutes.pos.meta.pagePath!( + this.userId(), + this.businessId(), + this.complexId(), + this.posId(), + ), + }, + ]); + } +} diff --git a/src/app/domains/superAdmin/users/views/single.component.html b/src/app/domains/superAdmin/users/views/single.component.html index 44706c9..8bbcf81 100644 --- a/src/app/domains/superAdmin/users/views/single.component.html +++ b/src/app/domains/superAdmin/users/views/single.component.html @@ -8,6 +8,7 @@ + `${baseUrl}/guilds`, + providers: () => `${baseUrl}/providers`, + devices: () => `${baseUrl}/devices`, + deviceBrands: () => `${baseUrl}/device_brands`, +}; diff --git a/src/app/shared/catalog/deviceBrands/components/select.component.ts b/src/app/shared/catalog/deviceBrands/components/select.component.ts new file mode 100644 index 0000000..78b31a3 --- /dev/null +++ b/src/app/shared/catalog/deviceBrands/components/select.component.ts @@ -0,0 +1,34 @@ +import { IListingResponse } from '@/core/models/service.model'; +import ISummary from '@/core/models/summary'; +import { AbstractSelectComponent } from '@/shared/abstractClasses'; +import { UikitFieldComponent } from '@/uikit'; +import { Component, inject, Input } from '@angular/core'; +import { ReactiveFormsModule } from '@angular/forms'; +import { Select } from 'primeng/select'; +import { CatalogsService } from '../../service'; + +@Component({ + selector: 'catalog-deviceBrand-select', + templateUrl: '../../template.html', + imports: [UikitFieldComponent, Select, ReactiveFormsModule], +}) +export class CatalogDeviceBrandSelectComponent extends AbstractSelectComponent< + ISummary, + IListingResponse +> { + @Input() override showClear: boolean = false; + @Input() label: string = ''; + private readonly service = inject(CatalogsService); + + get preparedLabel() { + return this.label || 'انتخاب برند دستگاه'; + } + + ngOnInit() { + this.getData(); + } + + getDataService() { + return this.service.getDeviceBrands(); + } +} diff --git a/src/app/shared/catalog/deviceBrands/index.ts b/src/app/shared/catalog/deviceBrands/index.ts new file mode 100644 index 0000000..0ac8688 --- /dev/null +++ b/src/app/shared/catalog/deviceBrands/index.ts @@ -0,0 +1 @@ +export * from './components/select.component'; diff --git a/src/app/shared/catalog/devices/components/select.component.ts b/src/app/shared/catalog/devices/components/select.component.ts new file mode 100644 index 0000000..fbe5ede --- /dev/null +++ b/src/app/shared/catalog/devices/components/select.component.ts @@ -0,0 +1,34 @@ +import { IListingResponse } from '@/core/models/service.model'; +import ISummary from '@/core/models/summary'; +import { AbstractSelectComponent } from '@/shared/abstractClasses'; +import { UikitFieldComponent } from '@/uikit'; +import { Component, inject, Input } from '@angular/core'; +import { ReactiveFormsModule } from '@angular/forms'; +import { Select } from 'primeng/select'; +import { CatalogsService } from '../../service'; + +@Component({ + selector: 'catalog-device-select', + templateUrl: '../../template.html', + imports: [UikitFieldComponent, Select, ReactiveFormsModule], +}) +export class CatalogDeviceSelectComponent extends AbstractSelectComponent< + ISummary, + IListingResponse +> { + @Input() override showClear: boolean = false; + @Input() label: string = ''; + private readonly service = inject(CatalogsService); + + get preparedLabel() { + return this.label || 'انتخاب دستگاه'; + } + + ngOnInit() { + this.getData(); + } + + getDataService() { + return this.service.getDevices(); + } +} diff --git a/src/app/shared/catalog/devices/index.ts b/src/app/shared/catalog/devices/index.ts new file mode 100644 index 0000000..0ac8688 --- /dev/null +++ b/src/app/shared/catalog/devices/index.ts @@ -0,0 +1 @@ +export * from './components/select.component'; diff --git a/src/app/shared/catalog/guild/components/select.component.html b/src/app/shared/catalog/guild/components/select.component.html new file mode 100644 index 0000000..31cf852 --- /dev/null +++ b/src/app/shared/catalog/guild/components/select.component.html @@ -0,0 +1,13 @@ + + + diff --git a/src/app/shared/catalog/guild/components/select.component.ts b/src/app/shared/catalog/guild/components/select.component.ts new file mode 100644 index 0000000..b72d34f --- /dev/null +++ b/src/app/shared/catalog/guild/components/select.component.ts @@ -0,0 +1,30 @@ +import { IListingResponse } from '@/core/models/service.model'; +import ISummary from '@/core/models/summary'; +import { AbstractSelectComponent } from '@/shared/abstractClasses'; +import { UikitFieldComponent } from '@/uikit'; +import { Component, inject, Input } from '@angular/core'; +import { ReactiveFormsModule } from '@angular/forms'; +import { Select } from 'primeng/select'; +import { CatalogsService } from '../../service'; + +@Component({ + selector: 'catalog-guild-select', + templateUrl: './select.component.html', + imports: [UikitFieldComponent, Select, ReactiveFormsModule], +}) +export class CatalogGuildSelectComponent extends AbstractSelectComponent< + ISummary, + IListingResponse +> { + @Input() override showClear: boolean = false; + @Input() label: string = ''; + private readonly service = inject(CatalogsService); + + ngOnInit() { + this.getData(); + } + + getDataService() { + return this.service.getGuilds(); + } +} diff --git a/src/app/shared/catalog/guild/index.ts b/src/app/shared/catalog/guild/index.ts new file mode 100644 index 0000000..0ac8688 --- /dev/null +++ b/src/app/shared/catalog/guild/index.ts @@ -0,0 +1 @@ +export * from './components/select.component'; diff --git a/src/app/shared/catalog/index.ts b/src/app/shared/catalog/index.ts index e69de29..bab7efc 100644 --- a/src/app/shared/catalog/index.ts +++ b/src/app/shared/catalog/index.ts @@ -0,0 +1,3 @@ +export * from './devices'; +export * from './guild'; +export * from './providers'; diff --git a/src/app/shared/catalog/providers/components/select.component.ts b/src/app/shared/catalog/providers/components/select.component.ts new file mode 100644 index 0000000..d3801f7 --- /dev/null +++ b/src/app/shared/catalog/providers/components/select.component.ts @@ -0,0 +1,34 @@ +import { IListingResponse } from '@/core/models/service.model'; +import ISummary from '@/core/models/summary'; +import { AbstractSelectComponent } from '@/shared/abstractClasses'; +import { UikitFieldComponent } from '@/uikit'; +import { Component, inject, Input } from '@angular/core'; +import { ReactiveFormsModule } from '@angular/forms'; +import { Select } from 'primeng/select'; +import { CatalogsService } from '../../service'; + +@Component({ + selector: 'catalog-provider-select', + templateUrl: '../../template.html', + imports: [UikitFieldComponent, Select, ReactiveFormsModule], +}) +export class CatalogProviderSelectComponent extends AbstractSelectComponent< + ISummary, + IListingResponse +> { + @Input() override showClear: boolean = false; + @Input() label: string = ''; + private readonly service = inject(CatalogsService); + + get preparedLabel() { + return this.label || 'انتخاب ارایه‌دهنده'; + } + + ngOnInit() { + this.getData(); + } + + getDataService() { + return this.service.getProviders(); + } +} diff --git a/src/app/shared/catalog/providers/index.ts b/src/app/shared/catalog/providers/index.ts new file mode 100644 index 0000000..0ac8688 --- /dev/null +++ b/src/app/shared/catalog/providers/index.ts @@ -0,0 +1 @@ +export * from './components/select.component'; diff --git a/src/app/shared/catalog/service.ts b/src/app/shared/catalog/service.ts new file mode 100644 index 0000000..d187a2e --- /dev/null +++ b/src/app/shared/catalog/service.ts @@ -0,0 +1,29 @@ +import { IListingResponse } from '@/core/models/service.model'; +import ISummary from '@/core/models/summary'; +import { HttpClient } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; +import { CATALOG_API_ROUTES } from './apiRoutes'; + +@Injectable({ providedIn: 'root' }) +export class CatalogsService { + constructor(private http: HttpClient) {} + + private apiRoutes = CATALOG_API_ROUTES; + + getGuilds(): Observable> { + return this.http.get>(this.apiRoutes.guilds()); + } + + getProviders(): Observable> { + return this.http.get>(this.apiRoutes.providers()); + } + + getDevices(): Observable> { + return this.http.get>(this.apiRoutes.devices()); + } + + getDeviceBrands(): Observable> { + return this.http.get>(this.apiRoutes.deviceBrands()); + } +} diff --git a/src/app/shared/catalog/template.html b/src/app/shared/catalog/template.html new file mode 100644 index 0000000..28a428a --- /dev/null +++ b/src/app/shared/catalog/template.html @@ -0,0 +1,13 @@ + + + diff --git a/src/app/shared/components/input/input.component.html b/src/app/shared/components/input/input.component.html index 4a01988..c525cea 100644 --- a/src/app/shared/components/input/input.component.html +++ b/src/app/shared/components/input/input.component.html @@ -1,42 +1,48 @@ @if (type === "switch") { - } @else if (type === "price") { - - - ریال - } @else { - + + + @if (type === "price") { + + + } @else { + + } + @if (preparedSuffix()) { + {{ preparedSuffix() }} + } + } @if (hint) { {{ hint }} diff --git a/src/app/shared/components/input/input.component.ts b/src/app/shared/components/input/input.component.ts index f19ac29..fca544d 100644 --- a/src/app/shared/components/input/input.component.ts +++ b/src/app/shared/components/input/input.component.ts @@ -1,12 +1,15 @@ import { Maybe } from '@/core'; +import { ToastService } from '@/core/services/toast.service'; import { UikitFieldComponent } from '@/uikit/uikit-field.component'; import { CommonModule } from '@angular/common'; -import { Component, EventEmitter, Input, Output } from '@angular/core'; +import { Component, computed, EventEmitter, inject, Input, Output } from '@angular/core'; import { FormControl, ReactiveFormsModule, Validators } from '@angular/forms'; import { InputGroupModule } from 'primeng/inputgroup'; import { InputGroupAddon } from 'primeng/inputgroupaddon'; +import { InputMaskModule } from 'primeng/inputmask'; import { InputNumberModule } from 'primeng/inputnumber'; import { InputTextModule } from 'primeng/inputtext'; +import { KeyFilterModule } from 'primeng/keyfilter'; import { ToggleSwitch } from 'primeng/toggleswitch'; @Component({ @@ -21,6 +24,8 @@ import { ToggleSwitch } from 'primeng/toggleswitch'; ToggleSwitch, InputGroupAddon, InputNumberModule, + KeyFilterModule, + InputMaskModule, ], templateUrl: './input.component.html', }) @@ -33,27 +38,43 @@ export class InputComponent { | 'email' | 'checkbox' | 'switch' + | 'number' | 'price' = 'simple'; @Input() control!: FormControl>; @Input() name!: string; @Input() label: string = ''; - @Input() customPlaceholder?: string; + @Input() placeholder?: string; @Input() required = false; @Input() disabled = false; @Input() size?: 'small' | 'large'; @Input() autocomplete?: string = 'off'; - @Input() showErrors = false; + @Input() showErrors = true; @Input() hint?: string; + @Input() isLtrInput = false; + @Input() suffix: string = ''; + @Input() maxLength?: number; + @Input() min?: number; + @Input() max?: number; @Output() valueChange = new EventEmitter(); @Output() blur = new EventEmitter(); - onInput(ev: Event) { - const v = (ev.target as HTMLInputElement).value; - this.valueChange.emit(this.type === 'price' ? parseFloat(v) : v); - } + private readonly toastService = inject(ToastService); - get placeholder(): string | null { - if (this.customPlaceholder) return this.customPlaceholder; + // onInput(ev: Event) { + // const v = (ev.target as HTMLInputElement).value; + + // const newLocal = v || v == '0'; + // // this.valueChange.emit(this.type === 'price' && newLocal ? parseFloat(v) : v); + // } + + preparedSuffix = computed(() => { + if (this.type === 'price') { + return 'ریال'; + } else return this.suffix; + }); + + get preparedPlaceholder(): string | null { + if (this.placeholder) return this.placeholder; switch (this.type) { case 'mobile': return '09xxxxxxxx'; @@ -76,13 +97,18 @@ export class InputComponent { case 'phone': case 'postalCode': case 'price': + case 'number': return 'numeric'; default: return 'text'; } } - get maxLength(): number | null { + get isNumeric(): boolean { + return this.inputMode === 'numeric'; + } + + get preparedMaxLength(): number | null { switch (this.type) { case 'mobile': return 11; @@ -91,28 +117,45 @@ export class InputComponent { case 'phone': return 11; default: - return null; + return this.maxLength || null; } } get inputClass(): string { + let inputClass = []; switch (this.type) { case 'mobile': case 'phone': case 'price': - return 'ltrInput'; + case 'number': + inputClass.push('ltrInput'); + break; case 'email': case 'postalCode': - return 'ltrInput rtlPlaceholder'; - default: - return ''; + inputClass.push('ltrInput', 'rtlPlaceholder'); + break; } + + if (this.isLtrInput) { + inputClass.push('ltrInput', 'rtlPlaceholder'); + } + return inputClass.join(' '); } get htmlType(): string { switch (this.type) { case 'email': return 'email'; + case 'mobile': + case 'phone': + case 'price': + case 'postalCode': + case 'number': + return 'number'; + case 'checkbox': + return 'checkbox'; + case 'switch': + return 'radio'; default: return 'text'; } @@ -121,4 +164,40 @@ export class InputComponent { get isRequired(): boolean { return this.required || this.control.hasValidator(Validators.required); } + + onInput($event: Event) { + // @ts-ignore + const value = $event.target.value as string; + if (this.type === 'number') { + let newValue = parseFloat(value); + + const minValidator = (this.min || this.min === 0) && parseFloat(value) < this.min!; + const maxValidator = (this.max || this.max === 0) && parseFloat(value) > this.max; + + if (minValidator || maxValidator) { + if (minValidator) { + this.toastService.warn({ + text: `مقدار فیلد باید بیشتر از ${this.min} باشد.`, + }); + } + if (maxValidator) { + this.toastService.warn({ + text: `مقدار فیلد باید کمتر از ${this.max} باشد.`, + }); + } + + newValue = parseFloat(value.slice(0, value.length - 1)); + // @ts-ignore + $event.target.value = newValue; + } + this.control.setValue(newValue); + } + + if (this.preparedMaxLength && this.preparedMaxLength < value.length) { + let newValue = value.slice(0, value.length - 1); + // @ts-ignore + $event.target.value = newValue; + this.control.setValue(newValue); + } + } } diff --git a/src/app/shared/components/pageDataList/page-data-list.component.html b/src/app/shared/components/pageDataList/page-data-list.component.html index a340bb7..ad118e7 100644 --- a/src/app/shared/components/pageDataList/page-data-list.component.html +++ b/src/app/shared/components/pageDataList/page-data-list.component.html @@ -94,7 +94,7 @@ - + - @for (i of [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; track i) { diff --git a/src/app/shared/components/pageDataList/page-data-list.component.ts b/src/app/shared/components/pageDataList/page-data-list.component.ts index 8fab474..881aeb8 100644 --- a/src/app/shared/components/pageDataList/page-data-list.component.ts +++ b/src/app/shared/components/pageDataList/page-data-list.component.ts @@ -150,10 +150,7 @@ export class PageDataListComponent { if (!path) return '-'; const nestedData = path .split('.') - .reduce( - (obj, key) => (obj && obj[key] !== undefined ? obj[key] : null), - item[String(field)], - ); + .reduce((obj, key) => (obj && obj[key] !== undefined ? obj[key] : null), item); return nestedData || '-'; } diff --git a/src/app/utils/index.ts b/src/app/utils/index.ts index b3d1f7f..71ff882 100644 --- a/src/app/utils/index.ts +++ b/src/app/utils/index.ts @@ -1,5 +1,6 @@ export * from './currency'; export * from './jalali-date.utils'; export * from './name'; +export * from './page-params.utils'; export * from './price-mask.utils'; export * from './time'; diff --git a/src/app/utils/page-params.utils.ts b/src/app/utils/page-params.utils.ts new file mode 100644 index 0000000..6d04d94 --- /dev/null +++ b/src/app/utils/page-params.utils.ts @@ -0,0 +1,19 @@ +import { Maybe } from '@/core'; +import { ActivatedRoute } from '@angular/router'; + +export default (activatedRoute: ActivatedRoute) => { + let currentRoute = activatedRoute as Maybe; + let allParams: Record = {}; + + while (currentRoute) { + allParams = { ...allParams, ...currentRoute.snapshot.params }; + + if (currentRoute.parent) { + currentRoute = currentRoute.parent; + } else { + currentRoute = null; + } + } + + return allParams; +};