feat: implement stock keeping unit management form and list components

- Added StockKeepingUnitFormComponent for creating and editing stock keeping units.
- Introduced StockKeepingUnitsComponent for listing stock keeping units with pagination.
- Integrated form fields for code, name, VAT, and SKU type in the stock keeping unit form.
- Created API routes for stock keeping units with CRUD operations.
- Updated input components to handle numeric and price types with Persian/Arabic digit normalization.
- Enhanced key-value component to support tag display instead of badge.
- Adjusted layout styles for sidebar menu.
- Added AGENT.md for repository-specific coding guidelines and practices.
- Implemented good management form with file upload and category selection.
This commit is contained in:
2026-05-06 22:01:20 +03:30
parent 54d00e19ae
commit b2a1eb8e5b
87 changed files with 882 additions and 434 deletions
@@ -2,12 +2,13 @@ import { formatDurationToText, formatJalali, JALALI_DATE_FORMATS } from '@/utils
import priceMaskUtils from '@/utils/price-mask.utils';
import { CommonModule } from '@angular/common';
import { Component, computed, Input, signal } from '@angular/core';
import { Badge } from 'primeng/badge';
import { Tag } from 'primeng/tag';
import { TDataType } from '../pageDataList/page-data-list.component';
@Component({
selector: 'app-key-value',
standalone: true,
imports: [CommonModule, Badge],
imports: [CommonModule, Tag],
templateUrl: './key-value.component.html',
host: {
class: 'w-full block',
@@ -18,24 +19,12 @@ export class KeyValueComponent {
@Input() value?: string | boolean | number;
@Input() hint?: string;
@Input() alignment?: 'start' | 'center' | 'end' = 'start';
@Input() type:
| 'price'
| 'active'
| 'boolean'
| 'has'
| 'date'
| 'dateTime'
| 'duration'
| 'id'
| 'thumbnail'
| 'nested'
| 'index'
| 'number'
| 'simple' = 'simple';
@Input() type: TDataType = 'simple';
@Input() trueValueToShow?: string;
@Input() falseValueToShow?: string;
@Input() variant?: 'badge' | 'text';
@Input() variant?: 'tag' | 'text';
tagSeverity = computed(() => (this.value ? 'success' : 'danger'));
valueToShow = signal(this.setValueToShow());
@@ -105,6 +94,6 @@ export class KeyValueComponent {
}
valueType = computed(() =>
this.variant || ['boolean', 'has', 'active'].includes(this.type) ? 'badge' : 'text',
this.variant || ['boolean', 'has', 'active'].includes(this.type) ? 'tag' : 'text',
);
}