feat: implement change password functionality with dialog and service integration

This commit is contained in:
2026-06-07 13:56:36 +03:30
parent cd09b09e3b
commit 2f67801700
9 changed files with 89 additions and 60 deletions
@@ -0,0 +1 @@
<shared-change-password-form-dialog [(visible)]="visible" [loading]="submitLoading()" (onSubmit)="submit($event)" />
@@ -0,0 +1,34 @@
import { ToastService } from '@/core/services/toast.service';
import { AbstractDialog } from '@/shared/abstractClasses/abstract-dialog';
import { ChangePasswordFormDialogComponent } from '@/shared/components';
import { Component, inject, signal } from '@angular/core';
import { finalize } from 'rxjs';
import { IChangePasswordSubmitPayload } from '../modules/configs/components/changePassword/model';
import { PosChangePasswordService } from '../services/password';
@Component({
selector: 'pos-change-password',
templateUrl: 'change-password.component.html',
imports: [ChangePasswordFormDialogComponent],
})
export class PosChangePasswordComponent extends AbstractDialog {
private readonly service = inject(PosChangePasswordService);
private readonly toastService = inject(ToastService);
submitLoading = signal(false);
submit(payload: IChangePasswordSubmitPayload) {
this.submitLoading.set(true);
this.service
.changePassword(payload.password)
.pipe(finalize(() => this.submitLoading.set(false)))
.subscribe(() => {
this.toastService.success({
text: 'تغییر گذرواژه با موفقیت انجام شد.',
});
this.submitLoading.set(false);
this.close();
});
}
}
@@ -25,52 +25,27 @@
@if (loading()) {
<shared-page-loading />
} @else {
<!-- <div class="w-svw h-svh bg-surface-ground flex flex-col gap-4 p-4"> -->
<!-- <div class="w-full flex items-center gap-4 shrink-0 justify-between">
<div class="flex gap-2 items-center">
@if (posInfo()) {
<div class="w-10 h-10">
<img [src]="placeholderLogo" alt="Logo" class="w-full h-full object-cover rounded-md bg-surface-card" />
</div>
<span class="text-lg font-bold">
{{ posInfo()?.name }} ({{ posInfo()?.complex!.name }} - {{ posInfo()?.businessActivity!.name }})
</span>
}
</div>
<div class="flex gap-2 items-center">
<div class="bg-surface-card px-3 rounded-md shadow-sm h-9 flex items-center">
<span [jalaliDate]="now" jalaliFormat="dddd YYYY/MM/DD" class="text-base"></span>
</div>
<div class="">
<p-menu #menu [model]="profileMenuItems" [popup]="true" />
<button pButton (click)="menu.toggle($event)" icon="pi pi-user" severity="contrast">
{{ posProfile()?.account?.username }}
</button>
</div>
</div>
</div> -->
@if (error()) {
@switch (error()?.status) {
@case (412) {
<pos-choose-cards class="h-full" (onChoose)="onChoosePos()" />
}
@default {
<div class="flex h-full w-full items-center justify-center">
<p-card class="border-surface-border border">
<div class="flex shrink-0 flex-col items-center justify-between gap-2">
<i class="pi pi-exclamation-triangle text-error mb-3 text-6xl!" aria-hidden="true"></i>
<span class="text-error mb-2 block text-xl font-semibold"> عدم دسترسی </span>
<p class="inline-block text-base">متاسفانه امکان دسترسی برای کاربر شما فراهم نیست</p>
<button pButton outlined severity="danger" class="mt-5 w-32" (click)="logout()">خروج</button>
</div>
</p-card>
</div>
}
} @else if (error()) {
@switch (error()?.status) {
@case (412) {
<pos-choose-cards class="h-full" (onChoose)="onChoosePos()" />
}
@default {
<div class="flex h-full w-full items-center justify-center">
<p-card class="border-surface-border border">
<div class="flex shrink-0 flex-col items-center justify-between gap-2">
<i class="pi pi-exclamation-triangle text-error mb-3 text-6xl!" aria-hidden="true"></i>
<span class="text-error mb-2 block text-xl font-semibold"> عدم دسترسی </span>
<p class="inline-block text-base">متاسفانه امکان دسترسی برای کاربر شما فراهم نیست</p>
<button pButton outlined severity="danger" class="mt-5 w-32" (click)="logout()">خروج</button>
</div>
</p-card>
</div>
}
} @else {
<pos-main-menu-sidebar [(visible)]="mainMenuVisible" />
<router-outlet></router-outlet>
}
<!-- </div> -->
} @else {
<pos-main-menu-sidebar [(visible)]="mainMenuVisible" />
<pos-change-password [(visible)]="changePasswordVisible" />
<router-outlet></router-outlet>
}
<!-- </div> -->
@@ -11,6 +11,7 @@ import { Menu } from 'primeng/menu';
import { finalize } from 'rxjs';
import images from 'src/assets/images';
import config from 'src/config';
import { PosChangePasswordComponent } from '../../components/change-password.component';
import { PosInfoStore, PosProfileStore } from '../../store';
import { DeviceInfoStore } from '../../store/device.store';
import { PosMainMenuSidebarComponent } from '../mainMenuSidebar/main-menu-sidebar.component';
@@ -30,6 +31,7 @@ import { PosChooseCardsComponent } from './choose-pos.component';
CommonModule,
RouterLinkWithHref,
RouterOutlet,
PosChangePasswordComponent,
],
})
export class PosPagesLayoutComponent {
@@ -49,6 +51,7 @@ export class PosPagesLayoutComponent {
private readonly layoutService = inject(LayoutService);
mainMenuVisible = signal(false);
changePasswordVisible = signal(false);
readonly posProfileLoading = computed(() => this.posProfileStore.loading());
readonly posProfile = computed(() => this.posProfileStore.entity());
@@ -67,12 +70,21 @@ export class PosPagesLayoutComponent {
this.authService.logout();
};
showChangePasswordDialog = () => {
this.changePasswordVisible.set(true);
};
profileMenuItems: MenuItem[] = [
{
label: 'راهنمای سامانه',
icon: 'pi pi-question-circle',
disabled: true,
},
{
label: 'تغییر گذرواژه',
icon: 'pi pi-key',
command: this.showChangePasswordDialog,
},
{
label: 'خروج',
icon: 'pi pi-sign-out',
@@ -97,7 +109,7 @@ export class PosPagesLayoutComponent {
.pipe(
finalize(() => {
this.layoutService.changeFullPageLoading(false);
}),
})
)
.subscribe();
},
@@ -10,7 +10,6 @@
<pos-config-send-to-fiscal-activation-form class="w-full" />
</div>
</app-card-data>
<pos-change-password-form class="w-full" />
<app-card-data cardTitle="تنظیمات پرینت صورت‌حساب" class="w-full">
<p-message variant="text" severity="info" icon="pi pi-info-circle">
هریک از موارد زیر را که می‌خواهید در چاپ صورت‌حساب‌ نمایش داده‌ شوند را انتخاب کنید
@@ -3,7 +3,6 @@ import { AppCardComponent } from '@/shared/components';
import { Component, computed, inject } from '@angular/core';
import { Router } from '@angular/router';
import { Message } from 'primeng/message';
import { PosChangePasswordFormDialogComponent } from '../components/changePassword/form.component';
import { PosConfigGoldPriceFormComponent } from '../components/goldPrice/form.component';
import { PosConfigPrintFormComponent } from '../components/print/form.component';
import { PosConfigRapidInvoiceFormComponent } from '../components/rapidInvoice/form.component';
@@ -19,7 +18,6 @@ import { PosConfigSendToFiscalActivationFormComponent } from '../components/send
PosConfigGoldPriceFormComponent,
PosConfigRapidInvoiceFormComponent,
PosConfigSendToFiscalActivationFormComponent,
PosChangePasswordFormDialogComponent,
],
})
export class PosConfigPageComponent {
+14
View File
@@ -0,0 +1,14 @@
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root',
})
export class PosChangePasswordService {
constructor(private readonly http: HttpClient) {}
changePassword(password: string): Observable<unknown> {
return this.http.put('/api/v1/pos/update-password', { password });
}
}