refactor: update terminology from "مشتری" to "مودی" and "ارایه‌دهنده" to "PSP" across the application
Production CI / validate-and-build (push) Failing after 1m6s

- Updated column headers and labels in various components and constants to reflect the new terminology.
- Changed the titles and placeholders in forms and dialogs to use "مودی" and "PSP".
- Adjusted routing titles and menu items to align with the new naming conventions.
- Refactored related constants and configurations to ensure consistency throughout the application.
This commit is contained in:
2026-06-16 15:47:23 +03:30
parent 151eff2f7c
commit ea458c7b72
42 changed files with 148 additions and 153 deletions
@@ -10,7 +10,7 @@ export const columns: IColumn[] = [
{ field: 'device', header: 'دستگاه', type: 'nested', nestedOption: { path: 'device.name' } }, { field: 'device', header: 'دستگاه', type: 'nested', nestedOption: { path: 'device.name' } },
{ {
field: 'provider', field: 'provider',
header: 'ارایه‌دهنده', header: 'PSP',
type: 'nested', type: 'nested',
nestedOption: { path: 'provider.name' }, nestedOption: { path: 'provider.name' },
}, },
@@ -10,7 +10,7 @@
<app-key-value label="شماره سریال" [value]="pos()?.serial_number" /> <app-key-value label="شماره سریال" [value]="pos()?.serial_number" />
<app-key-value label="نوع دستگاه" [value]="pos()?.device?.name" /> <app-key-value label="نوع دستگاه" [value]="pos()?.device?.name" />
<app-key-value label="مدل دستگاه" [value]="pos()?.model" /> <app-key-value label="مدل دستگاه" [value]="pos()?.model" />
<app-key-value label="ارایه‌دهنده" [value]="pos()?.provider?.name" /> <app-key-value label="PSP" [value]="pos()?.provider?.name" />
</div> </div>
</div> </div>
</app-card-data> </app-card-data>
@@ -10,7 +10,7 @@
<app-key-value label="شماره سریال" [value]="pos()?.serial_number" /> <app-key-value label="شماره سریال" [value]="pos()?.serial_number" />
<app-key-value label="نوع دستگاه" [value]="pos()?.device?.name" /> <app-key-value label="نوع دستگاه" [value]="pos()?.device?.name" />
<app-key-value label="مدل دستگاه" [value]="pos()?.model" /> <app-key-value label="مدل دستگاه" [value]="pos()?.model" />
<app-key-value label="ارایه‌دهنده" [value]="pos()?.provider?.name" /> <app-key-value label="PSP" [value]="pos()?.provider?.name" />
</div> </div>
</div> </div>
</app-card-data> </app-card-data>
@@ -8,7 +8,7 @@ export const PARTNER_MENU_ITEMS = [
routerLink: ['/partner'], routerLink: ['/partner'],
}, },
{ {
label: شتری', label: ودی',
icon: 'pi pi-fw pi-users', icon: 'pi pi-fw pi-users',
routerLink: ['/partner/consumers'], routerLink: ['/partner/consumers'],
}, },
@@ -1,11 +1,10 @@
<shared-dialog <shared-dialog
header="افزودن مشتری" header="افزودن مودی"
[(visible)]="visible" [(visible)]="visible"
[modal]="true" [modal]="true"
[style]="{ width: '640px' }" [style]="{ width: '640px' }"
[closable]="true" [closable]="true"
(onHide)="close()" (onHide)="close()">
>
<p-stepper [value]="activeStep()" [linear]="true"> <p-stepper [value]="activeStep()" [linear]="true">
<p-step-list> <p-step-list>
<p-step [value]="1">اطلاعات اولیه</p-step> <p-step [value]="1">اطلاعات اولیه</p-step>
@@ -24,16 +23,14 @@
<partner-consumer-businessActivities-form-content <partner-consumer-businessActivities-form-content
[consumerId]="consumer()?.id || ''" [consumerId]="consumer()?.id || ''"
(onSubmit)="onBusinessActivitySubmit($event)" (onSubmit)="onBusinessActivitySubmit($event)"
(onClose)="close()" (onClose)="close()" />
/>
} }
@case (3) { @case (3) {
<partner-consumer-complex-form-content <partner-consumer-complex-form-content
[consumerId]="consumer()?.id || ''" [consumerId]="consumer()?.id || ''"
[businessActivityId]="businessActivity()?.id || ''" [businessActivityId]="businessActivity()?.id || ''"
(onSubmit)="onComplexSubmit($event)" (onSubmit)="onComplexSubmit($event)"
(onClose)="close()" (onClose)="close()" />
/>
} }
@case (4) { @case (4) {
<partner-consumer-pos-form-content <partner-consumer-pos-form-content
@@ -41,8 +38,7 @@
[businessActivityId]="businessActivity()?.id || ''" [businessActivityId]="businessActivity()?.id || ''"
[complexId]="complex()?.id || ''" [complexId]="complex()?.id || ''"
(onSubmit)="onPosSubmit($event)" (onSubmit)="onPosSubmit($event)"
(onClose)="close()" (onClose)="close()" />
/>
} }
} }
</div> </div>
@@ -17,7 +17,7 @@ export class ConsumerUserFormDialogComponent extends AbstractDialog {
@Input() consumerId?: string; @Input() consumerId?: string;
get preparedTitle() { get preparedTitle() {
return `${this.editMode ? 'ویرایش' : 'افزودن'} مشتری`; return `${this.editMode ? 'ویرایش' : 'افزودن'} مودی`;
} }
onFormSubmit(response: IPartnerConsumerResponse) { onFormSubmit(response: IPartnerConsumerResponse) {
@@ -10,7 +10,7 @@ export const partnerConsumersNamedRoutes: NamedRoutes<TConsumersRouteNames> = {
path: 'consumers', path: 'consumers',
loadComponent: () => import('../../views/list.component').then((m) => m.ConsumersComponent), loadComponent: () => import('../../views/list.component').then((m) => m.ConsumersComponent),
meta: { meta: {
title: شتری‌ها', title: ودیان',
pagePath: () => '/partner/consumers', pagePath: () => '/partner/consumers',
}, },
}, },
@@ -18,7 +18,7 @@ export const partnerConsumersNamedRoutes: NamedRoutes<TConsumersRouteNames> = {
path: 'consumers/:consumerId', path: 'consumers/:consumerId',
loadComponent: () => import('../../views/single.component').then((m) => m.ConsumerComponent), loadComponent: () => import('../../views/single.component').then((m) => m.ConsumerComponent),
meta: { meta: {
title: شتری', title: ودی',
pagePath: (guildId: string) => `/partner/consumers/${guildId}`, pagePath: (guildId: string) => `/partner/consumers/${guildId}`,
}, },
}, },
@@ -1,10 +1,10 @@
<app-page-data-list <app-page-data-list
pageTitle=شتری‌ها" pageTitle=ودیان"
[addNewCtaLabel]="'افزودن مشتری'" [addNewCtaLabel]="'افزودن مودی'"
[columns]="columns" [columns]="columns"
[showAdd]="true" [showAdd]="true"
emptyPlaceholderTitle=شتری یافت نشد" emptyPlaceholderTitle=ودی یافت نشد"
emptyPlaceholderDescription="برای افزودن مشتری، روی دکمهٔ بالا کلیک کنید." emptyPlaceholderDescription="برای افزودن مودی، روی دکمهٔ بالا کلیک کنید."
[items]="items()" [items]="items()"
[loading]="loading()" [loading]="loading()"
[showDetails]="true" [showDetails]="true"
@@ -1,10 +1,10 @@
<div class="flex flex-col gap-4"> <div class="flex flex-col gap-4">
<app-card-data cardTitle="اطلاعات مشتری" [editable]="true" [(editMode)]="editMode"> <app-card-data cardTitle="اطلاعات مودی" [editable]="true" [(editMode)]="editMode">
<ng-template #moreActions> </ng-template> <ng-template #moreActions> </ng-template>
<div class="flex flex-col gap-4"> <div class="flex flex-col gap-4">
<div class="listKeyValue"> <div class="listKeyValue">
<app-key-value label="نام مشتری" [value]="consumer()?.name" /> <app-key-value label="نام" [value]="consumer()?.name" />
<app-key-value label="نوع مشتری" [value]="consumer()?.type?.translate" /> <app-key-value label="نوع" [value]="consumer()?.type?.translate" />
@if (consumer()?.type?.value === 'LEGAL') { @if (consumer()?.type?.value === 'LEGAL') {
<app-key-value label="شناسه ملی" [value]="consumer()?.legal?.registration_code" /> <app-key-value label="شناسه ملی" [value]="consumer()?.legal?.registration_code" />
} @else { } @else {
@@ -1,7 +1,7 @@
<div class="flex flex-col gap-4 w-full"> <div class="flex w-full flex-col gap-4">
<uikit-field label="بر اساس نام مشتری" name="search" class="w-full"> <uikit-field label="بر اساس نام مودی" name="search" class="w-full">
<p-inputgroup class="w-full"> <p-inputgroup class="w-full">
<input pInputText [(ngModel)]="search" placeholder="جستجوی نام مشتری" (ngModelChange)="onFilterChange($event)" /> <input pInputText [(ngModel)]="search" placeholder="جستجوی نام مودی" (ngModelChange)="onFilterChange($event)" />
<p-inputgroup-addon> <p-inputgroup-addon>
<p-button icon="pi pi-times" severity="secondary" (onClick)="clearSearch()"></p-button> <p-button icon="pi pi-times" severity="secondary" (onClick)="clearSearch()"></p-button>
</p-inputgroup-addon> </p-inputgroup-addon>
@@ -18,7 +18,7 @@ export class PartnerLicenseListComponent extends AbstractList<ILicenseResponse>
// { field: 'id', header: 'شناسه', type: 'id' }, // { field: 'id', header: 'شناسه', type: 'id' },
{ {
field: 'business_activity', field: 'business_activity',
header: 'عنوان مشتری', header: 'مودی',
type: 'nested', type: 'nested',
nestedOption: { nestedOption: {
path: 'business_activity.consumer.name', path: 'business_activity.consumer.name',
@@ -1,10 +0,0 @@
<app-card-data cardTitle="تغییر رمز عبور" [editable]="false">
<form [formGroup]="form" (submit)="submit()" class="mx-auto max-w-lg">
<shared-password-input
[passwordControl]="form.controls.password"
[confirmPasswordControl]="form.controls.confirmPassword" />
<button type="submit" pButton [disabled]="form.invalid || loading()" class="mx-auto w-full max-w-xs">
تغییر رمز عبور
</button>
</form>
</app-card-data>
@@ -1,46 +0,0 @@
import { ToastService } from '@/core/services/toast.service';
import { MustMatch } from '@/core/validators';
import { AppCardComponent, SharedPasswordInputComponent } from '@/shared/components';
import { fieldControl } from '@/shared/constants';
import { Component, inject, signal } from '@angular/core';
import { FormBuilder, ReactiveFormsModule } from '@angular/forms';
import { ButtonDirective } from 'primeng/button';
import { finalize } from 'rxjs';
import { ProfileService } from '../services/main.service';
@Component({
selector: 'partner-reset-password-card',
templateUrl: './reset-password-card.component.html',
imports: [ReactiveFormsModule, AppCardComponent, SharedPasswordInputComponent, ButtonDirective],
})
export class PartnerResetPasswordCardComponent {
private readonly service = inject(ProfileService);
private readonly fb = inject(FormBuilder);
private readonly toastService = inject(ToastService);
readonly loading = signal(false);
form = this.fb.group(
{
password: fieldControl.password(),
confirmPassword: fieldControl.confirmPassword(),
},
{ validators: [MustMatch('password', 'confirmPassword')] }
);
submit() {
if (this.form.invalid) {
this.form.markAllAsTouched();
return;
}
this.loading.set(true);
this.service
.resetPassword({ password: this.form.value.password as string })
.pipe(finalize(() => this.loading.set(false)))
.subscribe(() => {
this.form.reset();
this.toastService.success({ text: 'رمز عبور با موفقیت به‌روز شد.' });
});
}
}
@@ -12,5 +12,6 @@ export interface IProfileRequestPayload {
} }
export interface IResetPasswordRequest { export interface IResetPasswordRequest {
currentPassword: string;
password: string; password: string;
} }
@@ -1,5 +1,10 @@
<div class="flex flex-col gap-4"> <div class="flex flex-col gap-4">
<app-card-data cardTitle="اطلاعات پروفایل" [editable]="true" [(editMode)]="editing"> <app-card-data cardTitle="اطلاعات پروفایل" [editable]="true" [(editMode)]="editing">
<ng-template #moreActions>
<p-button type="button" variant="outlined" size="small" (onClick)="openResetPasswordDialog()">
تغییر گذرواژه
</p-button>
</ng-template>
<div class="listKeyValue"> <div class="listKeyValue">
<app-key-value label="تصویر" [value]="profile()?.logo_url" type="thumbnail" /> <app-key-value label="تصویر" [value]="profile()?.logo_url" type="thumbnail" />
<app-key-value label="عنوان" [value]="profile()?.name" /> <app-key-value label="عنوان" [value]="profile()?.name" />
@@ -7,9 +12,13 @@
</div> </div>
</app-card-data> </app-card-data>
<partner-reset-password-card />
@if (editing()) { @if (editing()) {
<partner-profile-form [(visible)]="editing" [initialValues]="profile()!" (onSubmit)="onEditSuccess()" /> <partner-profile-form [(visible)]="editing" [initialValues]="profile()!" (onSubmit)="onEditSuccess()" />
} }
</div> </div>
<shared-change-password-form-dialog
[(visible)]="resetPasswordDialog"
[showCurrentPasswordField]="true"
[loading]="resetPasswordLoading()"
(onSubmit)="resetPassword($event)" />
@@ -1,8 +1,16 @@
import { ToastService } from '@/core/services/toast.service';
import { PartnerStore } from '@/domains/partner/store/main.store'; import { PartnerStore } from '@/domains/partner/store/main.store';
import { AppCardComponent, KeyValueComponent } from '@/shared/components'; import {
AppCardComponent,
ChangePasswordFormDialogComponent,
KeyValueComponent,
} from '@/shared/components';
import { Component, computed, inject, signal } from '@angular/core'; import { Component, computed, inject, signal } from '@angular/core';
import { Button } from 'primeng/button';
import { finalize } from 'rxjs';
import { PartnerProfileFormComponent } from '../components/form.component'; import { PartnerProfileFormComponent } from '../components/form.component';
import { PartnerResetPasswordCardComponent } from '../components/reset-password-card.component'; import { IResetPasswordRequest } from '../models';
import { ProfileService } from '../services/main.service';
@Component({ @Component({
selector: 'partner-profile', selector: 'partner-profile',
@@ -10,17 +18,22 @@ import { PartnerResetPasswordCardComponent } from '../components/reset-password-
imports: [ imports: [
AppCardComponent, AppCardComponent,
KeyValueComponent, KeyValueComponent,
PartnerResetPasswordCardComponent,
PartnerProfileFormComponent, PartnerProfileFormComponent,
Button,
ChangePasswordFormDialogComponent,
], ],
}) })
export class PartnerProfileComponent { export class PartnerProfileComponent {
private readonly store = inject(PartnerStore); private readonly store = inject(PartnerStore);
private readonly service = inject(ProfileService);
private readonly toastService = inject(ToastService);
readonly resetPasswordLoading = signal(false);
editing = signal(false);
resetPasswordDialog = signal(false);
readonly profile = computed(() => this.store.entity()); readonly profile = computed(() => this.store.entity());
editing = signal(false);
edit() { edit() {
this.editing.set(true); this.editing.set(true);
} }
@@ -28,4 +41,21 @@ export class PartnerProfileComponent {
onEditSuccess() { onEditSuccess() {
this.store.getData(); this.store.getData();
} }
openResetPasswordDialog() {
this.resetPasswordDialog.set(true);
}
resetPassword(payload: IResetPasswordRequest) {
this.resetPasswordLoading.set(true);
this.service
.resetPassword(payload)
.pipe(finalize(() => this.resetPasswordLoading.set(false)))
.subscribe(() => {
this.toastService.success({
text: 'تغییر رمز عبور با موفقیت انجام شد.',
});
this.resetPasswordDialog.set(false);
});
}
} }
@@ -2,6 +2,11 @@
<app-inner-pages-header [pageTitle]="preparedPageTitle()" [backRoute]="backRoute" /> <app-inner-pages-header [pageTitle]="preparedPageTitle()" [backRoute]="backRoute" />
<hr class="mt-0!" /> <hr class="mt-0!" />
<div class="flex w-full flex-col flex-wrap gap-3 p-4"> <div class="flex w-full flex-col flex-wrap gap-3 p-4">
<shared-good-form [guildId]="guildId()" [createFn]="createFn" (onSubmit)="onSubmit()" (onClose)="onPrev()" /> <shared-good-form
[guildId]="guildId()"
[createFn]="createFn"
class="block w-full"
(onSubmit)="onSubmit()"
(onClose)="onPrev()" />
</div> </div>
</div> </div>
@@ -9,6 +9,7 @@
[initialValues]="item()!" [initialValues]="item()!"
[updateFn]="updateFn" [updateFn]="updateFn"
[editMode]="true" [editMode]="true"
class="block w-full"
(onSubmit)="onSubmit()" (onSubmit)="onSubmit()"
(onClose)="onPrev()" /> (onClose)="onPrev()" />
} }
@@ -1,3 +1,3 @@
<div class="flex items-center justify-center h-svh w-svw"> <div class="flex h-svh w-svw items-center justify-center">
<span class="text-center"> به پنل ارایه‌دهنده خوش آمدید </span> <span class="text-center"> به پنل PSP خوش آمدید </span>
</div> </div>
@@ -8,7 +8,7 @@ export const SUPER_ADMIN_MENU_ITEMS = [
routerLink: ['/'], routerLink: ['/'],
}, },
// { // {
// label: 'مشتری‌', // label: 'مودی',
// icon: 'pi pi-fw pi-id-card', // icon: 'pi pi-fw pi-id-card',
// routerLink: ['/super_admin/consumers'], // routerLink: ['/super_admin/consumers'],
// }, // },
@@ -19,7 +19,7 @@ export const SUPER_ADMIN_MENU_ITEMS = [
routerLink: ['/super_admin/partners'], routerLink: ['/super_admin/partners'],
}, },
{ {
label: 'ارایه‌دهنده', label: 'PSP',
icon: 'pi pi-fw pi-building-columns', icon: 'pi pi-fw pi-building-columns',
routerLink: ['/super_admin/providers'], routerLink: ['/super_admin/providers'],
}, },
@@ -29,7 +29,7 @@ export class ConsumerUserFormComponent extends AbstractFormDialog<
@Input() consumerId?: string; @Input() consumerId?: string;
private service = inject(ConsumersService); private service = inject(ConsumersService);
preparedTitle = computed(() => `${this.editMode ? 'ویرایش' : 'افزودن'} مشتری`); preparedTitle = computed(() => `${this.editMode ? 'ویرایش' : 'افزودن'} مودی`);
initForm = () => { initForm = () => {
const form = this.fb.group({ const form = this.fb.group({
@@ -63,7 +63,7 @@ export class ConsumerUserFormComponent extends AbstractFormDialog<
this.fb.control<string>('', { this.fb.control<string>('', {
nonNullable: true, nonNullable: true,
validators: fieldControl.username('')[1], validators: fieldControl.username('')[1],
}), })
); );
// @ts-ignore // @ts-ignore
form.addControl( form.addControl(
@@ -71,7 +71,7 @@ export class ConsumerUserFormComponent extends AbstractFormDialog<
this.fb.control<string>('', { this.fb.control<string>('', {
nonNullable: true, nonNullable: true,
validators: [Validators.required], validators: [Validators.required],
}), })
); );
// @ts-ignore // @ts-ignore
form.addControl( form.addControl(
@@ -79,7 +79,7 @@ export class ConsumerUserFormComponent extends AbstractFormDialog<
this.fb.control<string>('', { this.fb.control<string>('', {
nonNullable: true, nonNullable: true,
validators: [Validators.required], validators: [Validators.required],
}), })
); );
form.addValidators([MustMatch('password', 'confirmPassword')]); form.addValidators([MustMatch('password', 'confirmPassword')]);
} }
@@ -29,7 +29,7 @@ export class ConsumerPosesComponent extends AbstractList<IPosResponse> {
{ field: 'pos_type', header: 'نوع دستگاه' }, { field: 'pos_type', header: 'نوع دستگاه' },
{ {
field: 'provider', field: 'provider',
header: 'ارایه‌دهنده', header: 'PSP',
type: 'nested', type: 'nested',
nestedOption: { path: 'provider.name' }, nestedOption: { path: 'provider.name' },
}, },
@@ -58,8 +58,8 @@ export class ConsumerPosesComponent extends AbstractList<IPosResponse> {
this.consumerId, this.consumerId,
this.businessId, this.businessId,
this.complexId, this.complexId,
item.id, item.id
), )
); );
} }
} }
@@ -10,7 +10,7 @@ export const superAdminConsumersNamedRoutes: NamedRoutes<TConsumersRouteNames> =
path: 'consumers', path: 'consumers',
loadComponent: () => import('../../views/list.component').then((m) => m.ConsumersComponent), loadComponent: () => import('../../views/list.component').then((m) => m.ConsumersComponent),
meta: { meta: {
title: شتری‌ها', title: ودیان',
pagePath: () => '/super_admin/consumers', pagePath: () => '/super_admin/consumers',
}, },
}, },
@@ -18,7 +18,7 @@ export const superAdminConsumersNamedRoutes: NamedRoutes<TConsumersRouteNames> =
path: 'consumers/:consumerId', path: 'consumers/:consumerId',
loadComponent: () => import('../../views/single.component').then((m) => m.ConsumerComponent), loadComponent: () => import('../../views/single.component').then((m) => m.ConsumerComponent),
meta: { meta: {
title: شتری', title: ودی',
pagePath: (guildId: string) => `/super_admin/consumers/${guildId}`, pagePath: (guildId: string) => `/super_admin/consumers/${guildId}`,
}, },
}, },
@@ -1,19 +1,17 @@
<app-page-data-list <app-page-data-list
pageTitle="مدیریت مشتری‌ها" pageTitle="مدیریت مودیان"
[columns]="columns" [columns]="columns"
emptyPlaceholderTitle=شتری یافت نشد" emptyPlaceholderTitle=ودی یافت نشد"
[items]="items()" [items]="items()"
[loading]="loading()" [loading]="loading()"
[showDetails]="true" [showDetails]="true"
(onAdd)="openAddForm()" (onAdd)="openAddForm()"
(onDetails)="toSinglePage($event)" (onDetails)="toSinglePage($event)"
(onEdit)="onEditClick($event)" (onEdit)="onEditClick($event)"
(onRefresh)="refresh()" (onRefresh)="refresh()" />
/>
<superAdmin-consumer-form <superAdmin-consumer-form
[(visible)]="visibleForm" [(visible)]="visibleForm"
[editMode]="editMode()" [editMode]="editMode()"
[consumerId]="selectedItemForEdit()?.id" [consumerId]="selectedItemForEdit()?.id"
[initialValues]="selectedItemForEdit() || undefined" [initialValues]="selectedItemForEdit() || undefined"
(onSubmit)="refresh()" (onSubmit)="refresh()" />
/>
@@ -1,10 +1,10 @@
<div class="flex flex-col gap-4"> <div class="flex flex-col gap-4">
<app-card-data cardTitle="اطلاعات مشتری" [(editMode)]="editMode"> <app-card-data cardTitle="اطلاعات مودی" [(editMode)]="editMode">
<ng-template #moreActions> </ng-template> <ng-template #moreActions> </ng-template>
<div class="flex flex-col gap-4"> <div class="flex flex-col gap-4">
<div class="listKeyValue"> <div class="listKeyValue">
<app-key-value label="نام مشتری" [value]="consumer()?.name" /> <app-key-value label="نام" [value]="consumer()?.name" />
<app-key-value label="نوع مشتری" [value]="consumer()?.type?.translate" /> <app-key-value label="نوع" [value]="consumer()?.type?.translate" />
@if (consumer()?.type?.value === 'LEGAL') { @if (consumer()?.type?.value === 'LEGAL') {
<app-key-value label="شناسه ملی" [value]="consumer()?.legal?.registration_code" /> <app-key-value label="شناسه ملی" [value]="consumer()?.legal?.registration_code" />
} @else { } @else {
@@ -20,7 +20,7 @@ export class AdminPartnerLicensesComponent extends AbstractList<IPartnerActivate
// { field: 'id', header: 'شناسه', type: 'id' }, // { field: 'id', header: 'شناسه', type: 'id' },
{ {
field: 'consumer', field: 'consumer',
header: شتری', header: ودی',
customDataModel(item: IPartnerActivatedLicenseResponse) { customDataModel(item: IPartnerActivatedLicenseResponse) {
return `${item.business_activity.consumer_name} (${item.business_activity.name})`; return `${item.business_activity.consumer_name} (${item.business_activity.name})`;
}, },
@@ -54,7 +54,7 @@ export class ProviderFormComponent extends AbstractFormDialog<IProviderRequest,
form = this.initForm(); form = this.initForm();
preparedTitle = computed(() => `${this.editMode ? 'ویرایش' : 'افزودن'} ارایه‌دهنده`); preparedTitle = computed(() => `${this.editMode ? 'ویرایش' : 'افزودن'} PSP`);
override ngOnChanges() { override ngOnChanges() {
this.form.patchValue(this.initialValues ?? {}); this.form.patchValue(this.initialValues ?? {});
@@ -16,7 +16,7 @@ export const providersNamedRoutes: NamedRoutes<TProvidersRouteNames> = {
path: 'providers/:providerId', path: 'providers/:providerId',
loadComponent: () => import('../../views/single.component').then((m) => m.ProviderComponent), loadComponent: () => import('../../views/single.component').then((m) => m.ProviderComponent),
meta: { meta: {
title: 'ارایه‌دهنده', title: 'PSP',
pagePath: () => '/super_admin/providers/:providerId', pagePath: () => '/super_admin/providers/:providerId',
}, },
}, },
@@ -4,24 +4,22 @@
[options]="items()" [options]="items()"
optionLabel="name" optionLabel="name"
[optionValue]="selectOptionValue" [optionValue]="selectOptionValue"
placeholder="انتخاب ارایه‌دهنده" placeholder="انتخاب PSP"
[formControl]="control" [formControl]="control"
[showClear]="showClear" [showClear]="showClear"
[filter]="true" [filter]="true"
appendTo="body" appendTo="body">
>
@if (canInsert) { @if (canInsert) {
<ng-template #footer> <ng-template #footer>
<div class="p-3"> <div class="p-3">
<p-button <p-button
label="افزودن ارایه‌دهنده" label="افزودن PSP"
fluid fluid
severity="secondary" severity="secondary"
text text
size="small" size="small"
icon="pi pi-plus" icon="pi pi-plus"
(onClick)="onOpenForm()" (onClick)="onOpenForm()" />
/>
</div> </div>
</ng-template> </ng-template>
} }
@@ -1,21 +1,19 @@
<app-page-data-list <app-page-data-list
[pageTitle]="'مدیریت ارایه‌دهنده‌گان'" [pageTitle]="'مدیریت PSP'"
[addNewCtaLabel]="'افزودن ارایه‌دهنده'" [addNewCtaLabel]="'افزودن PSP'"
[columns]="columns" [columns]="columns"
[showAdd]="true" [showAdd]="true"
emptyPlaceholderTitle="ارایه‌دهنده‌ی یافت نشد" emptyPlaceholderTitle="PSP‌ی یافت نشد"
emptyPlaceholderDescription="برای افزودن ارایه‌دهنده‌ی، روی دکمهٔ بالا کلیک کنید." emptyPlaceholderDescription="برای افزودن PSP‌ی، روی دکمهٔ بالا کلیک کنید."
[items]="items()" [items]="items()"
[loading]="loading()" [loading]="loading()"
[showDetails]="true" [showDetails]="true"
[showAdd]="true" [showAdd]="true"
(onAdd)="openAddForm()" (onAdd)="openAddForm()"
(onRefresh)="refresh()" (onRefresh)="refresh()" />
/>
<provider-form <provider-form
[(visible)]="visibleForm" [(visible)]="visibleForm"
[editMode]="editMode()" [editMode]="editMode()"
[providerId]="selectedItemForEdit()?.id" [providerId]="selectedItemForEdit()?.id"
[initialValues]="selectedItemForEdit() || undefined" [initialValues]="selectedItemForEdit() || undefined"
(onSubmit)="refresh()" (onSubmit)="refresh()" />
/>
@@ -36,7 +36,7 @@ export class AppLayout {
constructor( constructor(
public layoutService: LayoutService, public layoutService: LayoutService,
public renderer: Renderer2, public renderer: Renderer2,
public router: Router, public router: Router
) { ) {
this.layoutService.headerSlot$.subscribe((tpl) => (this.topBarMoreAction = tpl)); this.layoutService.headerSlot$.subscribe((tpl) => (this.topBarMoreAction = tpl));
this.layoutService.topbarStartSlot$.subscribe((tpl) => (this.topBarStartAction = tpl)); this.layoutService.topbarStartSlot$.subscribe((tpl) => (this.topBarStartAction = tpl));
@@ -105,7 +105,7 @@ export class AppLayout {
} else { } else {
document.body.className = document.body.className.replace( document.body.className = document.body.className.replace(
new RegExp('(^|\\b)' + 'blocked-scroll'.split(' ').join('|') + '(\\b|$)', 'gi'), new RegExp('(^|\\b)' + 'blocked-scroll'.split(' ').join('|') + '(\\b|$)', 'gi'),
' ', ' '
); );
} }
} }
@@ -169,6 +169,10 @@ export class AppLayout {
} }
} }
ngOnChanges() {
console.log('layout changed');
}
ngOnDestroy() { ngOnDestroy() {
if (this.overlayMenuOpenSubscription) { if (this.overlayMenuOpenSubscription) {
this.overlayMenuOpenSubscription.unsubscribe(); this.overlayMenuOpenSubscription.unsubscribe();
@@ -9,13 +9,12 @@
size="large" size="large"
icon="pi pi-bars" icon="pi pi-bars"
class="layout-menu-button layout-topbar-action" class="layout-menu-button layout-topbar-action"
(click)="layoutService.onMenuToggle()" (click)="layoutService.onMenuToggle()"></p-button>
></p-button>
} }
<div class="flex items-center gap-2"> <a href="/" class="flex items-center gap-2">
<img [src]="logo" width="32" /> <img [src]="logo" width="32" />
<span class="text-xl">{{ panelTitle() }}</span> <span class="text-xl">{{ panelTitle() }}</span>
</div> </a>
} }
</ng-template> </ng-template>
<ng-template #center> <ng-template #center>
@@ -34,13 +33,12 @@
[icon]="`pi ${layoutService.isDarkTheme() ? 'pi-moon' : 'pi-sun'}`" [icon]="`pi ${layoutService.isDarkTheme() ? 'pi-moon' : 'pi-sun'}`"
text text
size="large" size="large"
(click)="toggleDarkMode()" (click)="toggleDarkMode()">
>
<i [ngClass]="{}"></i> <i [ngClass]="{}"></i>
</p-button> </p-button>
<div class=""> <div class="">
<p-menu #menu [model]="profileMenuItems()" [popup]="true" /> <p-menu #menu appendTo="body" [model]="profileMenuItems()" [popup]="true" />
<p-button (click)="menu.toggle($event)" icon="pi pi-user" text severity="contrast" size="large" /> <p-button (click)="menu.toggle($event)" icon="pi pi-user" text severity="contrast" size="large" />
</div> </div>
</div> </div>
@@ -21,7 +21,7 @@ export class CatalogProviderSelectComponent extends AbstractSelectComponent<
private readonly service = inject(CatalogsService); private readonly service = inject(CatalogsService);
get preparedLabel() { get preparedLabel() {
return this.label || 'انتخاب ارایه‌دهنده'; return this.label || 'انتخاب PSP';
} }
ngOnInit() { ngOnInit() {
@@ -1,7 +1,7 @@
import { IListConfig } from './list-config.model'; import { IListConfig } from './list-config.model';
export const consumerAccountListConfig: IListConfig = { export const consumerAccountListConfig: IListConfig = {
pageTitle: 'مدیریت حساب‌های مشتری', pageTitle: 'مدیریت حساب‌های مودی',
addNewCtaLabel: 'افزودن حساب', addNewCtaLabel: 'افزودن حساب',
emptyPlaceholderTitle: 'حسابی یافت نشد', emptyPlaceholderTitle: 'حسابی یافت نشد',
emptyPlaceholderDescription: 'برای افزودن حساب، روی دکمهٔ بالا کلیک کنید.', emptyPlaceholderDescription: 'برای افزودن حساب، روی دکمهٔ بالا کلیک کنید.',
@@ -1,10 +1,10 @@
import { IListConfig } from './list-config.model'; import { IListConfig } from './list-config.model';
export const consumerListConfig: IListConfig = { export const consumerListConfig: IListConfig = {
pageTitle: 'مدیریت مشتری‌ها', pageTitle: 'مدیریت مودیان',
addNewCtaLabel: 'افزودن مشتری', addNewCtaLabel: 'افزودن مودی',
emptyPlaceholderTitle: شتری‌ای یافت نشد', emptyPlaceholderTitle: ودی‌ای یافت نشد',
emptyPlaceholderDescription: 'برای افزودن مشتری، روی دکمهٔ بالا کلیک کنید.', emptyPlaceholderDescription: 'برای افزودن مودی، روی دکمهٔ بالا کلیک کنید.',
columns: [ columns: [
{ field: 'name', header: 'عنوان' }, { field: 'name', header: 'عنوان' },
{ {
@@ -16,7 +16,7 @@ export const consumerListConfig: IListConfig = {
}, },
{ {
field: 'partner', field: 'partner',
header: 'ارایه‌دهنده', header: 'PSP',
type: 'nested', type: 'nested',
nestedOption: { path: 'partner.name' }, nestedOption: { path: 'partner.name' },
}, },
@@ -8,7 +8,7 @@ export const licenseListConfig: IListConfig = {
columns: [ columns: [
{ {
field: 'consumer', field: 'consumer',
header: شتری', header: ودی',
customDataModel(item: any) { customDataModel(item: any) {
return `${item.consumer.first_name} ${item.consumer.last_name}`; return `${item.consumer.first_name} ${item.consumer.last_name}`;
}, },
@@ -2,9 +2,9 @@ import { IListConfig } from './list-config.model';
export const partnerListConfig: IListConfig = { export const partnerListConfig: IListConfig = {
pageTitle: 'مدیریت ارایه‌دهندگان', pageTitle: 'مدیریت ارایه‌دهندگان',
addNewCtaLabel: 'افزودن ارایه‌دهنده', addNewCtaLabel: 'افزودن PSP',
emptyPlaceholderTitle: 'ارایه‌دهندگان‌ای یافت نشد', emptyPlaceholderTitle: 'ارایه‌دهندگان‌ای یافت نشد',
emptyPlaceholderDescription: 'برای افزودن ارایه‌دهنده، روی دکمهٔ بالا کلیک کنید.', emptyPlaceholderDescription: 'برای افزودن PSP، روی دکمهٔ بالا کلیک کنید.',
columns: [ columns: [
{ field: 'name', header: 'عنوان' }, { field: 'name', header: 'عنوان' },
{ field: 'code', header: 'کد' }, { field: 'code', header: 'کد' },
@@ -12,7 +12,7 @@ export const posListConfig: IListConfig = {
{ field: 'device', header: 'دستگاه', type: 'nested', nestedOption: { path: 'device.name' } }, { field: 'device', header: 'دستگاه', type: 'nested', nestedOption: { path: 'device.name' } },
{ {
field: 'provider', field: 'provider',
header: 'ارایه‌دهنده', header: 'PSP',
type: 'nested', type: 'nested',
nestedOption: { path: 'provider.name' }, nestedOption: { path: 'provider.name' },
}, },
+1 -1
View File
@@ -13,5 +13,5 @@ export const AccountTypeTranslates = {
CONSUMER: 'مصرف کننده', CONSUMER: 'مصرف کننده',
SUPER_ADMIN: 'مدیر کل سیستم', SUPER_ADMIN: 'مدیر کل سیستم',
ADMIN: 'مدیر', ADMIN: 'مدیر',
PROVIDER: 'ارایه‌دهنده', PROVIDER: 'PSP',
} as Record<AccountType, string>; } as Record<AccountType, string>;
+12
View File
@@ -9,6 +9,18 @@ body {
line-height: 1.2; line-height: 1.2;
} }
html.application-pos,
body.application-pos {
width: 100%;
max-width: 600px;
margin-left: auto;
margin-right: auto;
}
body.application-pos {
overflow-x: hidden;
}
a { a {
text-decoration: none; text-decoration: none;
} }
+2 -2
View File
@@ -3,8 +3,8 @@ export const environment = {
production: false, production: false,
// apiBaseUrl: 'http://194.59.214.243:5002', // apiBaseUrl: 'http://194.59.214.243:5002',
// apiBaseUrl: 'http://192.168.128.73:5002', // apiBaseUrl: 'http://192.168.128.73:5002',
// apiBaseUrl: 'http://localhost:5002', apiBaseUrl: 'http://localhost:5002',
apiBaseUrl: 'https://psp-api.shift-am.ir', // apiBaseUrl: 'https://psp-api.shift-am.ir',
// host: 'http://194.59.214.243', // host: 'http://194.59.214.243',
host: 'localhost', host: 'localhost',
port: 5000, port: 5000,
+1
View File
@@ -17,6 +17,7 @@ if (themeMeta) {
} }
if (config.isPosApplication) { if (config.isPosApplication) {
document.documentElement.classList.add('application-pos');
document.body.classList.add('application-pos'); document.body.classList.add('application-pos');
} }