feat: update consumer and partner components for improved data handling and UI enhancements

- Refactor ConsumerPosListComponent to dynamically set cookie domain based on hostname.
- Modify ConsumerUserFormContentComponent to correctly handle type selection and initialization.
- Enhance single.component.html to conditionally display consumer details based on type.
- Update ConsumerAccountListComponent to include nested role translation and pos details.
- Adjust IConsumerAccountRawResponse to use IEnumTranslate for role and add pos details.
- Refine ConsumersComponent to display translated status in the list view.
- Revise single.component.html for superAdmin to show translated consumer type and details.
- Improve AdminPartnerChargeAccountListComponent and AdminPartnerChargeLicenseTransactionListComponent by updating header labels.
- Add file upload functionality in form.component.html for partner creation.
- Enhance GuildFormComponent to handle file uploads and form data submission.
- Update AdminPartnerLicensesComponent to display consumer names correctly.
- Modify IPartnerActivatedLicenseResponse to include consumer_name for better clarity.
- Add logo_url to IPartnerRawResponse for displaying partner logos.
- Refactor PartnersService to handle FormData for partner creation and updates.
- Enhance list.component.html to include partner logos in the display.
- Update single.component.html for partners to show total counts for licenses and users.
- Implement payment result handling in AuthComponent for improved payment integration.
- Refactor SharedUploadFileComponent to manage file previews and uploads more effectively.
- Introduce IEnumTranslate interface for better type handling in consumer models.
- Update form-data utility to allow skipping specific fields during FormData construction.
- Add RTL support styles for file upload and avatar components.
- Change environment configuration for API base URL.
This commit is contained in:
2026-04-28 20:06:21 +03:30
parent 822bf96966
commit c89d4027d6
28 changed files with 362 additions and 70 deletions
@@ -21,7 +21,7 @@ export class CatalogGuildSelectComponent extends AbstractSelectComponent<
@Input() label: string = '';
private readonly service = inject(CatalogsService);
ngOnInit() {
ngAfterViewInit() {
this.getData();
}
@@ -1,8 +1,88 @@
<p-fileupload [name]="name" [accept]="accept" [maxFileSize]="maxSize" (onSelect)="onSelectedFile($event)">
<ng-template #header let-chooseCallback="chooseCallback">
<div class="flex items-center justify-center flex-col cursor-pointer py-5 w-full" (click)="chooseCallback()">
<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-fileupload
[name]="name"
[accept]="accept"
[maxFileSize]="maxSize"
mode="advanced"
(onSelect)="onSelectedFile($event)"
>
<ng-template
#header
let-files
let-chooseCallback="chooseCallback"
let-clearCallback="clearCallback"
let-uploadCallback="uploadCallback"
class="hidden"
[style]="{ display: 'none' }"
>
</ng-template>
<ng-template
#content
let-files
let-chooseCallback="chooseCallback"
let-uploadedFiles="uploadedFiles"
let-removeFileCallback="removeFileCallback"
let-removeUploadedFileCallback="removeUploadedFileCallback"
>
<div class="flex flex-col gap-8 pt-4">
@if (filePreview) {
<div class="flex justify-center">
<div class="inline-block relative">
<img [src]="filePreview" alt="Preview" class="max-h-52 rounded-lg object-contain" />
<div class="absolute left-2 top-2 flex gap-2">
<button
pButton
type="button"
icon="pi pi-pencil"
severity="warn"
size="small"
(click)="chooseCallback()"
></button>
<button
pButton
type="button"
icon="pi pi-trash"
severity="danger"
size="small"
(click)="onDeleteFilePreview()"
></button>
</div>
</div>
</div>
} @else {
<div class="flex items-center justify-center flex-col cursor-pointer py-5 w-full" (click)="chooseCallback()">
<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>
}
<!-- <div *ngIf="files?.length > 0">
<h5>Pending</h5>
<div class="flex flex-wrap gap-4">
<div *ngFor="let file of files; let i = index" class="p-8 rounded-border flex flex-col border border-surface items-center gap-4">
<div>
<img role="presentation" [alt]="file.name" [src]="file.objectURL" width="100" height="50" />
</div>
<span class="font-semibold text-ellipsis max-w-60 whitespace-nowrap overflow-hidden">{{ file.name }}</span>
<div>{{ formatSize(file.size) }}</div>
<p-badge value="Pending" severity="warn" />
<p-button icon="pi pi-times" (click)="onRemoveTemplatingFile($event, file, removeFileCallback, index)" [outlined]="true" [rounded]="true" severity="danger" />
</div>
</div>
</div>
<div *ngIf="uploadedFiles?.length > 0">
<h5>Completed</h5>
<div class="flex flex-wrap gap-4">
<div *ngFor="let file of uploadedFiles; let i = index" class="card m-0 px-12 flex flex-col border border-surface items-center gap-4">
<div>
<img role="presentation" [alt]="file.name" [src]="file.objectURL" width="100" height="50" />
</div>
<span class="font-semibold text-ellipsis max-w-60 whitespace-nowrap overflow-hidden">{{ file.name }}</span>
<div>{{ formatSize(file.size) }}</div>
<p-badge value="Completed" class="mt-4" severity="success" />
<p-button icon="pi pi-times" (onClick)="removeUploadedFileCallback(index)" [outlined]="true" [rounded]="true" severity="danger" />
</div>
</div>
</div> -->
</div>
</ng-template>
<ng-template #file></ng-template>
</p-fileupload>
@@ -1,31 +1,90 @@
import { Maybe } from '@/core';
import { Component, EventEmitter, Input, Output } from '@angular/core';
import {
Component,
EventEmitter,
Input,
OnChanges,
OnDestroy,
Output,
SimpleChanges,
ViewChild,
} from '@angular/core';
import { ButtonDirective } from 'primeng/button';
import { FileSelectEvent, FileUpload } from 'primeng/fileupload';
import { onSelectFileArgs } from './model';
@Component({
selector: 'app-shared-upload-file',
templateUrl: './upload-file.component.html',
imports: [FileUpload],
imports: [FileUpload, ButtonDirective],
})
export class SharedUploadFileComponent {
@Input() currentImage: Maybe<string> = null;
export class SharedUploadFileComponent implements OnChanges, OnDestroy {
@Input() loading: boolean = false;
@Input() name: string = 'file';
@Input() accept: string = 'image/*';
@Input() maxSize: Maybe<number> = 5 * 1024 * 1024;
@Input() error: Maybe<string> = null;
@Input() hint: Maybe<string> = null;
@Input() initial_file_url: Maybe<string> = null;
@Output() onSelect = new EventEmitter<onSelectFileArgs>();
@ViewChild(FileUpload) uploader?: FileUpload;
filePreview: Maybe<string> = null;
private objectUrl: Maybe<string> = null;
ngOnChanges(changes: SimpleChanges) {
if ('initial_file_url' in changes && !this.objectUrl) {
this.filePreview = this.initial_file_url;
}
}
ngAfterViewInit() {
this.revokeObjectUrl();
console.log('first');
if (this.initial_file_url && !this.objectUrl) {
this.filePreview = this.initial_file_url;
}
}
ngOnDestroy() {
this.revokeObjectUrl();
}
onSelectedFile($event: FileSelectEvent) {
const file = $event.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 });
}
onEditFile() {
this.uploader?.choose();
}
onDeleteFilePreview() {
this.revokeObjectUrl();
this.filePreview = null;
}
private setPreviewFromFile(file: File) {
this.revokeObjectUrl();
this.objectUrl = URL.createObjectURL(file);
this.filePreview = this.objectUrl;
}
private revokeObjectUrl() {
if (!this.objectUrl) {
return;
}
this.filePreview = null;
URL.revokeObjectURL(this.objectUrl);
this.objectUrl = null;
}
}
+3 -2
View File
@@ -1,11 +1,12 @@
import { Maybe } from '@/core';
import { IEnumTranslate } from './enum_translate.type';
export interface IConsumerRawResponse {
id: string;
status: string;
created_at: string;
name: string;
type: 'INDIVIDUAL' | 'LEGAL';
type: IEnumTranslate;
status: IEnumTranslate;
partner: {
id: string;
name: string;
@@ -0,0 +1,4 @@
export interface IEnumTranslate<T = string> {
value: T;
translate: string;
}