diff --git a/src/app/core/interceptors/error.interceptor.ts b/src/app/core/interceptors/error.interceptor.ts index 094b6b6..876086f 100644 --- a/src/app/core/interceptors/error.interceptor.ts +++ b/src/app/core/interceptors/error.interceptor.ts @@ -18,6 +18,9 @@ export const errorInterceptor: HttpInterceptorFn = (req, next) => { return next(req).pipe( catchError((error: HttpErrorResponse) => { + console.log('error'); + console.log(error); + let errorMessage = 'خطای نامشخص رخ داده است'; if (error.error instanceof ErrorEvent) { @@ -130,9 +133,13 @@ export enum ErrorType { * Helper function to determine error type */ export function getErrorType(error: HttpErrorResponse): ErrorType { + console.log('getErrorType'); + console.log(error); + if (error.error instanceof ErrorEvent) { return ErrorType.NETWORK; } + console.log(error.status); switch (error.status) { case 400: diff --git a/src/app/core/services/error-handler.service.ts b/src/app/core/services/error-handler.service.ts index 7390085..cd6ce9d 100644 --- a/src/app/core/services/error-handler.service.ts +++ b/src/app/core/services/error-handler.service.ts @@ -140,19 +140,23 @@ export class ErrorHandlerService { * Extract user-friendly message from error */ private getUserMessage(error: HttpErrorResponse): string { - if (error.error && typeof error.error === 'object') { - // Try different common message fields - return ( - error.error.message || - error.error.error || - error.error.detail || - error.statusText || - 'خطای نامشخص رخ داده است' - ); - } - - if (typeof error.error === 'string') { - return error.error; + if (error.error) { + if (error.error.errors && Array.isArray(error.error.errors)) { + return error.error.errors[0]; + } + if (typeof error.error === 'object') { + // Try different common message fields + return ( + error.error.message || + error.error.error || + error.error.detail || + error.statusText || + 'خطای نامشخص رخ داده است' + ); + } + if (typeof error.error === 'string') { + return error.error; + } } return error.statusText || 'خطای نامشخص رخ داده است'; diff --git a/src/app/domains/superAdmin/modules/partners/components/charge-license-form-dialog.component.html b/src/app/domains/superAdmin/modules/partners/components/charge-license-form-dialog.component.html new file mode 100644 index 0000000..3540cd0 --- /dev/null +++ b/src/app/domains/superAdmin/modules/partners/components/charge-license-form-dialog.component.html @@ -0,0 +1,13 @@ + +
+ + + +
diff --git a/src/app/domains/superAdmin/modules/partners/components/charge-license-form-dialog.component.ts b/src/app/domains/superAdmin/modules/partners/components/charge-license-form-dialog.component.ts new file mode 100644 index 0000000..0761ab8 --- /dev/null +++ b/src/app/domains/superAdmin/modules/partners/components/charge-license-form-dialog.component.ts @@ -0,0 +1,30 @@ +import { AbstractFormDialog } from '@/shared/abstractClasses'; +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 { ILicenseChargeRequest, ILicenseChargeResponse } from '../models'; +import { PartnersService } from '../services/main.service'; + +@Component({ + selector: 'partner-charge-license-form-dialog', + templateUrl: './charge-license-form-dialog.component.html', + imports: [Dialog, ReactiveFormsModule, InputComponent, FormFooterActionsComponent], +}) +export class PartnerChargeLicenseFormDialogComponent extends AbstractFormDialog< + ILicenseChargeRequest, + ILicenseChargeResponse +> { + @Input({ required: true }) partnerId!: string; + + private readonly service = inject(PartnersService); + + form = this.fb.group({ + count: [0, [Validators.min(0)]], + }); + + submitForm(payload: ILicenseChargeRequest) { + return this.service.licenseCharge(this.partnerId, payload); + } +} diff --git a/src/app/domains/superAdmin/modules/partners/constants/apiRoutes/index.ts b/src/app/domains/superAdmin/modules/partners/constants/apiRoutes/index.ts index 8deaa22..fb27d84 100644 --- a/src/app/domains/superAdmin/modules/partners/constants/apiRoutes/index.ts +++ b/src/app/domains/superAdmin/modules/partners/constants/apiRoutes/index.ts @@ -5,4 +5,5 @@ const baseUrl = '/api/v1/admin/partners'; export const PARTNERS_API_ROUTES = { list: () => `${baseUrl}`, single: (id: string) => `${baseUrl}/${id}`, + licenseCharge: (id: string) => `${baseUrl}/${id}/charge-license`, }; diff --git a/src/app/domains/superAdmin/modules/partners/models/io.d.ts b/src/app/domains/superAdmin/modules/partners/models/io.d.ts index 91b42f6..0644b73 100644 --- a/src/app/domains/superAdmin/modules/partners/models/io.d.ts +++ b/src/app/domains/superAdmin/modules/partners/models/io.d.ts @@ -12,3 +12,11 @@ export interface IPartnerRequest { code: string; license_quota: number; } + +//charge license +export interface ILicenseChargeRawResponse {} +export interface ILicenseChargeResponse extends ILicenseChargeRawResponse {} + +export interface ILicenseChargeRequest { + count: number; +} diff --git a/src/app/domains/superAdmin/modules/partners/services/main.service.ts b/src/app/domains/superAdmin/modules/partners/services/main.service.ts index 7bb6b70..6f84a77 100644 --- a/src/app/domains/superAdmin/modules/partners/services/main.service.ts +++ b/src/app/domains/superAdmin/modules/partners/services/main.service.ts @@ -3,7 +3,14 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; import { PARTNERS_API_ROUTES } from '../constants'; -import { IPartnerRawResponse, IPartnerRequest, IPartnerResponse } from '../models'; +import { + ILicenseChargeRawResponse, + ILicenseChargeRequest, + ILicenseChargeResponse, + IPartnerRawResponse, + IPartnerRequest, + IPartnerResponse, +} from '../models'; @Injectable({ providedIn: 'root' }) export class PartnersService { @@ -14,15 +21,22 @@ export class PartnersService { getAll(): Observable> { return this.http.get>(this.apiRoutes.list()); } - getSingle(userId: string): Observable { - return this.http.get(this.apiRoutes.single(userId)); + getSingle(partnerId: string): Observable { + return this.http.get(this.apiRoutes.single(partnerId)); } create(userData: IPartnerRequest): Observable { return this.http.post(this.apiRoutes.list(), userData); } - update(userId: string, userData: IPartnerRequest): Observable { - return this.http.patch(this.apiRoutes.single(userId), userData); + update(partnerId: string, userData: IPartnerRequest): Observable { + return this.http.patch(this.apiRoutes.single(partnerId), userData); + } + + licenseCharge( + partnerId: string, + data: ILicenseChargeRequest, + ): Observable { + return this.http.post(this.apiRoutes.licenseCharge(partnerId), data); } } diff --git a/src/app/domains/superAdmin/modules/partners/views/single.component.html b/src/app/domains/superAdmin/modules/partners/views/single.component.html index c9601ff..0d64215 100644 --- a/src/app/domains/superAdmin/modules/partners/views/single.component.html +++ b/src/app/domains/superAdmin/modules/partners/views/single.component.html @@ -1,6 +1,9 @@
- + + شارژ لایسنس‌ + {{ visibleChargeFormDialog() }} +
@@ -20,4 +23,10 @@ [initialValues]="partner() || undefined" (onSubmit)="getData()" /> + +
diff --git a/src/app/domains/superAdmin/modules/partners/views/single.component.ts b/src/app/domains/superAdmin/modules/partners/views/single.component.ts index 514f2ed..773a077 100644 --- a/src/app/domains/superAdmin/modules/partners/views/single.component.ts +++ b/src/app/domains/superAdmin/modules/partners/views/single.component.ts @@ -2,7 +2,9 @@ import { BreadcrumbService } from '@/core/services'; import { AppCardComponent, KeyValueComponent } from '@/shared/components'; 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 { PartnerChargeLicenseFormDialogComponent } from '../components/charge-license-form-dialog.component'; import { GuildFormComponent } from '../components/form.component'; import { superAdminPartnersNamedRoutes } from '../constants'; import { PartnerStore } from '../store/partner.store'; @@ -10,7 +12,14 @@ import { PartnerStore } from '../store/partner.store'; @Component({ selector: 'app-user', templateUrl: './single.component.html', - imports: [AppCardComponent, KeyValueComponent, GuildFormComponent, ConsumerAccountListComponent], + imports: [ + AppCardComponent, + KeyValueComponent, + GuildFormComponent, + ConsumerAccountListComponent, + Button, + PartnerChargeLicenseFormDialogComponent, + ], }) export class PartnerComponent { private readonly store = inject(PartnerStore); @@ -22,6 +31,7 @@ export class PartnerComponent { readonly loading = computed(() => this.store.loading()); readonly partner = computed(() => this.store.entity()); + visibleChargeFormDialog = signal(false); constructor() { effect(() => { @@ -46,4 +56,8 @@ export class PartnerComponent { }, ]); } + + openChargeDialog() { + this.visibleChargeFormDialog.set(true); + } } diff --git a/src/app/shared/components/input/input.component.html b/src/app/shared/components/input/input.component.html index 5e62b87..66d3736 100644 --- a/src/app/shared/components/input/input.component.html +++ b/src/app/shared/components/input/input.component.html @@ -31,8 +31,13 @@ [attr.maxlength]="preparedMaxLength || null" [attr.type]="htmlType" [attr.autocomplete]="autocomplete" - [class]=" - `${inputClass} w-full ${size === 'large' ? 'p-inputtext-lg' : size === 'small' ? 'p-inputtext-sm' : ''}` + [classList]=" + [ + inputClass, + 'w-full', + `${size === 'large' ? 'p-inputtext-lg' : size === 'small' ? 'p-inputtext-sm' : ''}`, + suffixTemp || preparedSuffix() ? 'hasSuffix' : '', + ].join(' ') " [required]="isRequired" [invalid]="control.invalid && (control.touched || control.dirty)" diff --git a/src/app/shared/components/input/input.component.ts b/src/app/shared/components/input/input.component.ts index f553fca..ce48179 100644 --- a/src/app/shared/components/input/input.component.ts +++ b/src/app/shared/components/input/input.component.ts @@ -224,9 +224,9 @@ export class InputComponent { // @ts-ignore $event.target.value = newValue; } - - this.control.setValue(newValue); } + if (!['nationalId', 'phone', 'postalCode', 'mobile'].includes(this.type)) + this.control.setValue(newValue); } if (this.preparedMaxLength && this.preparedMaxLength < value.length) {