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
@@ -1,10 +1,10 @@
import { MustMatch, password } from '@/core/validators';
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 { Component, EventEmitter, Output, input } from '@angular/core';
import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
import { SharedPasswordInputComponent } from '../passwordInput/password-input.component';
import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component';
export interface IChangePasswordSubmitPayload {
password: string;
@@ -14,7 +14,12 @@ export interface IChangePasswordSubmitPayload {
@Component({
selector: 'shared-change-password-form-dialog',
templateUrl: './change-password-form-dialog.component.html',
imports: [ReactiveFormsModule, SharedDialogComponent, FormFooterActionsComponent, SharedPasswordInputComponent],
imports: [
ReactiveFormsModule,
SharedDialogComponent,
FormFooterActionsComponent,
SharedPasswordInputComponent,
],
})
export class ChangePasswordFormDialogComponent extends AbstractDialog {
title = input<string>('');
@@ -31,11 +36,11 @@ export class ChangePasswordFormDialogComponent extends AbstractDialog {
},
{
validators: [MustMatch('password', 'confirmPassword')],
},
}
);
get dialogHeader() {
return this.title() ? `تغییر گذرواژه ${this.title()}` : 'تغییر گذرواژه';
return this.title() ? `تغییر رمز عبور ${this.title()}` : 'تغییر رمز عبور';
}
submit() {
@@ -4,7 +4,7 @@
<div class="bg-surface-card flex flex-col items-center rounded p-8">
<div
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>
<span class="mt-6 mb-2 block text-2xl font-bold">{{ message.header }}</span>
<p class="mb-0">{{ message.message }}</p>
@@ -3,7 +3,7 @@
<div class="mt-4 flex flex-col gap-3">
@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">
<img
[src]="item.good_snapshot.image_url || ''"
@@ -3,13 +3,7 @@
} @else if (!invoice) {
<uikit-empty-state> </uikit-empty-state>
} @else {
<p-dialog [visible]="actionLoading" [closable]="false" header="لطفا صبر کنید">
<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">
<app-inner-pages-header [pageTitle]="`صورت‌حساب ${invoice.invoice_number}`" [backRoute]="backRoute">
<ng-template #actions>
<p-button (click)="printInvoice()" icon="pi pi-print" outlined size="small" label="چاپ" />
</ng-template>
@@ -18,7 +12,6 @@
<p-card>
<div class="flex flex-col gap-4">
<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.invoice_date" type="date" />
<app-key-value label="تاریخ ایجاد صورت‌حساب‌" [value]="invoice.created_at" type="dateTime" />
@@ -117,9 +110,9 @@
pButton
[label]="action.label || ''"
[icon]="action.icon || ''"
size="small"
[severity]="$any(action).severity || 'secondary'"
[outlined]="$any(action).severity === 'secondary'"
[loading]="actionLoading"
(click)="action.command()"></button>
}
</div>
@@ -110,17 +110,6 @@ export class SharedSaleInvoiceSingleViewComponent {
showCorrectionForm = 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 = () => {};
inquiry = () => {
this.onInquiry.emit();
@@ -150,49 +139,49 @@ export class SharedSaleInvoiceSingleViewComponent {
icon: 'pi pi-send',
neededStatus: TspProviderResponseStatus.SEND_FAILURE,
severity: 'info',
command: this.resend,
command: () => this.resend(),
},
{
label: 'ارسال صورت‌حساب',
icon: 'pi pi-send',
neededStatus: TspProviderResponseStatus.NOT_SEND,
severity: 'info',
command: this.send,
command: () => this.send(),
},
{
label: 'استعلام وضعیت',
icon: 'pi pi-info',
neededStatus: TspProviderResponseStatus.FISCAL_QUEUED,
severity: 'info',
command: this.inquiry,
command: () => this.inquiry(),
},
{
label: 'دلایل خطا',
icon: 'pi pi-question',
neededStatus: TspProviderResponseStatus.FAILURE,
severity: 'danger',
command: this.showErrors,
command: () => this.showErrors(),
},
{
label: 'ابطال',
icon: 'pi pi-eraser',
neededStatus: TspProviderResponseStatus.SUCCESS,
severity: 'danger',
command: this.showRevokeConfirmation,
command: () => this.showRevokeConfirmation(),
},
{
label: 'اصلاح',
icon: 'pi pi-file-edit',
neededStatus: TspProviderResponseStatus.SUCCESS,
severity: 'warn',
command: this.showCorrection,
command: () => this.showCorrection(),
},
{
label: 'برگشت از فروش',
icon: 'pi pi-cart-minus',
neededStatus: TspProviderResponseStatus.SUCCESS,
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 gap-2 items-center w-full">
<span class="text-muted-color text-base font-normal flex-auto grow-0">{{ label }}:</span>
<div class="inline-flex w-full flex-col gap-1">
<div class="inline-flex w-full items-center gap-2">
<span class="text-muted-color flex-auto grow-0 text-base font-normal">{{ label }}:</span>
<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]="{
'text-right': alignment === 'start',
'text-center': alignment === 'center',
'text-left': alignment === 'end',
}"
>
}">
<ng-content>
@if (type === "thumbnail") {
<div class="w-20 h-20 rounded-2xl overflow-hidden bg-surface-100 cursor-pointer">
@if (type === 'thumbnail') {
<div class="bg-surface-100 h-20 w-20 cursor-pointer overflow-hidden rounded-2xl">
@if (valueToShow()) {
<img [src]="valueToShow()" class="w-full h-full object-cover" />
<img [src]="valueToShow()" class="h-full w-full object-cover" />
}
</div>
} @else if (valueType() === "tag") {
} @else if (valueType() === 'tag') {
<p-tag [value]="valueToShow()?.toString()" [severity]="value ? 'contrast' : 'danger'" />
} @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>
</div>
@@ -15,6 +15,14 @@
[style]="{ display: 'none' }"
>
</ng-template>
<input
#cameraInput
type="file"
class="hidden"
[accept]="accept"
[attr.capture]="accept?.includes('image') ? cameraCapture : null"
(change)="onNativeFileSelected($event)"
/>
<ng-template
#content
let-files
@@ -35,7 +43,7 @@
icon="pi pi-pencil"
severity="warn"
size="small"
(click)="chooseCallback()"
(click)="openFilePicker()"
></button>
<button
pButton
@@ -49,7 +57,7 @@
</div>
</div>
} @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>
<p class="mt-6 mb-0">فایل مورد نظر خود را در اینجا رها کنید</p>
</div>
@@ -1,6 +1,7 @@
import { Maybe } from '@/core';
import {
Component,
ElementRef,
EventEmitter,
Input,
OnChanges,
@@ -22,6 +23,7 @@ export class SharedUploadFileComponent implements OnChanges, OnDestroy {
@Input() loading: boolean = false;
@Input() name: string = 'file';
@Input() accept: string = 'image/*';
@Input() cameraCapture: 'user' | 'environment' = 'environment';
@Input() maxSize: Maybe<number> = 5 * 1024 * 1024;
@Input() error: Maybe<string> = null;
@Input() hint: Maybe<string> = null;
@@ -30,6 +32,7 @@ export class SharedUploadFileComponent implements OnChanges, OnDestroy {
@Output() onSelect = new EventEmitter<onSelectFileArgs>();
@ViewChild(FileUpload) uploader?: FileUpload;
@ViewChild('cameraInput') cameraInput?: ElementRef<HTMLInputElement>;
filePreview: Maybe<string> = null;
private objectUrl: Maybe<string> = null;
@@ -63,8 +66,26 @@ export class SharedUploadFileComponent implements OnChanges, OnDestroy {
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() {
this.uploader?.choose();
this.openFilePicker();
}
onDeleteFilePreview() {