feat: enhance POS module with dynamic routing, improved state management, and new search functionality

This commit is contained in:
2025-12-26 16:47:47 +03:30
parent abfb2f3479
commit c6efda319c
20 changed files with 264 additions and 109 deletions
+31 -6
View File
@@ -1,11 +1,15 @@
import { Maybe } from '@/core';
import { ICustomerResponse } from '@/modules/customers/models';
import { computed, Injectable, signal } from '@angular/core';
import { computed, Inject, Injectable, InjectionToken, signal } from '@angular/core';
import { map } from 'rxjs';
import { IPosInfoResponse, IPosProductCategoriesResponse, IPosStockResponse } from '../models';
import { IPosInOrderProduct } from '../models/types';
import { PosService } from '../services/main.service';
export const POS_ID = new InjectionToken<number>('POS_ID');
export type TViewType = 'list' | 'grid';
interface IPosState {
getStockLoading: boolean;
stock: Maybe<IPosStockResponse[]>;
@@ -16,6 +20,8 @@ interface IPosState {
activeProductCategory: Maybe<number>;
inOrderProducts: IPosInOrderProduct[];
selectedCustomer: Maybe<ICustomerResponse>;
viewType: TViewType;
searchQuery: string;
}
export const INITIAL_POS_STATE: IPosState = {
@@ -28,11 +34,19 @@ export const INITIAL_POS_STATE: IPosState = {
activeProductCategory: null,
inOrderProducts: [],
selectedCustomer: null,
viewType: 'grid',
searchQuery: '',
};
@Injectable({ providedIn: 'any' })
export class POSStore {
constructor(private service: PosService) {}
constructor(
@Inject(POS_ID) posId: number,
private service: PosService,
) {
this.posId = posId;
this.initial();
}
private state$ = signal<IPosState>({ ...INITIAL_POS_STATE });
@@ -45,6 +59,8 @@ export class POSStore {
readonly getProductCategoriesLoading = computed(() => this.state$().getProductCategoriesLoading);
readonly activeProductCategory = computed(() => this.state$().activeProductCategory);
readonly selectedCustomer = computed(() => this.state$().selectedCustomer);
readonly viewType = computed(() => this.state$().viewType);
readonly searchQuery = computed(() => this.state$().searchQuery);
readonly activatedCategoryProducts = computed(() => {
if (this.activeProductCategory() === 0) {
return this.state$().stock;
@@ -72,6 +88,8 @@ export class POSStore {
};
});
posId!: number;
setState(partial: Partial<IPosState>) {
this.state$.set({ ...this.state$(), ...partial });
}
@@ -92,7 +110,7 @@ export class POSStore {
getInfo() {
this.setState({ getInfoLoading: true });
this.service.getInfo().subscribe({
this.service.getInfo(this.posId).subscribe({
next: (res) => {
this.setState({ info: res, getInfoLoading: false });
},
@@ -104,7 +122,7 @@ export class POSStore {
getStock() {
this.setState({ getStockLoading: true });
this.service.getStock().subscribe({
this.service.getStock(this.posId, this.state$().searchQuery).subscribe({
next: (res) => {
this.setState({ stock: res.data, getStockLoading: false });
},
@@ -117,7 +135,7 @@ export class POSStore {
getProductCategories() {
this.setState({ getProductCategoriesLoading: true });
this.service
.getCategories()
.getCategories(this.posId)
.pipe(
map((res) => {
return {
@@ -216,6 +234,13 @@ export class POSStore {
}
}
updateViewType(viewType: TViewType) {
this.setState({ viewType });
}
updateSearchQuery(searchQuery: string) {
this.setState({ searchQuery });
}
resetInOrderProducts() {
this.setState({ inOrderProducts: [] });
}
@@ -233,6 +258,6 @@ export class POSStore {
fee: item.fee,
})),
};
this.service.submitOrder(orderPayload).subscribe();
this.service.submitOrder(this.posId, orderPayload).subscribe();
}
}