feat: enhance order submission flow and UI improvements

- Updated categories component to improve loading state and category display.
- Modified order section to handle payment submission with event payload.
- Refactored payment form dialog to emit order response on successful payment.
- Adjusted order response model to enforce required fields.
- Improved root component layout and added success dialog for order submission.
- Enhanced sale invoice card component to use new TSP API methods.
- Updated API routes for sale invoices to reflect TSP changes.
- Improved user interface for business activities and partners sections.
- Added card shadow styling for better visual hierarchy.
- Introduced new order submitted dialog component for post-order actions.
- Cleaned up console logs and improved code readability across components.
This commit is contained in:
2026-05-08 18:08:57 +03:30
parent ce40bd8c75
commit a138034c06
40 changed files with 375 additions and 212 deletions
@@ -1,5 +1,5 @@
<app-page-data-list
pageTitle="لیست فعالیت‌های اقتصادی"
pageTitle="لیست فعالیت اقتصادی"
[columns]="columns"
emptyPlaceholderTitle="فعالیت اقتصادی‌ای یافت نشد."
[items]="items()"
@@ -14,7 +14,7 @@ export const superAdminConsumerBusinessActivitiesNamedRoutes: NamedRoutes<TBusin
),
// @ts-ignore
meta: {
title: 'فعالیت‌های اقتصادی',
title: 'فعالیت اقتصادی',
pagePath: (consumerId: string) =>
`/super_admin/consumers/${consumerId}/business_activities`,
},
@@ -21,7 +21,7 @@ export class ConsumersComponent extends AbstractList<IAdminConsumerResponse> {
this.columns = [
// { field: 'id', header: 'شناسه', type: 'id' },
{ field: 'name', header: 'نام' },
{ field: 'business_counts', header: 'تعداد فعالیت‌های اقتصادی' },
{ field: 'business_counts', header: 'تعداد فعالیت اقتصادی' },
{
field: 'partner',
header: 'ایجاد شده توسط',
@@ -1,15 +1,15 @@
<app-page-data-list
[pageTitle]="'مدیریت دسته‌بندی‌های کالا'"
[pageTitle]="'مدیریت دسته‌بندی‌ کالا'"
[addNewCtaLabel]="'افزودن دسته‌بندی'"
[columns]="columns"
emptyPlaceholderTitle="دسته‌بندی یافت نشد"
emptyPlaceholderDescription="برای افزودن دسته‌بندی، روی دکمهٔ بالا کلیک کنید."
[items]="items()"
[loading]="loading()"
[showDetails]="true"
[fullHeight]="fullHeight"
[showAdd]="true"
[showEdit]="true"
[fullHeight]="fullHeight"
[allItemsPageRoute]="allItemsPageRoute()"
(onEdit)="onEditClick($event)"
(onAdd)="openAddForm()"
(onRefresh)="refresh()"
@@ -4,7 +4,8 @@ import {
IColumn,
PageDataListComponent,
} from '@/shared/components/pageDataList/page-data-list.component';
import { Component, inject, Input } from '@angular/core';
import { Component, computed, inject, Input } from '@angular/core';
import { guildGoodCategoriesNamedRoutes } from '../../constants/routes/goodCategories';
import { IGoodCategoriesResponse } from '../../models';
import { GuildGoodCategoriesService } from '../../services/goodCategories.service';
import { GuildGoodCategoryFormComponent } from './form.component';
@@ -29,6 +30,10 @@ export class GuildGoodCategoriesListComponent extends AbstractList<IGoodCategori
];
service = inject(GuildGoodCategoriesService);
allItemsPageRoute = computed(() =>
guildGoodCategoriesNamedRoutes.goodCategories.meta.pagePath!(this.guildId),
);
override setColumns(): void {
this.columns = this.header;
}
@@ -5,12 +5,13 @@ export type TGuildGoodCategoriesRouteNames = 'goodCategories';
export const guildGoodCategoriesNamedRoutes: NamedRoutes<TGuildGoodCategoriesRouteNames> = {
goodCategories: {
path: 'good_categories',
path: 'good-categories',
loadComponent: () =>
import('../../views/categories/list.component').then((m) => m.GuildGoodCategoriesComponent),
// @ts-ignore
meta: {
title: 'دسته‌بندی‌های کالا',
pagePath: (guildId: string) => `/super_admin/guilds/${guildId}/good-categories`,
},
},
// goodCategory: {
@@ -39,26 +39,28 @@ export class GuildFormComponent extends AbstractFormDialog<IPartnerRequest, IPar
private service = inject(PartnersService);
private initForm() {
const form = this.fb.group({
const formConfig = {
name: fieldControl.name(this.initialValues?.name || ''),
code: fieldControl.code(this.initialValues?.code || ''),
username: fieldControl.username(),
password: fieldControl.password(),
confirmPassword: fieldControl.confirmPassword(),
});
username: [''],
password: [''],
confirmPassword: [''],
};
if (!this.editMode) {
form.controls.username.setValidators([Validators.required, usernameValidator()]);
form.controls.username.updateValueAndValidity({ emitEvent: false });
formConfig.username = fieldControl.username();
formConfig.password = fieldControl.password();
formConfig.confirmPassword = fieldControl.confirmPassword();
}
const form = this.fb.group(formConfig);
if (!this.editMode) {
// @ts-ignore
form.controls['username'].setValidators([Validators.required, usernameValidator()]);
// @ts-ignore
form.controls['username'].updateValueAndValidity({ emitEvent: false });
form.addValidators([MustMatch('password', 'confirmPassword')]);
} else {
// @ts-ignore
form.removeControl('username');
// @ts-ignore
form.removeControl('password');
// @ts-ignore
form.removeControl('confirmPassword');
form.removeValidators([MustMatch('password', 'confirmPassword')]);
}
return form;
@@ -75,15 +77,18 @@ export class GuildFormComponent extends AbstractFormDialog<IPartnerRequest, IPar
}
override ngOnChanges() {
this.form.patchValue(this.initialValues ?? {});
this.form = this.initForm();
this.form.patchValue((this.initialValues ?? {}) as Partial<Record<string, unknown>>);
if (this.editMode && !this.partnerId) {
throw 'missing some arguments';
}
this.initForm();
}
override submitForm(payload: IPartnerRequest) {
const formData = buildFormData(this.form, { logo: this.logo() }, ['confirmPassword']);
const skipFields = this.editMode
? ['confirmPassword', 'username', 'password']
: ['confirmPassword'];
const formData = buildFormData(this.form, { logo: this.logo() }, skipFields);
if (this.editMode) {
return this.service.update(this.partnerId!, formData);
+3 -1
View File
@@ -1,8 +1,10 @@
import { IEnumTranslate } from '@/shared/models/enum_translate.type';
export interface IPartnerRawResponse {
id: string;
name: string;
code: string;
status: string;
status: IEnumTranslate;
created_at: string;
logo_url: string;
licenses_status: {
@@ -38,7 +38,15 @@ export class PartnersComponent extends AbstractList<IPartnerResponse> {
header: 'تعداد لایسنس تمدیدی',
customDataModel: this.licensesRenewStatus,
},
{ field: 'status', header: 'وضعیت' },
{
field: 'status',
header: 'وضعیت',
type: 'nested',
variant: 'tag',
nestedOption: {
path: 'status.translate',
},
},
];
}
@@ -10,7 +10,7 @@ export const superAdminUserAccountsNamedRoutes: NamedRoutes<TAccountsRouteNames>
import('../../views/accounts/list.component').then((m) => m.UserAccountsComponent),
// @ts-ignore
meta: {
title: 'فعالیت‌های اقتصادی',
title: 'فعالیت اقتصادی',
pagePath: (userId: string) => `/super_admin/users/${userId}/accounts`,
},
},