feat: add new form field components for company details and consumer management

- Implemented CompanyNameComponent, DescriptionComponent, DeviceIdComponent, EconomicCodeComponent, EmailComponent, FirstNameComponent, FiscalCodeComponent, GuildIdComponent, LastNameComponent, LegalNameComponent, LicenseStartsAtComponent, MobileComponent, MobileNumberComponent, ModelComponent, NameComponent, NationalCodeComponent, NationalIdComponent, PartnerTokenComponent, PosTypeComponent, PostalCodeComponent, ProviderIdComponent, QuantityComponent, RegistrationCodeComponent, RegistrationNumberComponent, SerialNumberComponent, SetOffComponent, SkuComponent, TerminalComponent, UnitPriceComponent, UsernameComponent.
- Added field control configurations for new fields in the form.
- Updated routing and branding configurations for TIS tenant.
- Created consumer type models for handling individual and legal consumer data.
This commit is contained in:
2026-04-27 21:53:11 +03:30
parent c085104976
commit 822bf96966
235 changed files with 4007 additions and 1260 deletions
@@ -1,4 +1,4 @@
<p-dialog
<shared-dialog
header="فرم کاربر"
[(visible)]="visible"
[modal]="true"
@@ -7,7 +7,7 @@
(onHide)="close()"
>
<form [formGroup]="form" (submit)="submit()" class="flex flex-col gap-4">
<app-input label="نام کاربری" [control]="form.controls.username" name="username" />
<field-username [control]="form.controls.username" />
<app-enum-select [control]="form.controls.role" name="role" type="consumerRole" />
<shared-password-input
[passwordControl]="form.controls.password"
@@ -15,4 +15,4 @@
/>
<app-form-footer-actions [submitLabel]="'ذخیره'" [loading]="submitLoading()" (onCancel)="close()" />
</form>
</p-dialog>
</shared-dialog>
@@ -2,21 +2,22 @@ import { MustMatch, password } from '@/core/validators';
// import { CatalogRolesComponent } from '@/shared/catalog/roles';
import { AbstractFormDialog } from '@/shared/abstractClasses';
import { EnumSelectComponent } from '@/shared/apiEnum/select.component';
import { InputComponent, SharedPasswordInputComponent } from '@/shared/components';
import { SharedPasswordInputComponent, UsernameComponent } from '@/shared/components';
import { fieldControl } from '@/shared/constants/fields';
import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component';
import { Component, inject, Input } from '@angular/core';
import { ReactiveFormsModule, Validators } from '@angular/forms';
import { Dialog } from 'primeng/dialog';
import { IConsumerAccountRequest, IConsumerAccountResponse } from '../../models';
import { AdminConsumerAccountsService } from '../../services/accounts.service';
import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component';
@Component({
selector: 'superAdmin-consumer-account-form',
templateUrl: './form.component.html',
imports: [
ReactiveFormsModule,
Dialog,
InputComponent,
SharedDialogComponent,
UsernameComponent,
FormFooterActionsComponent,
SharedPasswordInputComponent,
EnumSelectComponent,
@@ -35,7 +36,7 @@ export class ConsumerAccountFormComponent extends AbstractFormDialog<
if (this.editMode) {
return this.fb.group(
{
username: [this.initialValues?.username || '', [Validators.required]],
username: fieldControl.username(this.initialValues?.account?.username || ''),
password: ['', [password()]],
confirmPassword: [''],
},
@@ -46,7 +47,7 @@ export class ConsumerAccountFormComponent extends AbstractFormDialog<
}
return this.fb.group(
{
username: [this.initialValues?.username || '', [Validators.required]],
username: fieldControl.username(this.initialValues?.account?.username || ''),
role: ['', [Validators.required]],
password: ['', [Validators.required, password()]],
confirmPassword: ['', [Validators.required]],
@@ -1,4 +1,4 @@
<p-dialog
<shared-dialog
[header]="preparedTitle"
[(visible)]="visible"
[modal]="true"
@@ -7,8 +7,11 @@
(onHide)="close()"
>
<form [formGroup]="form" (submit)="submit()" class="flex flex-col gap-4">
<app-input label="عنوان" [control]="form.controls.name" name="name" />
<catalog-guild-select label="صنف" [control]="form.controls.guild_id" name="guild_id" />
<field-name [control]="form.controls.name" />
<field-economic-code [control]="form.controls.economic_code" />
<field-fiscal-code [control]="form.controls.fiscal_code" />
<field-partner-token [control]="form.controls.partner_token" />
<field-guild-id [control]="form.controls.guild_id" />
<app-form-footer-actions [submitLabel]="'ذخیره'" [loading]="submitLoading()" (onCancel)="close()" />
</form>
</p-dialog>
</shared-dialog>
@@ -1,23 +1,32 @@
// import { CatalogRolesComponent } from '@/shared/catalog/roles';
import { AbstractFormDialog } from '@/shared/abstractClasses';
import { CatalogGuildSelectComponent } from '@/shared/catalog/guild/components/select.component';
import { InputComponent } from '@/shared/components';
import {
EconomicCodeComponent,
FiscalCodeComponent,
GuildIdComponent,
NameComponent,
PartnerTokenComponent,
} from '@/shared/components';
import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component';
import { fieldControl } from '@/shared/constants/fields';
import { Component, inject, Input } from '@angular/core';
import { ReactiveFormsModule, Validators } from '@angular/forms';
import { Dialog } from 'primeng/dialog';
import { ReactiveFormsModule } from '@angular/forms';
import { IBusinessActivityRequest, IBusinessActivityResponse } from '../../models';
import { AdminConsumerBusinessActivitiesService } from '../../services/businessActivities.service';
import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component';
@Component({
selector: 'superAdmin-consumer-businessActivities-form',
templateUrl: './form.component.html',
imports: [
ReactiveFormsModule,
Dialog,
InputComponent,
SharedDialogComponent,
NameComponent,
EconomicCodeComponent,
FiscalCodeComponent,
PartnerTokenComponent,
GuildIdComponent,
FormFooterActionsComponent,
CatalogGuildSelectComponent,
],
})
export class ConsumerBusinessActivitiesFormComponent extends AbstractFormDialog<
@@ -31,9 +40,12 @@ export class ConsumerBusinessActivitiesFormComponent extends AbstractFormDialog<
initForm = () => {
return this.fb.group({
name: [this.initialValues?.name || '', [Validators.required]],
name: fieldControl.name(this.initialValues?.name || ''),
economic_code: fieldControl.economic_code(this.initialValues?.economic_code || ''),
fiscal_code: fieldControl.fiscal_code(this.initialValues?.fiscal_code || ''),
partner_token: fieldControl.partner_token(this.initialValues?.partner_token || ''),
// @ts-ignore
guild_id: [this.initialValues?.guild?.id || '', [Validators.required]],
guild_id: fieldControl.guild_id(this.initialValues?.guild?.id || ''),
});
};
@@ -1,4 +1,4 @@
<p-dialog
<shared-dialog
[header]="preparedTitle"
[(visible)]="visible"
[modal]="true"
@@ -7,9 +7,9 @@
(onHide)="close()"
>
<form [formGroup]="form" (submit)="submit()" class="flex flex-col gap-4">
<app-input label="عنوان" [control]="form.controls.name" name="name" />
<app-input label="کد شعبه" [control]="form.controls.branch_code" name="branch_code" />
<app-input label="آدرس" [control]="form.controls.address" name="address" />
<field-name [control]="form.controls.name" />
<field-branch-code [control]="form.controls.branch_code" />
<field-address [control]="form.controls.address" />
<app-form-footer-actions [submitLabel]="'ذخیره'" [loading]="submitLoading()" (onCancel)="close()" />
</form>
</p-dialog>
</shared-dialog>
@@ -1,17 +1,29 @@
// import { CatalogRolesComponent } from '@/shared/catalog/roles';
import { AbstractFormDialog } from '@/shared/abstractClasses';
import { InputComponent } from '@/shared/components';
import {
NameComponent,
AddressComponent,
BranchCodeComponent,
} from '@/shared/components';
import { fieldControl } from '@/shared/constants/fields';
import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component';
import { Component, inject, Input } from '@angular/core';
import { ReactiveFormsModule, Validators } from '@angular/forms';
import { Dialog } from 'primeng/dialog';
import { ReactiveFormsModule } from '@angular/forms';
import { IComplexRequest, IComplexResponse } from '../../models';
import { AdminComplexesService } from '../../services/complexes.service';
import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component';
@Component({
selector: 'superAdmin-consumer-complex-form',
templateUrl: './form.component.html',
imports: [ReactiveFormsModule, Dialog, InputComponent, FormFooterActionsComponent],
imports: [
ReactiveFormsModule,
SharedDialogComponent,
NameComponent,
BranchCodeComponent,
AddressComponent,
FormFooterActionsComponent,
],
})
export class ConsumerComplexFormComponent extends AbstractFormDialog<
IComplexRequest,
@@ -25,9 +37,9 @@ export class ConsumerComplexFormComponent extends AbstractFormDialog<
initForm = () => {
return this.fb.group({
name: [this.initialValues?.name || '', [Validators.required]],
branch_code: [this.initialValues?.branch_code || ''],
address: [this.initialValues?.address || '', [Validators.required]],
name: fieldControl.name(this.initialValues?.name || ''),
branch_code: fieldControl.branch_code(this.initialValues?.branch_code || ''),
address: fieldControl.address(this.initialValues?.address || ''),
});
};
@@ -1,4 +1,4 @@
<p-dialog
<shared-dialog
[header]="preparedTitle()"
[(visible)]="visible"
[modal]="true"
@@ -7,28 +7,28 @@
(onHide)="close()"
>
<form [formGroup]="form" (submit)="submit()" class="flex flex-col gap-4">
<app-input label="نام" [control]="form.controls.first_name" name="first_name" />
<!-- <app-input label="نام" [control]="form.controls.first_name" name="first_name" />
<app-input label="نام خانوادگی" [control]="form.controls.last_name" name="last_name" />
<app-input label="موبایل" [control]="form.controls.mobile_number" name="mobile_number" type="mobile" />
<app-input label="موبایل" [control]="form.controls.mobile_number" name="mobile_number" type="mobile" /> -->
@if (!editMode) {
<p-divider align="center"> اطلاعات ورود </p-divider>
<!-- @ts-ignore -->
<app-input label="نام کاربری" [control]="form.controls.username" name="username" [isLtrInput]="true" />
<field-username [control]="form.controls.username" />
<shared-password-input
[passwordControl]="form.controls.password"
[confirmPasswordControl]="form.controls.confirmPassword"
/>
<p-divider align="center"> اطلاعات لایسنس </p-divider>
<uikit-datepicker
<!-- <uikit-datepicker
label="تاریخ شروع لایسنس"
[control]="form.controls.license.controls.starts_at"
name="license.starts_at"
hint="مدت زمان لایسنس‌ها ۱ ساله هستند."
/>
/> -->
<!-- <uikit-datepicker label="تاریخ انقضای لایسنس" [control]="form.controls.license.controls.expires_at" name="license.expires_at" /> -->
<app-partner-select label="شریک تجاری" [control]="form.controls.license.controls.partner_id" />
<!-- <app-partner-select label="شریک تجاری" [control]="form.controls.license.controls.partner_id" /> -->
}
<app-form-footer-actions [submitLabel]="'ذخیره'" [loading]="submitLoading()" (onCancel)="close()" />
</form>
</p-dialog>
</shared-dialog>
@@ -1,14 +1,13 @@
import { mobileValidator, MustMatch } from '@/core/validators';
import { MustMatch } from '@/core/validators';
import { AbstractFormDialog } from '@/shared/abstractClasses';
import { InputComponent, SharedPasswordInputComponent } from '@/shared/components';
import { SharedPasswordInputComponent, UsernameComponent } from '@/shared/components';
import { fieldControl } from '@/shared/constants/fields';
import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component';
import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component';
import { UikitFlatpickrJalaliComponent } from '@/uikit';
import { Component, computed, inject, Input } from '@angular/core';
import { ReactiveFormsModule, Validators } from '@angular/forms';
import { Dialog } from 'primeng/dialog';
import { Divider } from 'primeng/divider';
import { PartnerSelectComponent } from '../../partners/shared/select.component';
import { IConsumerRequest, IConsumerResponse } from '../models';
import { IAdminConsumerRequest, IAdminConsumerResponse } from '../models';
import { ConsumersService } from '../services/main.service';
@Component({
@@ -16,18 +15,16 @@ import { ConsumersService } from '../services/main.service';
templateUrl: './form.component.html',
imports: [
ReactiveFormsModule,
Dialog,
InputComponent,
SharedDialogComponent,
UsernameComponent,
FormFooterActionsComponent,
Divider,
UikitFlatpickrJalaliComponent,
PartnerSelectComponent,
SharedPasswordInputComponent,
],
})
export class ConsumerUserFormComponent extends AbstractFormDialog<
IConsumerRequest,
IConsumerResponse
IAdminConsumerRequest,
IAdminConsumerResponse
> {
@Input() consumerId?: string;
private service = inject(ConsumersService);
@@ -36,19 +33,19 @@ export class ConsumerUserFormComponent extends AbstractFormDialog<
initForm = () => {
const form = this.fb.group({
first_name: [this.initialValues?.first_name || '', [Validators.required]],
last_name: [this.initialValues?.last_name || '', [Validators.required]],
mobile_number: [
this.initialValues?.mobile_number || '',
[Validators.required, mobileValidator()],
],
// first_name: [this.initialValues?.first_name || '', [Validators.required]],
// last_name: [this.initialValues?.last_name || '', [Validators.required]],
// mobile_number: [
// this.initialValues?.mobile_number || '',
// [Validators.required, mobileValidator()],
// ],
username: [''],
password: [''],
confirmPassword: [''],
license: this.fb.group({
starts_at: [this.initialValues?.license_info?.starts_at || ''],
partner_id: [this.initialValues?.license_info?.partner?.id || ''],
}),
// license: this.fb.group({
// starts_at: [this.initialValues?.license_info?.starts_at || ''],
// partner_id: [this.initialValues?.license_info?.partner?.id || ''],
// }),
});
if (this.editMode) {
@@ -60,13 +57,15 @@ export class ConsumerUserFormComponent extends AbstractFormDialog<
form.removeControl('confirmPassword');
form.removeValidators([MustMatch('password', 'confirmPassword')]);
} else {
// @ts-ignore
form.addControl(
'username',
this.fb.control<string>('', {
nonNullable: true,
validators: [Validators.required],
validators: fieldControl.username('')[1],
}),
);
// @ts-ignore
form.addControl(
'password',
this.fb.control<string>('', {
@@ -74,6 +73,7 @@ export class ConsumerUserFormComponent extends AbstractFormDialog<
validators: [Validators.required],
}),
);
// @ts-ignore
form.addControl(
'confirmPassword',
this.fb.control<string>('', {
@@ -90,13 +90,14 @@ export class ConsumerUserFormComponent extends AbstractFormDialog<
form = this.initForm();
override ngOnChanges() {
this.form.patchValue({
...(this.initialValues ?? {}),
license: {
...(this.initialValues?.license_info ?? {}),
partner_id: this.initialValues?.license_info?.partner?.id || '',
},
});
// this.form.patchValue(this.initialValues ?? {});
// this.form.patchValue({
// ...(this.initialValues ?? {}),
// license: {
// ...(this.initialValues?.license_info ?? {}),
// partner_id: this.initialValues?.license_info?.partner?.id || '',
// },
// });
if (this.editMode && !this.consumerId) {
throw 'missing some arguments';
}
@@ -104,7 +105,7 @@ export class ConsumerUserFormComponent extends AbstractFormDialog<
this.form = this.initForm();
}
override submitForm(payload: IConsumerRequest) {
override submitForm(payload: IAdminConsumerRequest) {
if (this.editMode) {
return this.service.update(this.consumerId!, payload);
}
@@ -1,4 +1,4 @@
<p-dialog
<shared-dialog
[header]="preparedTitle()"
[(visible)]="visible"
[modal]="true"
@@ -17,4 +17,4 @@
<app-partner-select label="شریک تجاری" [control]="form.controls.partner_id" [showClear]="true" />
<app-form-footer-actions [submitLabel]="'ذخیره'" [loading]="submitLoading()" (onCancel)="close()" />
</form>
</p-dialog>
</shared-dialog>
@@ -3,17 +3,17 @@ import { FormFooterActionsComponent } from '@/shared/components/formFooterAction
import { UikitFlatpickrJalaliComponent } from '@/uikit';
import { Component, computed, inject, Input } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { Dialog } from 'primeng/dialog';
import { PartnerSelectComponent } from '../../../partners/shared/select.component';
import { ILicenseRequest, ILicenseResponse } from '../../models';
import { LicensesService } from '../../services/licenses.service';
import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component';
@Component({
selector: 'superAdmin-consumer-license-form',
templateUrl: './form.component.html',
imports: [
ReactiveFormsModule,
Dialog,
SharedDialogComponent,
FormFooterActionsComponent,
UikitFlatpickrJalaliComponent,
PartnerSelectComponent,
@@ -1,4 +1,4 @@
<p-dialog
<shared-dialog
[header]="preparedTitle"
[(visible)]="visible"
[modal]="true"
@@ -7,14 +7,14 @@
(onHide)="close()"
>
<form [formGroup]="form" (submit)="submit()" class="flex flex-col gap-4">
<app-input label="عنوان" [control]="form.controls.name" name="name" />
<app-input label="سریال دستگاه" [control]="form.controls.serial_number" name="serial_number" />
<field-name [control]="form.controls.name" />
<field-serial-number [control]="form.controls.serial_number" />
<!-- <app-input label="مدل دستگاه" [control]="form.controls.model" name="model" /> -->
<app-enum-select [control]="form.controls.pos_type" type="posType" name="pos_type" />
<field-pos-type [control]="form.controls.pos_type" />
@if (form.controls.pos_type.value === "PSP") {
<catalog-device-select [control]="form.controls.device_id" />
<catalog-provider-select [control]="form.controls.provider_id" />
<field-device-id [control]="form.controls.device_id" />
<field-provider-id [control]="form.controls.provider_id" />
}
<app-form-footer-actions [submitLabel]="'ذخیره'" [loading]="submitLoading()" (onCancel)="close()" />
</form>
</p-dialog>
</shared-dialog>
@@ -1,27 +1,32 @@
// import { CatalogRolesComponent } from '@/shared/catalog/roles';
import { AbstractFormDialog } from '@/shared/abstractClasses';
import { EnumSelectComponent } from '@/shared/apiEnum/select.component';
import { CatalogProviderSelectComponent } from '@/shared/catalog';
import { CatalogDeviceSelectComponent } from '@/shared/catalog/devices';
import { InputComponent } from '@/shared/components';
import {
NameComponent,
DeviceIdComponent,
ProviderIdComponent,
SerialNumberComponent,
PosTypeComponent,
} from '@/shared/components';
import { fieldControl } from '@/shared/constants/fields';
import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component';
import { Component, inject, Input } from '@angular/core';
import { ReactiveFormsModule, Validators } from '@angular/forms';
import { Dialog } from 'primeng/dialog';
import { IPosRequest, IPosResponse } from '../../models';
import { AdminPosesService } from '../../services/poses.service';
import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component';
@Component({
selector: 'superAdmin-consumer-pos-form',
templateUrl: './form.component.html',
imports: [
ReactiveFormsModule,
Dialog,
InputComponent,
SharedDialogComponent,
NameComponent,
FormFooterActionsComponent,
CatalogDeviceSelectComponent,
CatalogProviderSelectComponent,
EnumSelectComponent,
DeviceIdComponent,
ProviderIdComponent,
PosTypeComponent,
SerialNumberComponent,
],
})
export class ConsumerPosFormComponent extends AbstractFormDialog<IPosRequest, IPosResponse> {
@@ -34,27 +39,29 @@ export class ConsumerPosFormComponent extends AbstractFormDialog<IPosRequest, IP
initForm = () => {
const form = this.fb.group({
name: [this.initialValues?.name || '', [Validators.required]],
serial_number: [this.initialValues?.serial_number || '', [Validators.required]],
name: fieldControl.name(this.initialValues?.name || ''),
serial_number: fieldControl.serial_number(this.initialValues?.serial_number || '', true),
// model: [this.initialValues?.model || '', [Validators.required]],
pos_type: [this.initialValues?.pos_type || '', [Validators.required]],
device_id: [this.initialValues?.device?.id || ''],
provider_id: [this.initialValues?.provider?.id || ''],
pos_type: fieldControl.pos_type(this.initialValues?.pos_type || ''),
device_id: fieldControl.device_id(this.initialValues?.device?.id || ''),
provider_id: fieldControl.provider_id(this.initialValues?.provider?.id || ''),
});
form.controls.pos_type.valueChanges.subscribe((value) => {
if (value === 'PSP') {
// @ts-ignore
form.addControl(
'device_id',
this.fb.control<string>(this.initialValues?.device?.id ?? '', {
nonNullable: true,
validators: [Validators.required],
validators: fieldControl.device_id('', true)[1],
}),
);
// @ts-ignore
form.addControl(
'provider_id',
this.fb.control<string>(this.initialValues?.provider?.id ?? '', {
nonNullable: true,
validators: [Validators.required],
validators: fieldControl.provider_id('', true)[1],
}),
);
} else {
@@ -1,13 +1,24 @@
import { TAccountType } from '@/core/constants/accountTypes.const';
export interface IConsumerAccountRawResponse {
username: string;
id: string;
role: string;
created_at: string;
account: AccountInfo;
}
export interface IConsumerAccountResponse extends IConsumerAccountRawResponse {}
export interface IConsumerAccountRequest {
username: string;
password?: string;
type: TAccountType;
// Backend accepts role on create and status on update.
role?: string;
status?: string;
// Keep type optional for current form compatibility.
type?: TAccountType;
}
interface AccountInfo {
username: string;
status: string;
}
@@ -2,6 +2,9 @@ import ISummary from '@/core/models/summary';
export interface IBusinessActivityRawResponse {
name: string;
economic_code: string;
fiscal_code: string;
partner_token: string;
guild: ISummary;
id: string;
}
@@ -9,5 +12,8 @@ export interface IBusinessActivityResponse extends IBusinessActivityRawResponse
export interface IBusinessActivityRequest {
name: string;
economic_code: string;
fiscal_code: string;
partner_token: string;
guild_id: string;
}
+5 -25
View File
@@ -1,28 +1,8 @@
import ISummary from '@/core/models/summary';
import { IConsumerRequest, IConsumerResponse } from '@/shared/models/consumer.type';
export interface IConsumerRawResponse {
id: string;
first_name: string;
last_name: string;
mobile_number: string;
status: string;
created_at: string;
fullname: string;
license_info: ILicenseInfo;
}
export interface IConsumerResponse extends IConsumerRawResponse {}
export interface IAdminConsumerRawResponse extends IConsumerResponse {}
export interface IAdminConsumerResponse extends IAdminConsumerRawResponse {}
export interface IConsumerRequest {
first_name: string;
last_name: string;
mobile_number: string;
username: string;
password: string;
}
interface ILicenseInfo {
id: string;
starts_at: string;
expires_at: string;
partner: ISummary;
export interface IAdminConsumerRequest extends IConsumerRequest {
partner_id: string;
}
@@ -3,7 +3,11 @@ import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { CONSUMERS_API_ROUTES } from '../constants';
import { IConsumerRawResponse, IConsumerRequest, IConsumerResponse } from '../models';
import {
IAdminConsumerRawResponse,
IAdminConsumerRequest,
IAdminConsumerResponse,
} from '../models';
@Injectable({ providedIn: 'root' })
export class ConsumersService {
@@ -11,18 +15,18 @@ export class ConsumersService {
private apiRoutes = CONSUMERS_API_ROUTES;
getAll(): Observable<IPaginatedResponse<IConsumerResponse>> {
return this.http.get<IPaginatedResponse<IConsumerRawResponse>>(this.apiRoutes.list());
getAll(): Observable<IPaginatedResponse<IAdminConsumerResponse>> {
return this.http.get<IPaginatedResponse<IAdminConsumerRawResponse>>(this.apiRoutes.list());
}
getSingle(consumerId: string): Observable<IConsumerResponse> {
return this.http.get<IConsumerRawResponse>(this.apiRoutes.single(consumerId));
getSingle(consumerId: string): Observable<IAdminConsumerResponse> {
return this.http.get<IAdminConsumerRawResponse>(this.apiRoutes.single(consumerId));
}
create(userData: IConsumerRequest): Observable<IConsumerResponse> {
return this.http.post<IConsumerResponse>(this.apiRoutes.list(), userData);
create(userData: IAdminConsumerRequest): Observable<IAdminConsumerResponse> {
return this.http.post<IAdminConsumerResponse>(this.apiRoutes.list(), userData);
}
update(consumerId: string, userData: IConsumerRequest): Observable<IConsumerResponse> {
return this.http.patch<IConsumerResponse>(this.apiRoutes.single(consumerId), userData);
update(consumerId: string, userData: IAdminConsumerRequest): Observable<IAdminConsumerResponse> {
return this.http.patch<IAdminConsumerResponse>(this.apiRoutes.single(consumerId), userData);
}
}
@@ -3,17 +3,17 @@ import { computed, inject, Injectable } from '@angular/core';
import { MenuItem } from 'primeng/api';
import { catchError, finalize } from 'rxjs';
import { superAdminConsumersNamedRoutes } from '../constants';
import { IConsumerResponse } from '../models';
import { IAdminConsumerResponse } from '../models';
import { ConsumersService } from '../services/main.service';
interface ConsumerState extends EntityState<IConsumerResponse> {
interface ConsumerState extends EntityState<IAdminConsumerResponse> {
breadcrumbItems: MenuItem[];
}
@Injectable({
providedIn: 'root',
})
export class ConsumerStore extends EntityStore<IConsumerResponse, ConsumerState> {
export class ConsumerStore extends EntityStore<IAdminConsumerResponse, ConsumerState> {
private readonly service = inject(ConsumersService);
constructor() {
super({
@@ -36,7 +36,7 @@ export class ConsumerStore extends EntityStore<IConsumerResponse, ConsumerState>
routerLink: superAdminConsumersNamedRoutes.consumers.meta.pagePath!(),
},
{
title: this.entity()?.fullname,
title: this.entity()?.name,
routerLink: superAdminConsumersNamedRoutes.consumer.meta.pagePath!(consumerId),
},
],
@@ -1,14 +1,10 @@
<app-page-data-list
pageTitle="مدیریت مشتریان"
[addNewCtaLabel]="'افزودن مشتری جدید'"
[columns]="columns"
[showAdd]="true"
emptyPlaceholderTitle="مشتری‌ای یافت نشد"
emptyPlaceholderDescription="برای افزودن مشتری جدید، روی دکمهٔ بالا کلیک کنید."
[items]="items()"
[loading]="loading()"
[showDetails]="true"
[showAdd]="true"
[showEdit]="true"
(onAdd)="openAddForm()"
(onDetails)="toSinglePage($event)"
@@ -1,12 +1,11 @@
// import { CatalogRoleTagComponent } from '@/shared/catalog/roles';
import { AbstractList } from '@/shared/abstractClasses/abstract-list';
import { PageDataListComponent } from '@/shared/components/pageDataList/page-data-list.component';
import { formatJalali } from '@/utils';
import { Component, inject } from '@angular/core';
import { Router } from '@angular/router';
import { ConsumerUserFormComponent } from '../components/form.component';
import { superAdminConsumersNamedRoutes } from '../constants';
import { IConsumerResponse } from '../models';
import { IAdminConsumerResponse } from '../models';
import { ConsumersService } from '../services/main.service';
@Component({
@@ -14,26 +13,32 @@ import { ConsumersService } from '../services/main.service';
templateUrl: './list.component.html',
imports: [PageDataListComponent, ConsumerUserFormComponent],
})
export class ConsumersComponent extends AbstractList<IConsumerResponse> {
export class ConsumersComponent extends AbstractList<IAdminConsumerResponse> {
private readonly service = inject(ConsumersService);
private readonly router = inject(Router);
override setColumns(): void {
this.columns = [
{ field: 'id', header: 'شناسه', type: 'id' },
{ field: 'fullname', header: 'نام' },
{ field: 'mobile_number', header: 'شماره موبایل' },
{ field: 'status', header: 'وضعیت' },
{ field: 'name', header: 'نام' },
{ field: 'business_counts', header: 'تعداد فعالیت‌های اقتصادی' },
{
field: 'license_expires_at',
header: 'تاریخ انقضای لایسنس',
customDataModel(item) {
if (item.license_info) {
return formatJalali(item.license_info.expires_at);
}
return 'بدون لایسنس';
},
field: 'partner',
header: 'ایجاد شده توسط',
type: 'nested',
nestedOption: { path: 'partner.name' },
},
{ field: 'status', header: 'وضعیت' },
// {
// field: 'license_expires_at',
// header: 'تاریخ انقضای لایسنس',
// customDataModel(item) {
// if (item.license_info) {
// return formatJalali(item.license_info.expires_at);
// }
// return 'بدون لایسنس';
// },
// },
{
field: 'created_at',
header: 'تاریخ ایجاد',
@@ -46,7 +51,7 @@ export class ConsumersComponent extends AbstractList<IConsumerResponse> {
return this.service.getAll();
}
toSinglePage(consumer: IConsumerResponse) {
toSinglePage(consumer: IAdminConsumerResponse) {
this.router.navigateByUrl(superAdminConsumersNamedRoutes.consumer.meta.pagePath!(consumer.id));
}
}
@@ -3,28 +3,9 @@
<ng-template #moreActions> </ng-template>
<div class="flex flex-col gap-4">
<div class="grid grid-cols-3 gap-4 items-center">
<app-key-value label="نام مشتری" [value]="consumer()?.fullname" />
<app-key-value label="شماره موبایل" [value]="consumer()?.mobile_number" />
<app-key-value label="نام مشتری" [value]="consumer()?.name" />
<app-key-value label="نوع مشتری" [value]="consumer()?.type" />
<app-key-value label="وضعیت" [value]="consumer()?.status" />
@if (licenseStatus() === "EXPIRED") {
<app-key-value label="وضعیت لایسنس">
<p-button size="small" outlined severity="warn" (onClick)="openLicenseForm()">
منقضی شده در <span [jalaliDate]="license()!.expires_at"></span>
</p-button>
</app-key-value>
<app-key-value label="ارایه شده توسط" [value]="license()?.partner?.name || 'برند نرم‌افزار'" />
} @else if (licenseStatus() === "ACTIVE") {
<app-key-value label="وضعیت لایسنس">
<p-button size="small" outlined severity="success" (onClick)="openLicenseForm()">
تا تاریخ <span [jalaliDate]="license()!.expires_at"></span>
</p-button>
</app-key-value>
<!-- <app-key-value label="ارایه شده توسط" [value]="license()?.partner?.name || 'برند نرم‌افزار'" /> -->
} @else {
<app-key-value label="وضعیت لایسنس">
<p-button size="small" outlined severity="danger" (onClick)="openLicenseForm()"> ارایه نشده </p-button>
</app-key-value>
}
</div>
</div>
</app-card-data>
@@ -39,13 +20,4 @@
[initialValues]="consumer() || undefined"
(onSubmit)="getData()"
/>
<superAdmin-consumer-license-form
[(visible)]="visibleLicenseForm"
[editMode]="!!license()?.id"
[consumerId]="consumerId()"
[licenseId]="license()?.id"
[initialValues]="license() || undefined"
(onSubmit)="getData()"
/>
</div>
@@ -1,14 +1,10 @@
import { BreadcrumbService } from '@/core/services';
import { AppCardComponent, KeyValueComponent } from '@/shared/components';
import { JalaliDateDirective } from '@/shared/directives';
import { getLicenseStatus } from '@/utils';
import { Component, computed, effect, inject, signal } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Button } from 'primeng/button';
import { ConsumerAccountListComponent } from '../components/accounts/list.component';
import { ConsumerBusinessActivitiesComponent } from '../components/businessActivities/list.component';
import { ConsumerUserFormComponent } from '../components/form.component';
import { ConsumerLicenseFormComponent } from '../components/licenses/form.component';
import { ConsumerStore } from '../store/consumer.store';
@Component({
@@ -20,9 +16,6 @@ import { ConsumerStore } from '../store/consumer.store';
ConsumerUserFormComponent,
ConsumerAccountListComponent,
ConsumerBusinessActivitiesComponent,
Button,
JalaliDateDirective,
ConsumerLicenseFormComponent,
],
})
export class ConsumerComponent {
@@ -37,10 +30,6 @@ export class ConsumerComponent {
readonly loading = computed(() => this.store.loading());
readonly consumer = computed(() => this.store.entity());
readonly license = computed(() => this.store.entity()?.license_info);
readonly licenseStatus = computed(() =>
getLicenseStatus(this.store.entity()?.license_info?.expires_at),
);
constructor() {
effect(() => {
@@ -1,4 +1,4 @@
<p-dialog
<shared-dialog
[header]="preparedTitle()"
[(visible)]="visible"
[modal]="true"
@@ -10,4 +10,4 @@
<app-input label="عنوان" [control]="form.controls.name" name="name" />
<app-form-footer-actions [submitLabel]="'ذخیره'" [loading]="submitLoading()" (onCancel)="close()" />
</form>
</p-dialog>
</shared-dialog>
@@ -3,14 +3,14 @@ import { InputComponent } from '@/shared/components';
import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component';
import { Component, computed, inject, Input } from '@angular/core';
import { ReactiveFormsModule, Validators } from '@angular/forms';
import { Dialog } from 'primeng/dialog';
import { IDeviceBrandRequest, IDeviceBrandResponse } from '../models';
import { DeviceBrandsService } from '../services/main.service';
import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component';
@Component({
selector: 'deviceBrand-form',
templateUrl: './form.component.html',
imports: [ReactiveFormsModule, Dialog, InputComponent, FormFooterActionsComponent],
imports: [ReactiveFormsModule, SharedDialogComponent, InputComponent, FormFooterActionsComponent],
})
export class DeviceBrandFormComponent extends AbstractFormDialog<
IDeviceBrandRequest,
@@ -1,4 +1,4 @@
<p-dialog
<shared-dialog
[header]="preparedTitle"
[(visible)]="visible"
[modal]="true"
@@ -11,4 +11,4 @@
<catalog-deviceBrand-select [control]="form.controls.brand_id" />
<app-form-footer-actions [submitLabel]="'ذخیره'" [loading]="submitLoading()" (onCancel)="close()" />
</form>
</p-dialog>
</shared-dialog>
@@ -5,16 +5,16 @@ import { InputComponent } from '@/shared/components';
import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component';
import { Component, inject, Input } from '@angular/core';
import { ReactiveFormsModule, Validators } from '@angular/forms';
import { Dialog } from 'primeng/dialog';
import { IDeviceRequest, IDeviceResponse } from '../models';
import { SuperAdminDeviceService } from '../services/main.service';
import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component';
@Component({
selector: 'superAdmin-device-form',
templateUrl: './form.component.html',
imports: [
ReactiveFormsModule,
Dialog,
SharedDialogComponent,
InputComponent,
FormFooterActionsComponent,
CatalogDeviceBrandSelectComponent,
@@ -1,7 +1,7 @@
<p-dialog header="دسته‌بندی کالاها" [(visible)]="visible" [modal]="true" [style]="{ width: '500px' }" [closable]="true">
<shared-dialog header="دسته‌بندی کالاها" [(visible)]="visible" [modal]="true" [style]="{ width: '500px' }" [closable]="true">
<form [formGroup]="form" (submit)="submit()" class="flex flex-col gap-4">
<app-input label="عنوان" [control]="form.controls.name" name="name" />
<app-form-footer-actions [submitLabel]="'ذخیره'" [loading]="submitLoading()" (onCancel)="close()" />
</form>
</p-dialog>
</shared-dialog>
@@ -3,15 +3,15 @@ import { InputComponent } from '@/shared/components';
import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component';
import { Component, inject, Input } from '@angular/core';
import { ReactiveFormsModule, Validators } from '@angular/forms';
import { Dialog } from 'primeng/dialog';
import { IGoodCategoriesResponse, IGoodCategoryRequest } from '../../models';
import { GuildGoodCategoriesService } from '../../services/goodCategories.service';
import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component';
@Component({
selector: 'admin-guild-good-categories-form',
templateUrl: './form.component.html',
imports: [ReactiveFormsModule, Dialog, InputComponent, FormFooterActionsComponent],
imports: [ReactiveFormsModule, SharedDialogComponent, InputComponent, FormFooterActionsComponent],
})
export class GuildGoodCategoryFormComponent extends AbstractFormDialog<
IGoodCategoryRequest,
@@ -1,8 +1,8 @@
<p-dialog header="فرم صنف" [(visible)]="visible" [modal]="true" [style]="{ width: '500px' }" [closable]="true" ()>
<shared-dialog header="فرم صنف" [(visible)]="visible" [modal]="true" [style]="{ width: '500px' }" [closable]="true" ()>
<form [formGroup]="form" (submit)="submit()" class="flex flex-col gap-4">
<app-input label="عنوان" [control]="form.controls.name" name="name" />
<app-input label="کد" [control]="form.controls.code" name="code" />
<app-form-footer-actions [submitLabel]="'ذخیره'" [loading]="submitLoading()" (onCancel)="close()" />
</form>
</p-dialog>
</shared-dialog>
@@ -3,9 +3,9 @@ import { InputComponent } from '@/shared/components';
import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component';
import { Component, inject, Input } from '@angular/core';
import { ReactiveFormsModule, Validators } from '@angular/forms';
import { Dialog } from 'primeng/dialog';
import { IGuildRequest, IGuildResponse } from '../models';
import { GuildsService } from '../services/main.service';
import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component';
interface T {
name: string;
@@ -15,7 +15,7 @@ interface T {
@Component({
selector: 'admin-guild-form',
templateUrl: './form.component.html',
imports: [ReactiveFormsModule, Dialog, InputComponent, FormFooterActionsComponent],
imports: [ReactiveFormsModule, SharedDialogComponent, InputComponent, FormFooterActionsComponent],
})
export class GuildFormComponent extends AbstractFormDialog<IGuildRequest, IGuildResponse> {
@Input() guildId?: string;
@@ -1,4 +1,10 @@
<p-dialog [header]="preparedTitle" [(visible)]="visible" [modal]="true" [style]="{ width: '500px' }" [closable]="true">
<shared-dialog
[header]="preparedTitle"
[(visible)]="visible"
[modal]="true"
[style]="{ width: '500px' }"
[closable]="true"
>
<form [formGroup]="form" (submit)="submit()" class="flex flex-col gap-4">
<app-shared-upload-file accept="image/*" name="image" (onSelect)="changeFile($event)" />
<app-input label="عنوان" [control]="form.controls.name" name="name" />
@@ -9,10 +15,10 @@
[control]="form.controls.category_id"
name="category_id"
/>
<app-enum-select type="unitType" [control]="form.controls.unit_type" />
<app-enum-select type="goodPricingModel" [control]="form.controls.pricing_model" />
<app-enum-select type="unitType" [control]="form.controls.unit_type" name="unit_type" />
<app-enum-select type="goodPricingModel" [control]="form.controls.pricing_model" name="pricing_model" />
<app-input label="توضیحات" [control]="form.controls.description" name="description" />
<app-form-footer-actions [submitLabel]="'ذخیره'" [loading]="submitLoading()" (onCancel)="close()" />
</form>
</p-dialog>
</shared-dialog>
@@ -3,7 +3,6 @@ import { InputComponent } from '@/shared/components';
import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component';
import { Component, inject, Input, signal } from '@angular/core';
import { ReactiveFormsModule, Validators } from '@angular/forms';
import { Dialog } from 'primeng/dialog';
import { Maybe } from '@/core';
import { EnumSelectComponent } from '@/shared/apiEnum/select.component';
@@ -13,13 +12,14 @@ import { buildFormData } from '@/utils';
import { IGuildGoodRequest, IGuildGoodsResponse } from '../../models';
import { GuildGoodsService } from '../../services/goods.service';
import { GuildCategoriesSelectComponent } from '../categories/select.component';
import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component';
@Component({
selector: 'admin-guild-good-form',
templateUrl: './form.component.html',
imports: [
ReactiveFormsModule,
Dialog,
SharedDialogComponent,
InputComponent,
FormFooterActionsComponent,
EnumSelectComponent,
@@ -1,4 +1,4 @@
<p-dialog
<shared-dialog
header="فرم کاربر"
[(visible)]="visible"
[modal]="true"
@@ -10,4 +10,4 @@
<app-input label="عنوان" [control]="form.controls.name" name="name" />
<app-form-footer-actions [submitLabel]="'ذخیره'" [loading]="form.disabled" (onCancel)="close()" />
</form>
</p-dialog>
</shared-dialog>
@@ -3,14 +3,14 @@ import { InputComponent } from '@/shared/components';
import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component';
import { Component, inject } from '@angular/core';
import { ReactiveFormsModule, Validators } from '@angular/forms';
import { Dialog } from 'primeng/dialog';
import { ILicenseRequest, ILicenseResponse } from '../models';
import { LicensesService } from '../services/main.service';
import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component';
@Component({
selector: 'license-form',
templateUrl: './form.component.html',
imports: [ReactiveFormsModule, Dialog, InputComponent, FormFooterActionsComponent],
imports: [ReactiveFormsModule, SharedDialogComponent, InputComponent, FormFooterActionsComponent],
})
export class LicenseFormComponent extends AbstractFormDialog<ILicenseRequest, ILicenseResponse> {
private service = inject(LicensesService);
@@ -1,4 +1,4 @@
<p-dialog
<shared-dialog
header="فرم کاربر"
[(visible)]="visible"
[modal]="true"
@@ -7,12 +7,12 @@
(onHide)="close()"
>
<form [formGroup]="form" (submit)="submit()" class="flex flex-col gap-4">
<app-input label="نام کاربری" [control]="form.controls.username" name="username" />
<app-enum-select [control]="form.controls.type" name="type" type="accountType" />
<field-username [control]="form.controls.username" />
<app-enum-select [control]="form.controls.role" name="role" type="partnerRole" />
<shared-password-input
[passwordControl]="form.controls.password"
[confirmPasswordControl]="form.controls.confirmPassword"
/>
<app-form-footer-actions [submitLabel]="'ذخیره'" [loading]="submitLoading()" (onCancel)="close()" />
</form>
</p-dialog>
</shared-dialog>
@@ -2,21 +2,22 @@ import { MustMatch, password } from '@/core/validators';
// import { CatalogRolesComponent } from '@/shared/catalog/roles';
import { AbstractFormDialog } from '@/shared/abstractClasses';
import { EnumSelectComponent } from '@/shared/apiEnum/select.component';
import { InputComponent, SharedPasswordInputComponent } from '@/shared/components';
import { SharedPasswordInputComponent, UsernameComponent } from '@/shared/components';
import { fieldControl } from '@/shared/constants/fields';
import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component';
import { Component, inject, Input } from '@angular/core';
import { ReactiveFormsModule, Validators } from '@angular/forms';
import { Dialog } from 'primeng/dialog';
import { IPartnerAccountRequest, IPartnerAccountResponse } from '../../models';
import { AdminPartnerAccountsService } from '../../services/accounts.service';
import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component';
@Component({
selector: 'superAdmin-partner-account-form',
templateUrl: './form.component.html',
imports: [
ReactiveFormsModule,
Dialog,
InputComponent,
SharedDialogComponent,
UsernameComponent,
FormFooterActionsComponent,
SharedPasswordInputComponent,
EnumSelectComponent,
@@ -34,8 +35,8 @@ export class PartnerAccountFormComponent extends AbstractFormDialog<
initForm = () => {
return this.fb.group(
{
username: [this.initialValues?.username || '', [Validators.required]],
type: ['', [Validators.required]],
username: fieldControl.username(this.initialValues?.account?.username || ''),
role: [this.initialValues?.role || '', [Validators.required]],
password: ['', [Validators.required, password()]],
confirmPassword: ['', [Validators.required]],
},
@@ -1,4 +1,4 @@
<p-dialog
<shared-dialog
header="شارژ لایسنس"
[(visible)]="visible"
[modal]="true"
@@ -16,4 +16,4 @@
/>
<app-form-footer-actions [submitLabel]="'ذخیره'" [loading]="submitLoading()" (onCancel)="close()" />
</form>
</p-dialog>
</shared-dialog>
@@ -5,15 +5,15 @@ import { UikitFlatpickrJalaliComponent } from '@/uikit';
import { nowJalali } from '@/utils';
import { Component, inject, Input } from '@angular/core';
import { ReactiveFormsModule, Validators } from '@angular/forms';
import { Dialog } from 'primeng/dialog';
import { IPartnerChargeLicenseTransactionRequest } from '../models/chargeLicenseTransactions_io';
import { AdminPartnerChargeLicenseTransactionsService } from '../services/chargeLicenseTransactions.service';
import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component';
@Component({
selector: 'partner-charge-license-form-dialog',
templateUrl: './charge-license-form-dialog.component.html',
imports: [
Dialog,
SharedDialogComponent,
ReactiveFormsModule,
InputComponent,
FormFooterActionsComponent,
@@ -1,4 +1,4 @@
<p-dialog
<shared-dialog
header="شارژ کاربر"
[(visible)]="visible"
[modal]="true"
@@ -16,4 +16,4 @@
/>
<app-form-footer-actions [submitLabel]="'ذخیره'" [loading]="submitLoading()" (onCancel)="close()" />
</form>
</p-dialog>
</shared-dialog>
@@ -5,15 +5,15 @@ import { UikitFlatpickrJalaliComponent } from '@/uikit';
import { nowJalali } from '@/utils';
import { Component, inject, Input } from '@angular/core';
import { ReactiveFormsModule, Validators } from '@angular/forms';
import { Dialog } from 'primeng/dialog';
import { IAdminPartnerChargeAccountRequest } from '../../models/chargeAccount_io';
import { AdminPartnerChargeAccountService } from '../../services/chargeAccount.service';
import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component';
@Component({
selector: 'admin-partner-charge-account-form-dialog',
templateUrl: './charge-account-form-dialog.component.html',
imports: [
Dialog,
SharedDialogComponent,
ReactiveFormsModule,
InputComponent,
FormFooterActionsComponent,
@@ -1,4 +1,4 @@
<p-dialog
<shared-dialog
[header]="preparedTitle()"
[(visible)]="visible"
[modal]="true"
@@ -21,4 +21,4 @@
<app-form-footer-actions [submitLabel]="'ذخیره'" [loading]="submitLoading()" (onCancel)="close()" />
</form>
</p-dialog>
</shared-dialog>
@@ -4,17 +4,17 @@ import { InputComponent, SharedPasswordInputComponent } from '@/shared/component
import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component';
import { Component, computed, inject, Input } from '@angular/core';
import { ReactiveFormsModule, Validators } from '@angular/forms';
import { Dialog } from 'primeng/dialog';
import { Divider } from 'primeng/divider';
import { IPartnerRequest, IPartnerResponse } from '../models';
import { PartnersService } from '../services/main.service';
import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component';
@Component({
selector: 'partner-form',
templateUrl: './form.component.html',
imports: [
ReactiveFormsModule,
Dialog,
SharedDialogComponent,
InputComponent,
FormFooterActionsComponent,
Divider,
@@ -1,13 +1,23 @@
import { TAccountType } from '@/core/constants/accountTypes.const';
export interface IPartnerAccountRawResponse {
username: string;
id: string;
role: string;
created_at: string;
account: AccountInfo;
}
export interface IPartnerAccountResponse extends IPartnerAccountRawResponse {}
export interface IPartnerAccountRequest {
username: string;
password?: string;
type: TAccountType;
role?: string;
status?: string;
// Keep type optional for current form compatibility.
type?: TAccountType;
}
interface AccountInfo {
username: string;
status: string;
}
@@ -4,7 +4,7 @@ export interface IAdminPartnerChargeAccountRawResponse {
tracking_code: string;
activation_expires_at: string;
charged_license_count: number;
activated_license_count: number;
activation_count: number;
remained_license_count: number;
}
@@ -4,7 +4,7 @@ export interface IPartnerChargeLicenseTransactionRawResponse {
tracking_code: string;
activation_expires_at: string;
charged_license_count: number;
activated_license_count: number;
activation_count: number;
remained_license_count: number;
}
export interface IPartnerChargeLicenseTransactionResponse extends IPartnerChargeLicenseTransactionRawResponse {}
@@ -17,8 +17,8 @@ export class AdminPartnerChargeLicenseTransactionsService {
getAll(
partnerId: string,
): Observable<IPaginatedResponse<IPartnerChargeLicenseTransactionRawResponse>> {
return this.http.get<IPaginatedResponse<IPartnerChargeLicenseTransactionResponse>>(
): Observable<IPaginatedResponse<IPartnerChargeLicenseTransactionResponse>> {
return this.http.get<IPaginatedResponse<IPartnerChargeLicenseTransactionRawResponse>>(
this.apiRoutes.list(partnerId),
);
}
@@ -26,8 +26,8 @@ export class AdminPartnerChargeLicenseTransactionsService {
charge(
partnerId: string,
data: IPartnerChargeLicenseTransactionRequest,
): Observable<IPartnerChargeLicenseTransactionRawResponse> {
return this.http.post<IPartnerChargeLicenseTransactionResponse>(
): Observable<IPartnerChargeLicenseTransactionResponse> {
return this.http.post<IPartnerChargeLicenseTransactionRawResponse>(
this.apiRoutes.list(partnerId),
data,
);
@@ -1,4 +1,4 @@
<p-dialog
<shared-dialog
[header]="preparedTitle()"
[(visible)]="visible"
[modal]="true"
@@ -22,4 +22,4 @@
<app-form-footer-actions [submitLabel]="'ذخیره'" [loading]="submitLoading()" (onCancel)="close()" />
</form>
</p-dialog>
</shared-dialog>
@@ -4,17 +4,17 @@ import { InputComponent, SharedPasswordInputComponent } from '@/shared/component
import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component';
import { Component, computed, inject, Input } from '@angular/core';
import { ReactiveFormsModule, Validators } from '@angular/forms';
import { Dialog } from 'primeng/dialog';
import { Divider } from 'primeng/divider';
import { IProviderRequest, IProviderResponse } from '../models';
import { ProvidersService } from '../services/main.service';
import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component';
@Component({
selector: 'provider-form',
templateUrl: './form.component.html',
imports: [
ReactiveFormsModule,
Dialog,
SharedDialogComponent,
InputComponent,
FormFooterActionsComponent,
Divider,
@@ -1,4 +1,4 @@
<p-dialog
<shared-dialog
header="فرم کاربر"
[(visible)]="visible"
[modal]="true"
@@ -7,7 +7,7 @@
(onHide)="close()"
>
<form [formGroup]="form" (submit)="submit()" class="flex flex-col gap-4">
<app-input label="نام کاربری" [control]="form.controls.username" name="username" />
<field-username [control]="form.controls.username" />
<app-enum-select [control]="form.controls.type" name="type" type="accountType" />
<shared-password-input
[passwordControl]="form.controls.password"
@@ -15,4 +15,4 @@
/>
<app-form-footer-actions [submitLabel]="'ذخیره'" [loading]="submitLoading()" (onCancel)="close()" />
</form>
</p-dialog>
</shared-dialog>
@@ -2,11 +2,12 @@ import { MustMatch, password } from '@/core/validators';
// import { CatalogRolesComponent } from '@/shared/catalog/roles';
import { AbstractFormDialog } from '@/shared/abstractClasses';
import { EnumSelectComponent } from '@/shared/apiEnum/select.component';
import { InputComponent, SharedPasswordInputComponent } from '@/shared/components';
import { SharedPasswordInputComponent, UsernameComponent } from '@/shared/components';
import { fieldControl } from '@/shared/constants/fields';
import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component';
import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component';
import { Component, inject, Input } from '@angular/core';
import { ReactiveFormsModule, Validators } from '@angular/forms';
import { Dialog } from 'primeng/dialog';
import { IAccountRequest, IAccountResponse } from '../../models';
import { AdminUserAccountsService } from '../../services/accounts.service';
@@ -15,8 +16,8 @@ import { AdminUserAccountsService } from '../../services/accounts.service';
templateUrl: './form.component.html',
imports: [
ReactiveFormsModule,
Dialog,
InputComponent,
SharedDialogComponent,
UsernameComponent,
FormFooterActionsComponent,
EnumSelectComponent,
SharedPasswordInputComponent,
@@ -35,9 +36,8 @@ export class UserAccountFormComponent extends AbstractFormDialog<
if (this.editMode) {
return this.fb.group(
{
username: [this.initialValues?.username || '', [Validators.required]],
// @ts-ignore
type: [this.initialValues?.type, [Validators.required]],
username: fieldControl.username(this.initialValues?.username || ''),
type: [this.initialValues?.type || '', [Validators.required]],
password: ['', [password()]],
confirmPassword: [''],
@@ -49,9 +49,9 @@ export class UserAccountFormComponent extends AbstractFormDialog<
}
return this.fb.group(
{
username: [this.initialValues?.username || '', [Validators.required]],
username: fieldControl.username(this.initialValues?.username || ''),
// @ts-ignore
type: [this.initialValues?.type, [Validators.required]],
type: [this.initialValues?.type || '', [Validators.required]],
password: ['', [Validators.required, password()]],
confirmPassword: ['', [Validators.required]],
@@ -1,4 +1,4 @@
<p-dialog
<shared-dialog
header="فرم کاربر"
[(visible)]="visible"
[modal]="true"
@@ -13,4 +13,4 @@
<app-form-footer-actions [submitLabel]="'ذخیره'" [loading]="submitLoading()" (onCancel)="close()" />
</form>
</p-dialog>
</shared-dialog>
@@ -5,14 +5,14 @@ import { InputComponent } from '@/shared/components';
import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component';
import { Component, inject, Input } from '@angular/core';
import { ReactiveFormsModule, Validators } from '@angular/forms';
import { Dialog } from 'primeng/dialog';
import { IUserRequest, IUserResponse } from '../models';
import { UsersService } from '../services/main.service';
import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component';
@Component({
selector: 'superAdmin-user-form',
templateUrl: './form.component.html',
imports: [ReactiveFormsModule, Dialog, InputComponent, FormFooterActionsComponent],
imports: [ReactiveFormsModule, SharedDialogComponent, InputComponent, FormFooterActionsComponent],
})
export class UserAccountFormComponent extends AbstractFormDialog<IUserRequest, IUserResponse> {
private readonly service = inject(UsersService);
@@ -1,13 +1,17 @@
import { TAccountType } from '@/core/constants/accountTypes.const';
export interface IAccountRawResponse {
username: string;
id: string;
username?: string;
status?: string;
type?: string;
created_at?: string;
}
export interface IAccountResponse extends IAccountRawResponse {}
export interface IAccountRequest {
username: string;
password?: string;
type: TAccountType;
type?: TAccountType;
status?: string;
}