refactor: update labels and translations in various components
Production CI / validate-and-build (push) Failing after 1m2s

- Changed 'تغییر گذرواژه' to 'تغییر رمز عبور' in layout.component.ts
- Updated HTML structure in list.component.html and saleInvoices components for consistency and improved styling.
- Modified sale-invoice-card.component.html to enhance the display of invoice details.
- Adjusted sale-invoice-card.component.ts to handle customer types more effectively.
- Enhanced the handling of invoice statuses in saleInvoices components.
- Improved layout and styling in shop components for better user experience.
- Refactored key-value component for better readability and maintainability.
- Updated upload file component to streamline file selection process.
- Added new styles in customize.scss and psp.scss for consistent UI.
- Adjusted environment configuration for better API endpoint management.
This commit is contained in:
2026-06-09 13:31:48 +03:30
parent 5fa07c7ee8
commit 88f45eee38
41 changed files with 240 additions and 238 deletions
+8
View File
@@ -100,6 +100,10 @@
"input": "public-tis" "input": "public-tis"
} }
], ],
"styles": [
"src/assets/styles.scss",
"src/assets/psp.scss"
],
"budgets": [ "budgets": [
{ {
"maximumError": "3MB", "maximumError": "3MB",
@@ -144,6 +148,10 @@
"input": "public-tis" "input": "public-tis"
} }
], ],
"styles": [
"src/assets/styles.scss",
"src/assets/psp.scss"
],
"budgets": [ "budgets": [
{ {
"maximumError": "2.5MB", "maximumError": "2.5MB",
@@ -1,5 +1,5 @@
<shared-dialog <shared-dialog
header="تغییر گذرواژه" header="تغییر رمز عبور"
[(visible)]="visible" [(visible)]="visible"
[modal]="true" [modal]="true"
[style]="{ width: '500px' }" [style]="{ width: '500px' }"
@@ -1,5 +1,5 @@
<app-page-data-list <app-page-data-list
pageTitle="لیست صورت‌حساب‌ها" pageTitle="صورت‌حساب‌ها"
[columns]="columns" [columns]="columns"
emptyPlaceholderTitle="تا به حال صورت‌حسابی توسط این پایانه ایجاد نشده است." emptyPlaceholderTitle="تا به حال صورت‌حسابی توسط این پایانه ایجاد نشده است."
[items]="items()" [items]="items()"
@@ -1,11 +1,10 @@
<app-card-data cardTitle="تغییر گذرواژه" [editable]="false"> <app-card-data cardTitle="تغییر رمز عبور" [editable]="false">
<form [formGroup]="form" (submit)="submit()" class="max-w-lg mx-auto"> <form [formGroup]="form" (submit)="submit()" class="mx-auto max-w-lg">
<shared-password-input <shared-password-input
[passwordControl]="form.controls.password" [passwordControl]="form.controls.password"
[confirmPasswordControl]="form.controls.confirmPassword" [confirmPasswordControl]="form.controls.confirmPassword" />
/> <button type="submit" pButton [disabled]="form.invalid || loading()" class="mx-auto w-full max-w-xs">
<button type="submit" pButton [disabled]="form.invalid || loading()" class="w-full max-w-xs mx-auto"> تغییر رمز عبور
تغییر گذرواژه
</button> </button>
</form> </form>
</app-card-data> </app-card-data>
@@ -25,7 +25,7 @@ export class ConsumerResetPasswordCardComponent {
password: fieldControl.password(), password: fieldControl.password(),
confirmPassword: fieldControl.confirmPassword(), confirmPassword: fieldControl.confirmPassword(),
}, },
{ validators: [MustMatch('password', 'confirmPassword')] }, { validators: [MustMatch('password', 'confirmPassword')] }
); );
submit() { submit() {
@@ -40,7 +40,7 @@ export class ConsumerResetPasswordCardComponent {
.pipe(finalize(() => this.loading.set(false))) .pipe(finalize(() => this.loading.set(false)))
.subscribe(() => { .subscribe(() => {
this.form.reset(); this.form.reset();
this.toastService.success({ text: 'گذرواژه با موفقیت به‌روز شد.' }); this.toastService.success({ text: 'رمز عبور با موفقیت به‌روز شد.' });
}); });
} }
} }
@@ -1,5 +1,5 @@
<app-page-data-list <app-page-data-list
[pageTitle]="'لیست صورت‌حساب‌ها'" [pageTitle]="'صورت‌حساب‌ها'"
[columns]="columns" [columns]="columns"
emptyPlaceholderTitle="صورت‌حساب‌ی یافت نشد" emptyPlaceholderTitle="صورت‌حساب‌ی یافت نشد"
[items]="items()" [items]="items()"
@@ -1,5 +1,5 @@
<shared-dialog <shared-dialog
header="تغییر گذرواژه" header="تغییر رمز عبور"
[(visible)]="visible" [(visible)]="visible"
[modal]="true" [modal]="true"
[style]="{ width: '500px' }" [style]="{ width: '500px' }"
@@ -1,11 +1,10 @@
<app-card-data cardTitle="تغییر گذرواژه" [editable]="false"> <app-card-data cardTitle="تغییر رمز عبور" [editable]="false">
<form [formGroup]="form" (submit)="submit()" class="max-w-lg mx-auto"> <form [formGroup]="form" (submit)="submit()" class="mx-auto max-w-lg">
<shared-password-input <shared-password-input
[passwordControl]="form.controls.password" [passwordControl]="form.controls.password"
[confirmPasswordControl]="form.controls.confirmPassword" [confirmPasswordControl]="form.controls.confirmPassword" />
/> <button type="submit" pButton [disabled]="form.invalid || loading()" class="mx-auto w-full max-w-xs">
<button type="submit" pButton [disabled]="form.invalid || loading()" class="w-full max-w-xs mx-auto"> تغییر رمز عبور
تغییر گذرواژه
</button> </button>
</form> </form>
</app-card-data> </app-card-data>
@@ -25,7 +25,7 @@ export class PartnerResetPasswordCardComponent {
password: fieldControl.password(), password: fieldControl.password(),
confirmPassword: fieldControl.confirmPassword(), confirmPassword: fieldControl.confirmPassword(),
}, },
{ validators: [MustMatch('password', 'confirmPassword')] }, { validators: [MustMatch('password', 'confirmPassword')] }
); );
submit() { submit() {
@@ -40,7 +40,7 @@ export class PartnerResetPasswordCardComponent {
.pipe(finalize(() => this.loading.set(false))) .pipe(finalize(() => this.loading.set(false)))
.subscribe(() => { .subscribe(() => {
this.form.reset(); this.form.reset();
this.toastService.success({ text: 'گذرواژه با موفقیت به‌روز شد.' }); this.toastService.success({ text: 'رمز عبور با موفقیت به‌روز شد.' });
}); });
} }
} }
@@ -27,7 +27,7 @@ export class PosChangePasswordComponent extends AbstractDialog {
.pipe(finalize(() => this.submitLoading.set(false))) .pipe(finalize(() => this.submitLoading.set(false)))
.subscribe(() => { .subscribe(() => {
this.toastService.success({ this.toastService.success({
text: 'تغییر گذرواژه با موفقیت انجام شد.', text: 'تغییر رمز عبور با موفقیت انجام شد.',
}); });
this.submitLoading.set(false); this.submitLoading.set(false);
this.close(); this.close();
@@ -81,7 +81,7 @@ export class PosPagesLayoutComponent {
disabled: true, disabled: true,
}, },
{ {
label: 'تغییر گذرواژه', label: 'تغییر رمز عبور',
icon: 'pi pi-key', icon: 'pi pi-key',
command: this.showChangePasswordDialog, command: this.showChangePasswordDialog,
}, },
@@ -16,7 +16,7 @@
} }
} @else { } @else {
@for (good of items(); track good.id) { @for (good of items(); track good.id) {
<div class="bg-surface-card flex items-center gap-2 rounded-lg px-3 py-1 shadow-xs"> <div class="bg-surface-card flex items-center gap-2 rounded-lg px-3 py-1">
<div class="flex grow items-center gap-2"> <div class="flex grow items-center gap-2">
<img <img
[src]="good.image_url || goodPlaceholder" [src]="good.image_url || goodPlaceholder"
@@ -1,5 +1,5 @@
<div class="bg-surface-card"> <div class="bg-surface-card">
<app-inner-pages-header pageTitle="لیست صورت‌حساب‌های صادر شده" [backRoute]="backRoute"> <app-inner-pages-header pageTitle="صورت‌حساب‌های صادر شده" [backRoute]="backRoute">
<ng-template #actions> <ng-template #actions>
<div class="flex gap-1"> <div class="flex gap-1">
<p-button <p-button
@@ -16,11 +16,9 @@
<div class="flex flex-wrap gap-2 px-4 pb-2"> <div class="flex flex-wrap gap-2 px-4 pb-2">
@for (filter of activeFilters(); track filter.key) { @for (filter of activeFilters(); track filter.key) {
@if (filter.key !== 'page') { @if (filter.key !== 'page') {
<p-chip <p-chip removable class="border-surface-border border" (onRemove)="removeFilter(filter.key)">
removable <span class="text-sm"> {{ filter.label }}: {{ filter.value }} </span>
[label]="filter.label + ': ' + filter.value" </p-chip>
class="border-surface-border border"
(onRemove)="removeFilter(filter.key)" />
} }
} }
</div> </div>
@@ -1,18 +1,18 @@
<p-card class="border-surface-border relative overflow-visible border p-0!"> <p-card class="border-surface-border relative overflow-visible border p-0!">
<div class="flex w-full items-center justify-between gap-4"> <div class="flex w-full items-center justify-between gap-4">
<span> {{ saleInvoice.invoice_number }} - {{ saleInvoice.code }} </span> <span class="text-lg font-bold"> {{ saleInvoice.invoice_number }}</span>
<catalog-tax-provider-status-tag [status]="saleInvoice.status.value" [translate]="saleInvoice.status.translate" /> <catalog-tax-provider-status-tag [status]="saleInvoice.status.value" [translate]="saleInvoice.status.translate" />
</div> </div>
<hr /> <hr />
<div class="grid grid-cols-1 gap-4"> <div class="grid grid-cols-1 gap-3">
<app-key-value alignment="end" label="نوع صورت‌حساب"> <app-key-value alignment="end" label="تاریخ" [value]="saleInvoice.created_at" type="date" />
{{ preparedInvoiceType() }}
</app-key-value>
<app-key-value alignment="end" label="مبلغ کل" [value]="saleInvoice.total_amount" type="price" /> <app-key-value alignment="end" label="مبلغ کل" [value]="saleInvoice.total_amount" type="price" />
<app-key-value alignment="end" label="نوع صورت‌حساب‌"> <app-key-value alignment="end" label="نوع صورت‌حساب‌">
<catalog-invoice-type-tag [status]="saleInvoice.type.value" /> <catalog-invoice-type-tag [status]="saleInvoice.type.value" />
</app-key-value> </app-key-value>
<app-key-value alignment="end" label="تاریخ صورت‌حساب‌" [value]="saleInvoice.created_at" type="date" /> <app-key-value alignment="end" label="مشتری">
{{ preparedInvoiceType() }}
</app-key-value>
</div> </div>
<hr /> <hr />
<div class="flex items-center justify-center gap-4"> <div class="flex items-center justify-center gap-4">
@@ -50,20 +50,20 @@ export class SaleInvoiceCardComponent {
); );
preparedInvoiceType = computed(() => { preparedInvoiceType = computed(() => {
if (!this.saleInvoice) return ''; if (!this.saleInvoice) return '';
const { customer } = this.saleInvoice; const { customer, unknown_customer } = this.saleInvoice;
if (customer) { if (unknown_customer?.name || unknown_customer?.national_code) {
const { legal, individual } = customer; return `${unknown_customer.name || unknown_customer?.national_code || 'رهگذر'} (نوع دوم)`;
let text = 'نوع اول - '; } else if (customer) {
if (legal) { const { legal, individual, type } = customer;
text += `حقوقی (${legal.company_name})`; switch (type) {
case 'INDIVIDUAL':
return `${individual ? individual.first_name + ' ' + individual.last_name : '-----'} (نوع اول)`;
case 'LEGAL':
return `${legal?.name || '-----'} (نوع اول)`;
} }
if (individual) {
text += `حقیقی (${individual.first_name} ${individual.last_name})`;
}
return text;
} }
return 'نوع دوم (بدون اطلاعات خریدار)'; return 'رهگذر (نوع دوم)';
}); });
sendInvoice() { sendInvoice() {
@@ -103,7 +103,7 @@ export class SaleInvoiceCardComponent {
.retrySendToTsp(this.saleInvoice.id) .retrySendToTsp(this.saleInvoice.id)
.pipe(finalize(() => this.resendingLoading.set(false))) .pipe(finalize(() => this.resendingLoading.set(false)))
.subscribe((res) => { .subscribe((res) => {
if (res.status === 'FAILURE') { if (res.status === 'SEND_FAILURE') {
this.toastService.error({ this.toastService.error({
text: res.message || 'خطا در ارسال مجدد صورت‌حساب‌ رخ داده است.', text: res.message || 'خطا در ارسال مجدد صورت‌حساب‌ رخ داده است.',
}); });
+8 -15
View File
@@ -2,6 +2,7 @@ import { Maybe } from '@/core';
import ISummary from '@/core/models/summary'; import ISummary from '@/core/models/summary';
import { InvoiceTypes, TspProviderResponseStatus } from '@/shared/catalog'; import { InvoiceTypes, TspProviderResponseStatus } from '@/shared/catalog';
import { IEnumTranslate } from '@/shared/models/enum_translate.type'; import { IEnumTranslate } from '@/shared/models/enum_translate.type';
import { IIndividualCustomer, ILegalCustomer } from '../../shop/models';
export interface IPosSaleInvoicesSummaryRawResponse { export interface IPosSaleInvoicesSummaryRawResponse {
id: string; id: string;
@@ -10,6 +11,7 @@ export interface IPosSaleInvoicesSummaryRawResponse {
invoice_date: string; invoice_date: string;
created_at: string; created_at: string;
total_amount: string; total_amount: string;
unknown_customer: Partial<UnknownCoustomer>;
customer: Maybe<Customer>; customer: Maybe<Customer>;
status: IEnumTranslate<TspProviderResponseStatus>; status: IEnumTranslate<TspProviderResponseStatus>;
type: IEnumTranslate<InvoiceTypes>; type: IEnumTranslate<InvoiceTypes>;
@@ -30,6 +32,10 @@ export interface IPosSaleInvoicesRawResponse extends IPosSaleInvoicesSummaryRawR
export interface IPosSaleInvoicesResponse extends IPosSaleInvoicesRawResponse {} export interface IPosSaleInvoicesResponse extends IPosSaleInvoicesRawResponse {}
interface UnknownCoustomer {
name?: string;
national_code?: string;
}
interface ConsumerAccount { interface ConsumerAccount {
role: string; role: string;
account: Account; account: Account;
@@ -55,19 +61,6 @@ interface Payments {
interface Customer { interface Customer {
type: string; type: string;
individual: Individual; individual: IIndividualCustomer;
legal: Legal; legal: ILegalCustomer;
}
interface Individual {
first_name: string;
last_name: string;
national_code: string;
mobile_number: string;
}
interface Legal {
company_name: string;
economic_code: string;
registration_number: string;
} }
@@ -4,7 +4,9 @@
[backRoute]="backRoute()" [backRoute]="backRoute()"
[sendToTspLoading]="sendToTspLoading()" [sendToTspLoading]="sendToTspLoading()"
[inquiryLoading]="inquiryLoading()" [inquiryLoading]="inquiryLoading()"
[resendToTspLoading]="resendToTspLoading()"
(onSendToTsp)="sendToTsp()" (onSendToTsp)="sendToTsp()"
(onResendToTsp)="resendToTsp()"
(onInquiry)="inquiry()" (onInquiry)="inquiry()"
(onCorrection)="correction($event)" (onCorrection)="correction($event)"
(onReturnFromSale)="returnFromSale($event)" (onReturnFromSale)="returnFromSale($event)"
@@ -78,7 +78,12 @@ export class PosSaleInvoiceComponent {
this.resendToTspLoading.set(false); this.resendToTspLoading.set(false);
}) })
) )
.subscribe(); .subscribe((res) => {
this.toastService.success({
text: res.message || 'ارسال مجدد صورت‌حساب با موفقیت انجام شد.',
});
this.store.updateStatus(res.status);
});
} }
correction(data: IPosCorrectionRequest) { correction(data: IPosCorrectionRequest) {
this.correctionLoading.set(true); this.correctionLoading.set(true);
@@ -1,21 +1,20 @@
<div class="border border-surface-border rounded-xl p-2 shadow-sm"> <div class="border-surface-border rounded-xl border p-2">
<div class="flex gap-3 items-center"> <div class="flex items-center gap-3">
<img <img
[src]="inOrderGood.good.image_url || placeholderImage" [src]="inOrderGood.good.image_url || placeholderImage"
loading="lazy" loading="lazy"
decoding="async" decoding="async"
class="w-24 h-24 rounded-md bg-surface-100 object-cover shrink-0 border border-surface-border" class="bg-surface-100 border-surface-border h-24 w-24 shrink-0 rounded-md border object-cover" />
/> <div class="flex grow flex-col justify-between overflow-hidden">
<div class="flex flex-col grow justify-between overflow-hidden"> <div class="flex grow items-stretch gap-4">
<div class="flex items-stretch grow gap-4"> <div class="flex grow flex-col justify-between gap-2 overflow-hidden py-1">
<div class="flex flex-col justify-between gap-2 grow overflow-hidden py-1"> <div class="flex w-full shrink-0 flex-col overflow-hidden">
<div class="shrink-0 flex flex-col w-full overflow-hidden"> <div class="flex w-full items-center gap-1 overflow-hidden">
<div class="flex w-full overflow-hidden gap-1 items-center"> <span class="overflow-hidden text-lg font-bold text-nowrap text-ellipsis">
<span class="font-bold text-lg text-ellipsis text-nowrap overflow-hidden">
{{ inOrderGood.good.name }} {{ inOrderGood.good.name }}
</span> </span>
</div> </div>
<span class="text-sm text-ellipsis text-nowrap overflow-hidden"> <span class="overflow-hidden text-sm text-nowrap text-ellipsis">
{{ inOrderGood.quantity }} {{ inOrderGood.good.measure_unit.name }} {{ inOrderGood.quantity }} {{ inOrderGood.good.measure_unit.name }}
</span> </span>
</div> </div>
@@ -23,7 +22,7 @@
<span [appPriceMask]="inOrderGood.total_amount"></span> <span [appPriceMask]="inOrderGood.total_amount"></span>
} @else { } @else {
<div class="flex flex-col"> <div class="flex flex-col">
<span class="line-through text-muted-color text-xs" [appPriceMask]="inOrderGood.base_total_amount"></span> <span class="text-muted-color text-xs line-through" [appPriceMask]="inOrderGood.base_total_amount"></span>
<span [appPriceMask]="inOrderGood.base_total_amount - inOrderGood.discount_amount"></span> <span [appPriceMask]="inOrderGood.base_total_amount - inOrderGood.discount_amount"></span>
</div> </div>
} }
@@ -36,8 +35,7 @@
size="small" size="small"
severity="secondary" severity="secondary"
class="ms-auto" class="ms-auto"
(click)="editOrderItem()" (click)="editOrderItem()"></button>
></button>
<button <button
pButton pButton
type="button" type="button"
@@ -45,8 +43,7 @@
size="small" size="small"
severity="danger" severity="danger"
class="ms-auto" class="ms-auto"
(click)="removeGoodFromOrder()" (click)="removeGoodFromOrder()"></button>
></button>
</div> </div>
</div> </div>
</div> </div>
@@ -58,6 +55,5 @@
[(visible)]="visible" [(visible)]="visible"
[good]="inOrderGood.good" [good]="inOrderGood.good"
[initialValues]="inOrderGood" [initialValues]="inOrderGood"
[orderItemId]="inOrderGood.id" [orderItemId]="inOrderGood.id" />
/>
} }
@@ -1,31 +1,32 @@
<div class="overflow-x-auto"> <div class="overflow-x-auto">
<div class="w-full overflow-visible flex gap-3 px-4"> <div class="flex w-full gap-3 overflow-visible px-4">
@if (loading()) { @if (loading()) {
@for (i of [1, 2, 3, 4, 5]; track i) { @for (i of [1, 2, 3, 4, 5]; track i) {
<p-skeleton width="6rem" height="2.5rem" /> <div class="h-10 w-24 shrink-0">
<p-skeleton width="100%" height="100%" />
</div>
} }
} @else { } @else {
@for (category of categories(); track category.id) { @for (category of categories(); track category.id) {
<div <div
[class]=" [class]="
'h-10 rounded-lg px-3 flex items-center gap-3 border border-surface-border cursor-pointer bg-surface-100 hover:bg-surface-200 transition-all shrink-0' + 'border-surface-border bg-surface-100 hover:bg-surface-200 flex h-10 shrink-0 cursor-pointer items-center gap-3 rounded-lg border px-3 transition-all' +
(selectedCategory() === category.id ? ' bg-surface-card' : '') (selectedCategory() === category.id ? ' bg-surface-card' : '')
" "
(click)="changeSelectedCategory(category)" (click)="changeSelectedCategory(category)">
> <span class="text-muted-color text-sm font-bold"> {{ category.name }}</span>
<span class="text-sm text-muted-color font-bold"> {{ category.name }}</span>
<div <div
[class]=" [class]="
'flex items-center justify-center py-0.5 px-2 rounded-sm bg-surface-300 text-xs text-muted-color' + 'bg-surface-300 text-muted-color flex items-center justify-center rounded-sm px-2 py-0.5 text-xs' +
(selectedCategory() === category.id ? ' bg-amber-400! text-white' : '') (selectedCategory() === category.id ? ' bg-amber-400! text-white' : '')
" ">
>
<span> <span>
{{ category.goods_count }} {{ category.goods_count }}
</span> </span>
</div> </div>
</div> </div>
} }
<div class="invisible w-1 shrink-0 opacity-0"></div>
} }
</div> </div>
</div> </div>
@@ -7,7 +7,7 @@
} }
} @else { } @else {
@for (good of visibleGoods(); track good.id) { @for (good of visibleGoods(); track good.id) {
<div class="bg-surface-card flex items-center gap-2 rounded-lg px-3 py-1 shadow-xs"> <div class="bg-surface-card flex items-center gap-2 rounded-lg px-3 py-1">
<div class="flex grow items-center gap-2"> <div class="flex grow items-center gap-2">
<img <img
[src]="good.image_url || goodPlaceholder" [src]="good.image_url || goodPlaceholder"
@@ -18,7 +18,7 @@
<button <button
type="button" type="button"
pButton pButton
class="border-surface-border bg-surface-0 sticky! inset-x-0 right-0 bottom-0 z-1200 w-full rounded-b-none! border-t px-4 py-3 shadow-[0_-4px_16px_rgba(0,0,0,0.08)] md:hidden!" class="border-surface-border bg-surface-0 sticky! inset-x-0 right-0 bottom-0 z-120 w-full rounded-b-none! border-t px-4 py-3 md:hidden!"
(click)="openInvoiceBottomSheet()"> (click)="openInvoiceBottomSheet()">
<!-- [style.paddingBottom]="'calc(0.75rem + {{env(safe-area-inset-bottom)}})'" --> <!-- [style.paddingBottom]="'calc(0.75rem + {{env(safe-area-inset-bottom)}})'" -->
<div class="mx-auto flex w-full max-w-3xl items-center justify-between"> <div class="mx-auto flex w-full max-w-3xl items-center justify-between">
@@ -17,7 +17,7 @@ import { PosLandingStore } from '../store/main.store';
@Component({ @Component({
selector: 'pos-shop', selector: 'pos-shop',
templateUrl: './root.component.html', templateUrl: './root.component.html',
host: { class: 'grow overflow-hidden' }, host: { class: 'grow' },
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
imports: [ imports: [
@@ -1,5 +1,5 @@
<div <div
class="text-surface-700 relative flex flex-col gap-4 overflow-hidden rounded-lg border px-4 py-4 pe-2" class="text-surface-700 relative flex h-full flex-col gap-4 overflow-hidden rounded-lg border py-4 ps-3 pe-2"
[style.backgroundColor]="preparedInfo().bgColor" [style.backgroundColor]="preparedInfo().bgColor"
[style.borderColor]="preparedInfo().borderColor" [style.borderColor]="preparedInfo().borderColor"
(click)="showDetails()"> (click)="showDetails()">
@@ -1,57 +1,59 @@
<div class="flex flex-col gap-6 p-4"> <div class="flex min-h-[calc(100svh-5.5rem)] flex-col p-4 pt-0!">
<season-picker (onChange)="onDateChanged($event)" /> <div class="bg-surface-ground sticky top-[5.5rem] z-10 w-full pt-4!">
<div class="grid grid-cols-2 gap-4">
@if (loading()) {
@for (_ of [0, 1, 2, 3, 4, 5]; track $index) {
<div class="h-32 w-full">
<p-skeleton width="100%" height="100%"></p-skeleton>
</div>
}
} @else {
<pos-statistics-invoice-type-card
type="all"
[loading]="loading()"
[totalAmount]="item()?.all?.total_amount"
[totalTaxAmount]="item()?.all?.total_tax"
[count]="item()?.all?.count"
(onClick)="toInvoicesPage('all')" />
<pos-statistics-invoice-type-card
type="success"
[loading]="loading()"
[totalAmount]="item()?.success?.total_amount"
[totalTaxAmount]="item()?.success?.total_tax"
[count]="item()?.success?.count"
(onClick)="toInvoicesPage('success')" />
<pos-statistics-invoice-type-card
type="failure"
[loading]="loading()"
[totalAmount]="item()?.failure?.total_amount"
[totalTaxAmount]="item()?.failure?.total_tax"
[count]="item()?.failure?.count"
(onClick)="toInvoicesPage('failure')" />
<pos-statistics-invoice-type-card
type="not_send"
[loading]="loading()"
[totalAmount]="item()?.not_send?.total_amount"
[totalTaxAmount]="item()?.not_send?.total_tax"
[count]="item()?.not_send?.count"
(onClick)="toInvoicesPage('not_send')" />
<pos-statistics-invoice-type-card
type="pending"
[loading]="loading()"
[totalAmount]="item()?.pending?.total_amount"
[totalTaxAmount]="item()?.pending?.total_tax"
[count]="item()?.pending?.count"
(onClick)="toInvoicesPage('pending')" />
<pos-statistics-invoice-type-card
type="not_original"
[loading]="loading()"
[totalAmount]="item()?.not_original?.total_amount"
[totalTaxAmount]="item()?.not_original?.total_tax"
[count]="item()?.not_original?.count" />
}
</div>
<div class="fixed inset-x-0 bottom-0 p-4">
<button pButton [routerLink]="shopRoute" size="large" class="w-full">ایجاد صورت‌حساب جدید</button> <button pButton [routerLink]="shopRoute" size="large" class="w-full">ایجاد صورت‌حساب جدید</button>
</div> </div>
<season-picker class="mt-6 mb-4 block w-full" (onChange)="onDateChanged($event)" />
<div class="flex-1">
<div class="grid grid-cols-2 items-stretch gap-2">
@if (loading()) {
@for (_ of [0, 1, 2, 3, 4, 5]; track $index) {
<div class="h-32 w-full">
<p-skeleton width="100%" height="100%"></p-skeleton>
</div>
}
} @else {
<pos-statistics-invoice-type-card
type="all"
[loading]="loading()"
[totalAmount]="item()?.all?.total_amount"
[totalTaxAmount]="item()?.all?.total_tax"
[count]="item()?.all?.count"
(onClick)="toInvoicesPage('all')" />
<pos-statistics-invoice-type-card
type="success"
[loading]="loading()"
[totalAmount]="item()?.success?.total_amount"
[totalTaxAmount]="item()?.success?.total_tax"
[count]="item()?.success?.count"
(onClick)="toInvoicesPage('success')" />
<pos-statistics-invoice-type-card
type="failure"
[loading]="loading()"
[totalAmount]="item()?.failure?.total_amount"
[totalTaxAmount]="item()?.failure?.total_tax"
[count]="item()?.failure?.count"
(onClick)="toInvoicesPage('failure')" />
<pos-statistics-invoice-type-card
type="not_send"
[loading]="loading()"
[totalAmount]="item()?.not_send?.total_amount"
[totalTaxAmount]="item()?.not_send?.total_tax"
[count]="item()?.not_send?.count"
(onClick)="toInvoicesPage('not_send')" />
<pos-statistics-invoice-type-card
type="pending"
[loading]="loading()"
[totalAmount]="item()?.pending?.total_amount"
[totalTaxAmount]="item()?.pending?.total_tax"
[count]="item()?.pending?.count"
(onClick)="toInvoicesPage('pending')" />
<pos-statistics-invoice-type-card
type="not_original"
[loading]="loading()"
[totalAmount]="item()?.not_original?.total_amount"
[totalTaxAmount]="item()?.not_original?.total_tax"
[count]="item()?.not_original?.count" />
}
</div>
</div>
</div> </div>
@@ -1,29 +1,27 @@
<div class="layout-wrapper" [ngClass]="containerClass"> <div class="layout-wrapper flex min-h-svh flex-col" [ngClass]="containerClass">
@if (!fullPageLoading()) { @if (!fullPageLoading()) {
<app-topbar <app-topbar
[showMenu]="showMenu()" [showMenu]="showMenu()"
[startTemplate]="topBarStartAction" [startTemplate]="topBarStartAction"
[centerTemplate]="topBarCenterAction" [centerTemplate]="topBarCenterAction"
[endTemplate]="topBarEndAction || topBarMoreAction" [endTemplate]="topBarEndAction || topBarMoreAction" />
/>
} }
@if (showMenu()) { @if (showMenu()) {
<app-sidebar></app-sidebar> <app-sidebar></app-sidebar>
} }
<div [class]="`layout-main-container ${!showMenu() ? 'hideMenu' : ''} grow ${isFullPage ? 'isFullPage' : ''}`"> <div
<div class="layout-main flex flex-col gap-4"> [class]="`flex flex-col justify-between ${!showMenu() ? 'hideMenu m0 ps-0' : ''} grow ${isFullPage ? 'isFullPage p-0 ps-0' : ''}`">
<div class="flex flex-1 flex-col gap-4">
@if (showBreadcrumb) { @if (showBreadcrumb) {
<app-breadcrumb class="rounded-md overflow-hidden shrink-0" /> <app-breadcrumb class="shrink-0 overflow-hidden rounded-md" />
} }
<div [class]="`rounded-md flex flex-col grow`"> <div [class]="`flex min-h-0 flex-1 flex-col rounded-md`">
<!-- style="container-type: size" --> <!-- style="container-type: size" -->
<div class="h-full"> @if (content) {
@if (content) { <ng-container [ngTemplateOutlet]="content"></ng-container>
<ng-container [ngTemplateOutlet]="content"></ng-container> } @else {
} @else { <router-outlet></router-outlet>
<router-outlet></router-outlet> }
}
</div>
</div> </div>
</div> </div>
<app-footer></app-footer> <app-footer></app-footer>
@@ -1,3 +1,3 @@
<div class="p-4"> <div class="min-h-dvh p-4">
<shared-sale-invoice-single-view [loading]="loading()" [invoice]="invoice()" /> <shared-sale-invoice-single-view [loading]="loading()" [invoice]="invoice()" />
</div> </div>
@@ -1,10 +1,10 @@
import { MustMatch, password } from '@/core/validators'; import { MustMatch, password } from '@/core/validators';
import { AbstractDialog } from '@/shared/abstractClasses/abstract-dialog'; import { AbstractDialog } from '@/shared/abstractClasses/abstract-dialog';
import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component';
import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component'; import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component';
import { Component, EventEmitter, Output, input } from '@angular/core'; import { Component, EventEmitter, Output, input } from '@angular/core';
import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms'; import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
import { SharedPasswordInputComponent } from '../passwordInput/password-input.component'; import { SharedPasswordInputComponent } from '../passwordInput/password-input.component';
import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component';
export interface IChangePasswordSubmitPayload { export interface IChangePasswordSubmitPayload {
password: string; password: string;
@@ -14,7 +14,12 @@ export interface IChangePasswordSubmitPayload {
@Component({ @Component({
selector: 'shared-change-password-form-dialog', selector: 'shared-change-password-form-dialog',
templateUrl: './change-password-form-dialog.component.html', templateUrl: './change-password-form-dialog.component.html',
imports: [ReactiveFormsModule, SharedDialogComponent, FormFooterActionsComponent, SharedPasswordInputComponent], imports: [
ReactiveFormsModule,
SharedDialogComponent,
FormFooterActionsComponent,
SharedPasswordInputComponent,
],
}) })
export class ChangePasswordFormDialogComponent extends AbstractDialog { export class ChangePasswordFormDialogComponent extends AbstractDialog {
title = input<string>(''); title = input<string>('');
@@ -31,11 +36,11 @@ export class ChangePasswordFormDialogComponent extends AbstractDialog {
}, },
{ {
validators: [MustMatch('password', 'confirmPassword')], validators: [MustMatch('password', 'confirmPassword')],
}, }
); );
get dialogHeader() { get dialogHeader() {
return this.title() ? `تغییر گذرواژه ${this.title()}` : 'تغییر گذرواژه'; return this.title() ? `تغییر رمز عبور ${this.title()}` : 'تغییر رمز عبور';
} }
submit() { submit() {
@@ -4,7 +4,7 @@
<div class="bg-surface-card flex flex-col items-center rounded p-8"> <div class="bg-surface-card flex flex-col items-center rounded p-8">
<div <div
class="bg-primary text-primary-contrast -mt-20 inline-flex h-24 w-24 items-center justify-center rounded-full"> class="bg-primary text-primary-contrast -mt-20 inline-flex h-24 w-24 items-center justify-center rounded-full">
<i class="pi pi-question text-5xl!"></i> <i class="pi pi-question rotate-y-180 text-5xl!"></i>
</div> </div>
<span class="mt-6 mb-2 block text-2xl font-bold">{{ message.header }}</span> <span class="mt-6 mb-2 block text-2xl font-bold">{{ message.header }}</span>
<p class="mb-0">{{ message.message }}</p> <p class="mb-0">{{ message.message }}</p>
@@ -3,7 +3,7 @@
<div class="mt-4 flex flex-col gap-3"> <div class="mt-4 flex flex-col gap-3">
@for (item of initialValues || []; track item.id) { @for (item of initialValues || []; track item.id) {
<div class="border-surface-border rounded-xl border p-2 shadow-sm"> <div class="border-surface-border rounded-xl border p-2">
<div class="flex items-center gap-3"> <div class="flex items-center gap-3">
<img <img
[src]="item.good_snapshot.image_url || ''" [src]="item.good_snapshot.image_url || ''"
@@ -3,13 +3,7 @@
} @else if (!invoice) { } @else if (!invoice) {
<uikit-empty-state> </uikit-empty-state> <uikit-empty-state> </uikit-empty-state>
} @else { } @else {
<p-dialog [visible]="actionLoading" [closable]="false" header="لطفا صبر کنید"> <app-inner-pages-header [pageTitle]="`صورت‌حساب ${invoice.invoice_number}`" [backRoute]="backRoute">
<div class="flex h-[30svh] flex-col items-center justify-center gap-6">
<p-progressSpinner />
<span class="text-lg font-bold">در حال ارسال درخواست شما...</span>
</div>
</p-dialog>
<app-inner-pages-header pageTitle="اطلاعات صورت‌حساب‌" [backRoute]="backRoute">
<ng-template #actions> <ng-template #actions>
<p-button (click)="printInvoice()" icon="pi pi-print" outlined size="small" label="چاپ" /> <p-button (click)="printInvoice()" icon="pi pi-print" outlined size="small" label="چاپ" />
</ng-template> </ng-template>
@@ -18,7 +12,6 @@
<p-card> <p-card>
<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]="invoice.invoice_number" />
<app-key-value label="شماره منحصر به فرد مالیاتی" [value]="invoice.tax_id" /> <app-key-value label="شماره منحصر به فرد مالیاتی" [value]="invoice.tax_id" />
<app-key-value label="تاریخ صورت‌حساب‌" [value]="invoice.invoice_date" type="date" /> <app-key-value label="تاریخ صورت‌حساب‌" [value]="invoice.invoice_date" type="date" />
<app-key-value label="تاریخ ایجاد صورت‌حساب‌" [value]="invoice.created_at" type="dateTime" /> <app-key-value label="تاریخ ایجاد صورت‌حساب‌" [value]="invoice.created_at" type="dateTime" />
@@ -117,9 +110,9 @@
pButton pButton
[label]="action.label || ''" [label]="action.label || ''"
[icon]="action.icon || ''" [icon]="action.icon || ''"
size="small"
[severity]="$any(action).severity || 'secondary'" [severity]="$any(action).severity || 'secondary'"
[outlined]="$any(action).severity === 'secondary'" [outlined]="$any(action).severity === 'secondary'"
[loading]="actionLoading"
(click)="action.command()"></button> (click)="action.command()"></button>
} }
</div> </div>
@@ -110,17 +110,6 @@ export class SharedSaleInvoiceSingleViewComponent {
showCorrectionForm = signal(false); showCorrectionForm = signal(false);
showReturnFromSaleForm = signal(false); showReturnFromSaleForm = signal(false);
constructor() {
this.showErrors = this.showErrors.bind(this);
this.showRevokeConfirmation = this.showRevokeConfirmation.bind(this);
this.showCorrection = this.showCorrection.bind(this);
this.showReturnFromSale = this.showReturnFromSale.bind(this);
this.printInvoice = this.printInvoice.bind(this);
this.send = this.send.bind(this);
this.resend = this.resend.bind(this);
this.inquiry = this.inquiry.bind(this);
}
showErrors = () => {}; showErrors = () => {};
inquiry = () => { inquiry = () => {
this.onInquiry.emit(); this.onInquiry.emit();
@@ -150,49 +139,49 @@ export class SharedSaleInvoiceSingleViewComponent {
icon: 'pi pi-send', icon: 'pi pi-send',
neededStatus: TspProviderResponseStatus.SEND_FAILURE, neededStatus: TspProviderResponseStatus.SEND_FAILURE,
severity: 'info', severity: 'info',
command: this.resend, command: () => this.resend(),
}, },
{ {
label: 'ارسال صورت‌حساب', label: 'ارسال صورت‌حساب',
icon: 'pi pi-send', icon: 'pi pi-send',
neededStatus: TspProviderResponseStatus.NOT_SEND, neededStatus: TspProviderResponseStatus.NOT_SEND,
severity: 'info', severity: 'info',
command: this.send, command: () => this.send(),
}, },
{ {
label: 'استعلام وضعیت', label: 'استعلام وضعیت',
icon: 'pi pi-info', icon: 'pi pi-info',
neededStatus: TspProviderResponseStatus.FISCAL_QUEUED, neededStatus: TspProviderResponseStatus.FISCAL_QUEUED,
severity: 'info', severity: 'info',
command: this.inquiry, command: () => this.inquiry(),
}, },
{ {
label: 'دلایل خطا', label: 'دلایل خطا',
icon: 'pi pi-question', icon: 'pi pi-question',
neededStatus: TspProviderResponseStatus.FAILURE, neededStatus: TspProviderResponseStatus.FAILURE,
severity: 'danger', severity: 'danger',
command: this.showErrors, command: () => this.showErrors(),
}, },
{ {
label: 'ابطال', label: 'ابطال',
icon: 'pi pi-eraser', icon: 'pi pi-eraser',
neededStatus: TspProviderResponseStatus.SUCCESS, neededStatus: TspProviderResponseStatus.SUCCESS,
severity: 'danger', severity: 'danger',
command: this.showRevokeConfirmation, command: () => this.showRevokeConfirmation(),
}, },
{ {
label: 'اصلاح', label: 'اصلاح',
icon: 'pi pi-file-edit', icon: 'pi pi-file-edit',
neededStatus: TspProviderResponseStatus.SUCCESS, neededStatus: TspProviderResponseStatus.SUCCESS,
severity: 'warn', severity: 'warn',
command: this.showCorrection, command: () => this.showCorrection(),
}, },
{ {
label: 'برگشت از فروش', label: 'برگشت از فروش',
icon: 'pi pi-cart-minus', icon: 'pi pi-cart-minus',
neededStatus: TspProviderResponseStatus.SUCCESS, neededStatus: TspProviderResponseStatus.SUCCESS,
severity: 'warn', severity: 'warn',
command: this.showReturnFromSale, command: () => this.showReturnFromSale(),
}, },
]; ];
@@ -1,25 +1,24 @@
<div class="inline-flex flex-col gap-1 w-full"> <div class="inline-flex w-full flex-col gap-1">
<div class="inline-flex gap-2 items-center w-full"> <div class="inline-flex w-full items-center gap-2">
<span class="text-muted-color text-base font-normal flex-auto grow-0">{{ label }}:</span> <span class="text-muted-color flex-auto grow-0 text-base font-normal">{{ label }}:</span>
<div <div
class="shrink-0 grow max-sm:text-left" class="text-text-color shrink-0 grow text-base font-bold max-sm:text-left"
[ngClass]="{ [ngClass]="{
'text-right': alignment === 'start', 'text-right': alignment === 'start',
'text-center': alignment === 'center', 'text-center': alignment === 'center',
'text-left': alignment === 'end', 'text-left': alignment === 'end',
}" }">
>
<ng-content> <ng-content>
@if (type === "thumbnail") { @if (type === 'thumbnail') {
<div class="w-20 h-20 rounded-2xl overflow-hidden bg-surface-100 cursor-pointer"> <div class="bg-surface-100 h-20 w-20 cursor-pointer overflow-hidden rounded-2xl">
@if (valueToShow()) { @if (valueToShow()) {
<img [src]="valueToShow()" class="w-full h-full object-cover" /> <img [src]="valueToShow()" class="h-full w-full object-cover" />
} }
</div> </div>
} @else if (valueType() === "tag") { } @else if (valueType() === 'tag') {
<p-tag [value]="valueToShow()?.toString()" [severity]="value ? 'contrast' : 'danger'" /> <p-tag [value]="valueToShow()?.toString()" [severity]="value ? 'contrast' : 'danger'" />
} @else { } @else {
<span class="text-text-color text-base font-bold grow"> {{ valueToShow() }}</span> <span class="text-text-color grow text-base font-bold"> {{ valueToShow() }}</span>
} }
</ng-content> </ng-content>
</div> </div>
@@ -15,6 +15,14 @@
[style]="{ display: 'none' }" [style]="{ display: 'none' }"
> >
</ng-template> </ng-template>
<input
#cameraInput
type="file"
class="hidden"
[accept]="accept"
[attr.capture]="accept?.includes('image') ? cameraCapture : null"
(change)="onNativeFileSelected($event)"
/>
<ng-template <ng-template
#content #content
let-files let-files
@@ -35,7 +43,7 @@
icon="pi pi-pencil" icon="pi pi-pencil"
severity="warn" severity="warn"
size="small" size="small"
(click)="chooseCallback()" (click)="openFilePicker()"
></button> ></button>
<button <button
pButton pButton
@@ -49,7 +57,7 @@
</div> </div>
</div> </div>
} @else { } @else {
<div class="flex items-center justify-center flex-col cursor-pointer py-5 w-full" (click)="chooseCallback()"> <div class="flex items-center justify-center flex-col cursor-pointer py-5 w-full" (click)="openFilePicker()">
<i class="pi pi-cloud-upload border-2! rounded-full! p-8! text-4xl! text-muted-color!"></i> <i class="pi pi-cloud-upload border-2! rounded-full! p-8! text-4xl! text-muted-color!"></i>
<p class="mt-6 mb-0">فایل مورد نظر خود را در اینجا رها کنید</p> <p class="mt-6 mb-0">فایل مورد نظر خود را در اینجا رها کنید</p>
</div> </div>
@@ -1,6 +1,7 @@
import { Maybe } from '@/core'; import { Maybe } from '@/core';
import { import {
Component, Component,
ElementRef,
EventEmitter, EventEmitter,
Input, Input,
OnChanges, OnChanges,
@@ -22,6 +23,7 @@ export class SharedUploadFileComponent implements OnChanges, OnDestroy {
@Input() loading: boolean = false; @Input() loading: boolean = false;
@Input() name: string = 'file'; @Input() name: string = 'file';
@Input() accept: string = 'image/*'; @Input() accept: string = 'image/*';
@Input() cameraCapture: 'user' | 'environment' = 'environment';
@Input() maxSize: Maybe<number> = 5 * 1024 * 1024; @Input() maxSize: Maybe<number> = 5 * 1024 * 1024;
@Input() error: Maybe<string> = null; @Input() error: Maybe<string> = null;
@Input() hint: Maybe<string> = null; @Input() hint: Maybe<string> = null;
@@ -30,6 +32,7 @@ export class SharedUploadFileComponent implements OnChanges, OnDestroy {
@Output() onSelect = new EventEmitter<onSelectFileArgs>(); @Output() onSelect = new EventEmitter<onSelectFileArgs>();
@ViewChild(FileUpload) uploader?: FileUpload; @ViewChild(FileUpload) uploader?: FileUpload;
@ViewChild('cameraInput') cameraInput?: ElementRef<HTMLInputElement>;
filePreview: Maybe<string> = null; filePreview: Maybe<string> = null;
private objectUrl: Maybe<string> = null; private objectUrl: Maybe<string> = null;
@@ -63,8 +66,26 @@ export class SharedUploadFileComponent implements OnChanges, OnDestroy {
this.onSelect.emit({ data: payload, file }); this.onSelect.emit({ data: payload, file });
} }
openFilePicker() {
this.cameraInput?.nativeElement.click();
}
onNativeFileSelected(event: Event) {
const input = event.target as HTMLInputElement;
const file = input.files?.[0];
if (!file) {
return;
}
this.setPreviewFromFile(file);
const payload = new FormData();
payload.append(this.name, file, file.name);
this.onSelect.emit({ data: payload, file });
input.value = '';
}
onEditFile() { onEditFile() {
this.uploader?.choose(); this.openFilePicker();
} }
onDeleteFilePreview() { onDeleteFilePreview() {
@@ -2,7 +2,7 @@
<input pInputText readonly [name]="name" [value]="valueToShow" class="w-full" /> <input pInputText readonly [name]="name" [value]="valueToShow" class="w-full" />
</uikit-field> </uikit-field>
<p-popover #op appendTo="body"> <p-popover #op appendTo="body">
<div #wrapperRef class="dir-rtl border-divider bg-background-paper w-full min-w-sm overflow-auto rounded-md"> <div #wrapperRef class="dir-rtl border-divider bg-background-paper w-full min-w-[320px] overflow-auto rounded-md">
<div class="bg-primary-main sticky top-0 flex justify-center px-3"> <div class="bg-primary-main sticky top-0 flex justify-center px-3">
<div class="flex items-center gap-3"> <div class="flex items-center gap-3">
<div class="flex h-8 items-center"> <div class="flex h-8 items-center">
+2 -2
View File
@@ -3,7 +3,7 @@
} }
.listKeyValue { .listKeyValue {
@apply grid md:grid-cols-3 sm:grid-cols-2 sm:gap-4 gap-3 items-center; @apply grid items-center gap-3 sm:grid-cols-2 sm:gap-4 md:grid-cols-3;
} }
.cardShadow { .cardShadow {
@@ -11,7 +11,7 @@
} }
.summaryList { .summaryList {
@apply max-h-125 flex; @apply flex max-h-125;
> * { > * {
@apply w-full; @apply w-full;
} }
-6
View File
@@ -13,12 +13,6 @@ a {
text-decoration: none; text-decoration: none;
} }
.layout-wrapper {
min-height: 100vh;
display: flex;
flex-direction: column;
}
html { html {
scroll-behavior: smooth; scroll-behavior: smooth;
font-size: 14px; font-size: 14px;
+1 -17
View File
@@ -1,23 +1,7 @@
.layout-main-container { .layout-main-container {
display: flex; // padding: 2rem 1rem 2rem 2rem;
flex-direction: column;
// height: 100vh;
// overflow: hidden;
justify-content: space-between;
padding: 2rem 1rem 2rem 2rem;
transition: margin-inline-start var(--layout-section-transition-duration); transition: margin-inline-start var(--layout-section-transition-duration);
&.hideMenu { &.hideMenu {
margin: 0 !important;
transform: translateX(0) !important; transform: translateX(0) !important;
padding-inline-start: 2rem !important;
}
&.isFullPage {
padding-inline-start: 0 !important;
padding: 0 !important;
} }
} }
.layout-main {
flex: 1 1 auto;
// overflow: auto;
}
+7
View File
@@ -0,0 +1,7 @@
.p-inputtext {
box-shadow: none !important;
}
* {
box-shadow: none !important;
}
+3 -2
View File
@@ -1,9 +1,10 @@
// TIS tenant environment configuration // TIS tenant environment configuration
export const environment = { export const environment = {
production: true, production: true,
// apiBaseUrl: 'https://psp-api.shift-am.ir', apiBaseUrl: 'https://psp-api.shift-am.ir',
// apiBaseUrl: 'http://192.168.128.73:5002', // apiBaseUrl: 'http://192.168.128.73:5002',
apiBaseUrl: 'http://localhost:5002', // apiBaseUrl: 'http://192.168.0.162:5002',
// apiBaseUrl: 'http://localhost:5002',
host: 'localhost', host: 'localhost',
port: 5000, port: 5000,
enableLogging: false, enableLogging: false,