@isaiahiroko/tilmart-ngx-apps-admin 0.2.2 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-bulk-upload.module-BGTbsYUP.mjs +370 -0
- package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-bulk-upload.module-BGTbsYUP.mjs.map +1 -0
- package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-catalog.module-BwjfFXDU.mjs +562 -0
- package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-catalog.module-BwjfFXDU.mjs.map +1 -0
- package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-orders.module-Cfeb0QjH.mjs → isaiahiroko-tilmart-ngx-apps-admin-orders.module-vldWwcAr.mjs} +26 -3
- package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-orders.module-vldWwcAr.mjs.map +1 -0
- package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-settings.module-Cz6xPNwB.mjs → isaiahiroko-tilmart-ngx-apps-admin-settings.module-CFVgAQ2f.mjs} +48 -4
- package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-settings.module-CFVgAQ2f.mjs.map +1 -0
- package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin.mjs +14 -6
- package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin.mjs.map +1 -1
- package/package.json +1 -1
- package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-catalog.module-DoxDNaNn.mjs +0 -538
- package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-catalog.module-DoxDNaNn.mjs.map +0 -1
- package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-orders.module-Cfeb0QjH.mjs.map +0 -1
- package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-settings.module-Cz6xPNwB.mjs.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"isaiahiroko-tilmart-ngx-apps-admin-catalog.module-DoxDNaNn.mjs","sources":["../../../projects/admin/src/lib/pages/catalog/catalog.component.ts","../../../projects/admin/src/lib/pages/catalog/catalog.component.html","../../../projects/admin/src/lib/pages/catalog/catalog.module.ts"],"sourcesContent":["import { Component, inject } from '@angular/core';\nimport { HttpClient } from '@angular/common/http';\nimport { BaseDirective, getEnv, notify, using } from '@thescaffold/ngx-core';\nimport { firstValueFrom, takeUntil } from 'rxjs';\n\n// `ProductMedia.blobId` (P1.3) resolves to `GET {API_BASE_URL}/apps/blobs/\n// download/:id` — same helper/reasoning as the buyer app's\n// `lib/data/media.ts#blobUrl` (confirmed against the real\n// `ntx-apps/libs/blobs` controller, not guessed).\nfunction resolveBlobUrl(blobId?: string | null): string {\n if (!blobId) return '';\n return `${getEnv('API_BASE_URL')}/apps/blobs/download/${blobId}`;\n}\n\n// `@thescaffold/jsx-blobs`'s own `upload()` helper is broken against this\n// platform's response envelope: its internal `init()`/`verify()` return\n// the raw `{status, title, message, data}` body but `upload()` then reads\n// `file.id` (not `file.data.id`) — so it always reports \"Failed to init\n// file upload\" even on a 201. Confirmed by driving the real upload flow\n// in a browser and reading the network log: `init` returns 201 with a\n// real file id, `upload()` still fails. Rather than depend on a broken\n// vendor convenience function, this reimplements the same three-call\n// contract (init → chunked batch → verify) directly against\n// `apiService`, which is also how P1's demo-media seed script validated\n// the contract in the first place, and gets Angular's existing\n// `JwtInterceptor` auth for free instead of hand-managing SDK config.\nasync function uploadFileToBlobs(\n apiService: { post: (path: string, body?: any) => any },\n file: File,\n parentId: string,\n tags: string[],\n): Promise<string> {\n const ext = file.name.split('.').pop()?.toLowerCase() || '';\n const mime = file.type || 'application/octet-stream';\n const meta = { type: ext, parentId, name: file.name, tags, size: file.size, mime };\n\n const initRes: any = await firstValueFrom(apiService.post('apps/blobs/upload/init', meta));\n const fileId = initRes?.data?.id;\n if (!fileId) throw new Error('Failed to init file upload');\n\n const chunkSize = 512 * 1024;\n const reader = file.stream().getReader();\n let index = 0;\n let buffer = new Uint8Array();\n\n const flushChunk = async (bytes: Uint8Array) => {\n await firstValueFrom(\n apiService.post('apps/blobs/upload/batch', {\n pages: [{ fileId, index: index++, raw: uint8ToBase64(bytes) }],\n }),\n );\n };\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n const combined = new Uint8Array(buffer.length + value.length);\n combined.set(buffer);\n combined.set(value, buffer.length);\n buffer = combined;\n while (buffer.length >= chunkSize) {\n await flushChunk(buffer.slice(0, chunkSize));\n buffer = buffer.slice(chunkSize);\n }\n }\n if (buffer.length > 0) await flushChunk(buffer);\n\n const verifyRes: any = await firstValueFrom(apiService.post('apps/blobs/upload/verify', meta));\n const blobId = verifyRes?.data?.id;\n if (!blobId) throw new Error('Failed to verify file upload');\n return blobId;\n}\n\nfunction uint8ToBase64(bytes: Uint8Array): string {\n let binary = '';\n const chunkSize = 0x8000;\n for (let i = 0; i < bytes.length; i += chunkSize) {\n binary += String.fromCharCode(...bytes.subarray(i, i + chunkSize));\n }\n return btoa(binary);\n}\n\ninterface PublishError {\n field: string;\n message: string;\n}\n\ninterface ProductRowVm {\n id: string;\n name: string;\n model: string;\n type: string;\n status: string;\n updatedAt: string;\n checking: boolean;\n checked: boolean;\n canPublish?: boolean;\n errors?: PublishError[];\n}\n\ninterface CategoryOption {\n id: string;\n name: string;\n slug: string;\n parentId?: string;\n}\n\ninterface BrandOption {\n id: string;\n name: string;\n}\n\ninterface AttributeDefVm {\n id: string;\n key: string;\n label: string;\n unit?: string;\n dataType: string;\n allowedValues?: string[];\n required: boolean;\n group?: string;\n}\n\ninterface AttributeValueVm {\n id?: string;\n valueNumber?: number | null;\n valueNumberHigh?: number | null;\n valueText?: string;\n valueBool?: boolean;\n}\n\ninterface MediaVm {\n id: string;\n blobId: string;\n altText: string;\n type: string;\n // `GET apps/blobs/download/:id` requires a bearer token, which a plain\n // `<img src>` can never send (browsers only attach cookies to image\n // requests, not custom headers) — confirmed by driving the real upload\n // flow in a browser: even a valid admin session gets a 401 loading the\n // thumbnail directly. Buyer's product-image rendering\n // (`lib/data/media.ts#blobUrl`, used the same naive way) has this same\n // bug; out of scope here, but worth flagging. This page instead fetches\n // the bytes through the authenticated `HttpClient` and renders a local\n // `blob:` object URL.\n objectUrl?: string;\n}\n\ninterface DraftProduct {\n id?: string;\n name: string;\n slug: string;\n model: string;\n brandId: string;\n primaryCategoryId: string;\n shortDesc: string;\n type: string;\n status: string;\n}\n\nconst PRODUCT_TYPES = ['simple', 'variant', 'kit'];\nconst PRODUCT_STATUSES = ['draft', 'active', 'archived', 'discontinued'];\n\n// A fixed \"folder\" id for every admin-uploaded product image.\n// `BlobsFiles.parentId` is NOT NULL in the DB despite the entity/DTO\n// marking it optional (`@IsOptional()`, `nullable: true`) — a genuine\n// vendor-package mismatch, found by running the demo-catalogue media seed\n// script against a live server and reading the resulting\n// QueryFailedError (see the commerce migrations' own notes). No FK is\n// declared on the column, so any UUID satisfies it.\nconst PRODUCT_MEDIA_PARENT_ID = '00000000-0000-4000-8000-000000000d30';\n\n// P1.15 (original slice) + R1 production-readiness pass (this rebuild).\n// The original version of this page was read-only: a product list plus\n// the CAT-03 publish-validation check, with no create/edit/media/\n// attribute/variant/pricing UI anywhere — \"no way to add items to\n// catalogue\" was the single most direct gap this session set out to\n// close. This keeps the publish-check list and adds a full create/edit\n// flow: basic info → category/brand → the category's resolved attribute\n// grid → one implicit variant (simple products; a per-variant grid for\n// `variant`-type products is real, isolated follow-up work, same\n// reasoning P1.15 originally gave for deferring it) → media upload → a\n// single default price + stock level. Search/refresh on the list are\n// real (not the generic `x-webget-collection` — this table needs a\n// bespoke \"Check\" action + inline errors the generic collection can't\n// render, so pagination/search are hand-wired here instead).\n@Component({\n standalone: false,\n selector: 'x-catalog',\n templateUrl: './catalog.component.html',\n styleUrl: './catalog.component.scss',\n})\nexport class CatalogComponent extends BaseDirective {\n private readonly http = inject(HttpClient);\n\n private readonly productSource = this.apiService.on('apps/commerce/product');\n private readonly categorySource = this.apiService.on('apps/commerce/category');\n private readonly brandSource = this.apiService.on('apps/commerce/brand');\n private readonly variantSource = this.apiService.on('apps/commerce/product-variant');\n private readonly attrValueSource = this.apiService.on('apps/commerce/product-attribute-value');\n private readonly mediaSource = this.apiService.on('apps/commerce/product-media');\n private readonly priceSource = this.apiService.on('apps/commerce/price');\n private readonly stockLevelSource = this.apiService.on('apps/commerce/stock-level');\n private readonly stockLocationSource = this.apiService.on('apps/commerce/stock-location');\n\n readonly types = PRODUCT_TYPES;\n readonly statuses = PRODUCT_STATUSES;\n\n loading = true;\n products: ProductRowVm[] = [];\n categories: CategoryOption[] = [];\n brands: BrandOption[] = [];\n stockLocations: { id: string; name: string }[] = [];\n\n query = '';\n page = 1;\n perPage = 25;\n total = 0;\n\n editing = false;\n saving = false;\n uploadingMedia = false;\n\n draft: DraftProduct | null = null;\n variant: { id?: string; sku: string; weight: number | null; handlingClass: string } | null = null;\n attributeDefs: AttributeDefVm[] = [];\n attributeValues: Record<string, AttributeValueVm> = {};\n media: MediaVm[] = [];\n price: { id?: string; amount: number | null } | null = null;\n stock: { id?: string; locationId: string; available: number } | null = null;\n\n override init = () => {\n this.loadProducts();\n this.loadCategories();\n this.loadBrands();\n this.loadStockLocations();\n };\n\n loadProducts(page = this.page): void {\n this.loading = true;\n this.page = page;\n const params: any = { page, perPage: this.perPage };\n if (this.query.trim()) params.query = this.query.trim();\n this.productSource\n .getMany(params)\n .pipe(takeUntil(this.$))\n .subscribe(\n using((response: any) => {\n this.products = (response?.data ?? []).map(\n (p: any): ProductRowVm => ({\n id: p.id,\n name: p.name,\n model: p.model,\n type: p.type,\n status: p.status,\n updatedAt: p.updatedAt,\n checking: false,\n checked: false,\n }),\n );\n this.total = response?.meta?.total ?? this.products.length;\n this.loading = false;\n }),\n );\n }\n\n search(): void {\n this.loadProducts(1);\n }\n\n refresh(): void {\n this.loadProducts(this.page);\n }\n\n prevPage(): void {\n if (this.page > 1) this.loadProducts(this.page - 1);\n }\n\n nextPage(): void {\n if (this.page * this.perPage < this.total) this.loadProducts(this.page + 1);\n }\n\n loadCategories(): void {\n this.categorySource\n .getMany({ page: 1, perPage: 300 } as any)\n .pipe(takeUntil(this.$))\n .subscribe(\n using((response: any) => {\n this.categories = (response?.data ?? []).sort((a: any, b: any) =>\n String(a.name).localeCompare(String(b.name)),\n );\n }),\n );\n }\n\n loadBrands(): void {\n this.brandSource\n .getMany({ page: 1, perPage: 200 } as any)\n .pipe(takeUntil(this.$))\n .subscribe(\n using((response: any) => {\n this.brands = (response?.data ?? []).sort((a: any, b: any) =>\n String(a.name).localeCompare(String(b.name)),\n );\n }),\n );\n }\n\n loadStockLocations(): void {\n this.stockLocationSource\n .getMany({ page: 1, perPage: 50 } as any)\n .pipe(takeUntil(this.$))\n .subscribe(using((response: any) => (this.stockLocations = response?.data ?? [])));\n }\n\n checkPublish(product: ProductRowVm): void {\n product.checking = true;\n this.productSource\n .post(`apps/commerce/product/${product.id}/validate-publish`)\n .pipe(takeUntil(this.$))\n .subscribe(\n using((response: any) => {\n product.checking = false;\n product.checked = true;\n product.canPublish = !!response?.data?.canPublish;\n product.errors = response?.data?.errors ?? [];\n }),\n );\n }\n\n startCreate(): void {\n this.editing = true;\n this.draft = {\n name: '',\n slug: '',\n model: '',\n brandId: '',\n primaryCategoryId: '',\n shortDesc: '',\n type: 'simple',\n status: 'draft',\n };\n this.variant = { sku: '', weight: null, handlingClass: 'standard' };\n this.attributeDefs = [];\n this.attributeValues = {};\n this.media = [];\n this.price = { amount: null };\n this.stock = { locationId: this.stockLocations[0]?.id ?? '', available: 0 };\n }\n\n async edit(row: ProductRowVm): Promise<void> {\n this.editing = true;\n const productRes: any = await firstValueFrom(this.productSource.getOne(row.id));\n const p = productRes?.data;\n this.draft = {\n id: p.id,\n name: p.name ?? '',\n slug: p.slug ?? '',\n model: p.model ?? '',\n brandId: p.brandId ?? '',\n primaryCategoryId: p.primaryCategoryId ?? '',\n shortDesc: p.shortDesc ?? '',\n type: p.type,\n status: p.status,\n };\n\n this.attributeValues = {};\n if (this.draft.primaryCategoryId) {\n await this.loadAttributeTemplate(this.draft.primaryCategoryId);\n } else {\n this.attributeDefs = [];\n }\n\n const [variantsRes, attrsRes, mediaRes] = await Promise.all([\n firstValueFrom(this.variantSource.getMany({ productId: p.id, page: 1, perPage: 50 } as any)),\n firstValueFrom(this.attrValueSource.getMany({ productId: p.id, page: 1, perPage: 200 } as any)),\n firstValueFrom(this.mediaSource.getMany({ productId: p.id, page: 1, perPage: 50 } as any)),\n ]);\n\n const firstVariant = (variantsRes as any)?.data?.[0];\n this.variant = firstVariant\n ? {\n id: firstVariant.id,\n sku: firstVariant.sku,\n weight: firstVariant.weight ?? null,\n handlingClass: firstVariant.handlingClass ?? 'standard',\n }\n : { sku: '', weight: null, handlingClass: 'standard' };\n\n for (const v of (attrsRes as any)?.data ?? []) {\n this.attributeValues[v.attributeDefinitionId] = {\n id: v.id,\n valueNumber: v.valueNumber,\n valueNumberHigh: v.valueNumberHigh,\n valueText: v.valueText,\n valueBool: v.valueBool,\n };\n }\n\n this.media = ((mediaRes as any)?.data ?? []).map((m: any) => ({\n id: m.id,\n blobId: m.blobId,\n altText: m.altText,\n type: m.type,\n }));\n for (const m of this.media) {\n m.objectUrl = await this.resolveMediaObjectUrl(m.blobId);\n }\n\n if (this.variant.id) {\n const priceRes: any = await firstValueFrom(\n this.priceSource.getMany({ variantId: this.variant.id, page: 1, perPage: 1 } as any),\n );\n const priceRow = priceRes?.data?.[0];\n this.price = priceRow ? { id: priceRow.id, amount: priceRow.amount } : { amount: null };\n\n const stockRes: any = await firstValueFrom(\n this.stockLevelSource.getMany({ variantId: this.variant.id, page: 1, perPage: 1 } as any),\n );\n const stockRow = stockRes?.data?.[0];\n this.stock = stockRow\n ? { id: stockRow.id, locationId: stockRow.locationId, available: stockRow.available }\n : { locationId: this.stockLocations[0]?.id ?? '', available: 0 };\n } else {\n this.price = { amount: null };\n this.stock = { locationId: this.stockLocations[0]?.id ?? '', available: 0 };\n }\n }\n\n async onCategoryChange(): Promise<void> {\n if (!this.draft?.primaryCategoryId) {\n this.attributeDefs = [];\n return;\n }\n await this.loadAttributeTemplate(this.draft.primaryCategoryId);\n }\n\n private async loadAttributeTemplate(categoryId: string): Promise<void> {\n try {\n const res: any = await firstValueFrom(\n this.apiService.get(`apps/commerce/category/${categoryId}/attribute-template`),\n );\n this.attributeDefs = (res?.data?.definitions ?? []) as AttributeDefVm[];\n for (const def of this.attributeDefs) {\n if (!this.attributeValues[def.id]) this.attributeValues[def.id] = {};\n }\n } catch {\n this.attributeDefs = [];\n }\n }\n\n async saveProduct(): Promise<void> {\n if (!this.draft || !this.draft.name.trim()) {\n notify('Name is required.', undefined, 'error');\n return;\n }\n this.saving = true;\n try {\n const payload: any = {\n name: this.draft.name.trim(),\n slug: this.draft.slug.trim() || undefined,\n brandId: this.draft.brandId || undefined,\n model: this.draft.model.trim() || undefined,\n primaryCategoryId: this.draft.primaryCategoryId || undefined,\n shortDesc: this.draft.shortDesc.trim() || undefined,\n type: this.draft.type,\n status: this.draft.status,\n };\n\n if (this.draft.id) {\n await firstValueFrom(this.productSource.update(this.draft.id, payload));\n } else {\n const res: any = await firstValueFrom(this.productSource.create(payload));\n this.draft.id = res?.data?.id;\n }\n const productId = this.draft.id!;\n\n if (this.variant && this.variant.sku.trim()) {\n const variantPayload: any = {\n productId,\n sku: this.variant.sku.trim(),\n weight: this.variant.weight != null ? Number(this.variant.weight) : undefined,\n handlingClass: this.variant.handlingClass || 'standard',\n };\n if (this.variant.id) {\n await firstValueFrom(this.variantSource.update(this.variant.id, variantPayload));\n } else {\n const vRes: any = await firstValueFrom(this.variantSource.create(variantPayload));\n this.variant.id = vRes?.data?.id;\n }\n }\n\n for (const def of this.attributeDefs) {\n const v = this.attributeValues[def.id];\n if (!v) continue;\n const hasValue =\n (v.valueNumber !== null && v.valueNumber !== undefined && `${v.valueNumber}` !== '') ||\n !!v.valueText ||\n v.valueBool !== null && v.valueBool !== undefined;\n if (!hasValue) continue;\n\n const attrPayload: any = {\n productId,\n attributeDefinitionId: def.id,\n valueNumber:\n def.dataType === 'number' || def.dataType === 'range'\n ? v.valueNumber != null && `${v.valueNumber}` !== ''\n ? Number(v.valueNumber)\n : undefined\n : undefined,\n valueNumberHigh:\n def.dataType === 'range' && v.valueNumberHigh != null && `${v.valueNumberHigh}` !== ''\n ? Number(v.valueNumberHigh)\n : undefined,\n valueText: def.dataType === 'text' || def.dataType === 'enum' ? v.valueText || undefined : undefined,\n valueBool: def.dataType === 'boolean' ? !!v.valueBool : undefined,\n };\n\n if (v.id) {\n await firstValueFrom(this.attrValueSource.update(v.id, attrPayload));\n } else {\n const aRes: any = await firstValueFrom(this.attrValueSource.create(attrPayload));\n v.id = aRes?.data?.id;\n }\n }\n\n if (this.variant?.id) {\n if (this.price && this.price.amount != null && `${this.price.amount}` !== '') {\n const pricePayload: any = {\n variantId: this.variant.id,\n amount: Number(this.price.amount),\n minQuantity: 1,\n };\n if (this.price.id) {\n await firstValueFrom(this.priceSource.update(this.price.id, pricePayload));\n } else {\n const prRes: any = await firstValueFrom(this.priceSource.create(pricePayload));\n this.price.id = prRes?.data?.id;\n }\n }\n\n if (this.stock?.locationId) {\n const stockPayload: any = {\n variantId: this.variant.id,\n locationId: this.stock.locationId,\n available: Number(this.stock.available ?? 0),\n };\n if (this.stock.id) {\n await firstValueFrom(this.stockLevelSource.update(this.stock.id, stockPayload));\n } else {\n const stRes: any = await firstValueFrom(this.stockLevelSource.create(stockPayload));\n this.stock.id = stRes?.data?.id;\n }\n }\n }\n\n notify('Product saved.', undefined, 'success');\n this.loadProducts(this.page);\n } catch {\n notify('Could not save the product (check required fields).', undefined, 'error');\n } finally {\n this.saving = false;\n }\n }\n\n async onMediaSelected(event: Event): Promise<void> {\n const input = event.target as HTMLInputElement;\n const files = input.files;\n if (!files || !files.length || !this.draft?.id) return;\n\n this.uploadingMedia = true;\n try {\n const blobId = await uploadFileToBlobs(this.apiService, files[0], PRODUCT_MEDIA_PARENT_ID, [\n 'product-media',\n ]);\n const altText = `${this.draft.name} — product photo`;\n const res: any = await firstValueFrom(\n this.mediaSource.create({\n productId: this.draft.id,\n blobId,\n type: 'gallery',\n altText,\n position: this.media.length,\n } as any),\n );\n const objectUrl = await this.resolveMediaObjectUrl(blobId);\n this.media.push({ id: res?.data?.id, blobId, altText, type: 'gallery', objectUrl });\n notify('Image uploaded.', undefined, 'success');\n } catch (e) {\n console.error('media upload failed', e);\n notify('Could not upload the image.', undefined, 'error');\n } finally {\n this.uploadingMedia = false;\n input.value = '';\n }\n }\n\n async removeMedia(item: MediaVm): Promise<void> {\n try {\n await firstValueFrom(this.mediaSource.remove(item.id));\n this.media = this.media.filter((m) => m.id !== item.id);\n } catch {\n notify('Could not remove the image.', undefined, 'error');\n }\n }\n\n // `download/:id` needs the bearer header only `HttpClient` (via the\n // app's existing `JwtInterceptor`) can attach — see the `MediaVm.\n // objectUrl` comment. Empty string on failure just leaves the\n // thumbnail blank rather than breaking the editor.\n private async resolveMediaObjectUrl(blobId: string): Promise<string> {\n try {\n const blob = await firstValueFrom(this.http.get(resolveBlobUrl(blobId), { responseType: 'blob' }));\n // Not `URL.createObjectURL` — the app's CSP `img-src` allows `data:`\n // but not `blob:`, so an object URL renders as a CSP violation\n // (confirmed by driving this in a browser). A data URI sidesteps it.\n return await new Promise<string>((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(reader.result as string);\n reader.onerror = reject;\n reader.readAsDataURL(blob);\n });\n } catch {\n return '';\n }\n }\n\n cancelEdit(): void {\n this.editing = false;\n this.draft = null;\n this.variant = null;\n this.attributeDefs = [];\n this.attributeValues = {};\n this.media = [];\n this.price = null;\n this.stock = null;\n }\n}\n","<div class=\"x-page-head\">\n <div class=\"x-page-title\">Catalogue</div>\n <div class=\"x-page-subtitle\">Products, variants, attributes, media, pricing and stock.</div>\n</div>\n\n@if (!editing) {\n <div class=\"x-cat-toolbar\">\n <input\n type=\"text\"\n class=\"x-cat-search\"\n placeholder=\"Search products…\"\n [(ngModel)]=\"query\"\n (keyup.enter)=\"search()\"\n />\n <button type=\"button\" class=\"x-cat-btn\" (click)=\"search()\">Search</button>\n <button type=\"button\" class=\"x-cat-btn\" (click)=\"refresh()\">Refresh</button>\n <div class=\"x-cat-spacer\"></div>\n <button type=\"button\" class=\"x-cat-btn x-cat-btn-primary\" (click)=\"startCreate()\">+ New product</button>\n </div>\n\n @if (loading) {\n <x-element-loader></x-element-loader>\n } @else {\n <div class=\"x-catalog-table\">\n <div class=\"x-catalog-row x-catalog-head\">\n <div class=\"x-catalog-col-name\">Product</div>\n <div class=\"x-catalog-col-type\">Type</div>\n <div class=\"x-catalog-col-status\">Status</div>\n <div class=\"x-catalog-col-check\">Publish check</div>\n <div class=\"x-catalog-col-action\"></div>\n </div>\n @for (product of products; track product.id) {\n <div class=\"x-catalog-row\">\n <div class=\"x-catalog-col-name\">\n {{ product.name }}\n @if (product.model) {\n <span class=\"x-catalog-model\">{{ product.model }}</span>\n }\n </div>\n <div class=\"x-catalog-col-type\">{{ product.type }}</div>\n <div class=\"x-catalog-col-status\">\n <span class=\"x-status-badge\" [class]=\"'x-status-' + product.status\">{{\n product.status\n }}</span>\n </div>\n <div class=\"x-catalog-col-check\">\n @if (product.checking) {\n <span class=\"x-check-pending\">Checking…</span>\n } @else if (product.checked && product.canPublish) {\n <span class=\"x-check-ok\">✓ Ready to publish</span>\n } @else if (product.checked && product.errors?.length) {\n <ul class=\"x-check-errors\">\n @for (err of product.errors; track err.field) {\n <li>{{ err.message }}</li>\n }\n </ul>\n }\n </div>\n <div class=\"x-catalog-col-action\">\n <button type=\"button\" class=\"x-cat-btn\" (click)=\"edit(product)\">Edit</button>\n <button\n type=\"button\"\n class=\"x-check-btn\"\n [disabled]=\"product.checking\"\n (click)=\"checkPublish(product)\"\n >\n Check\n </button>\n </div>\n </div>\n }\n @if (!products.length) {\n <div class=\"x-catalog-empty\">No products yet — use \"+ New product\" to add one.</div>\n }\n </div>\n\n <div class=\"x-cat-pager\">\n <button type=\"button\" class=\"x-cat-btn\" [disabled]=\"page <= 1\" (click)=\"prevPage()\">← Prev</button>\n <span class=\"x-cat-pager-label\">Page {{ page }} · {{ total }} total</span>\n <button type=\"button\" class=\"x-cat-btn\" [disabled]=\"page * perPage >= total\" (click)=\"nextPage()\">\n Next →\n </button>\n </div>\n }\n} @else if (draft) {\n <div class=\"x-cat-editor\">\n <div class=\"x-cat-editor-head\">\n <div class=\"x-cat-editor-title\">{{ draft.id ? 'Edit product' : 'New product' }}</div>\n <div class=\"x-cat-editor-actions\">\n <button type=\"button\" class=\"x-cat-btn\" (click)=\"cancelEdit()\">Close</button>\n <button type=\"button\" class=\"x-cat-btn x-cat-btn-primary\" [disabled]=\"saving\" (click)=\"saveProduct()\">\n {{ saving ? 'Saving…' : 'Save' }}\n </button>\n </div>\n </div>\n\n <section class=\"x-cat-section\">\n <div class=\"x-cat-section-title\">Basic info</div>\n <div class=\"x-cat-f-row\">\n <label class=\"x-cat-f\">\n Name\n <input type=\"text\" [(ngModel)]=\"draft.name\" />\n </label>\n <label class=\"x-cat-f\">\n Slug (optional)\n <input type=\"text\" [(ngModel)]=\"draft.slug\" placeholder=\"auto from name if blank\" />\n </label>\n </div>\n <div class=\"x-cat-f-row\">\n <label class=\"x-cat-f\">\n Model\n <input type=\"text\" [(ngModel)]=\"draft.model\" />\n </label>\n <label class=\"x-cat-f\">\n Type\n <select [(ngModel)]=\"draft.type\">\n @for (t of types; track t) { <option [value]=\"t\">{{ t }}</option> }\n </select>\n </label>\n <label class=\"x-cat-f\">\n Status\n <select [(ngModel)]=\"draft.status\">\n @for (s of statuses; track s) { <option [value]=\"s\">{{ s }}</option> }\n </select>\n </label>\n </div>\n @if (draft.type !== 'simple') {\n <div class=\"x-cat-hint\">\n \"{{ draft.type }}\" products still save through this one-variant form for now — a full\n per-variant / per-component editor is a follow-up.\n </div>\n }\n <label class=\"x-cat-f\">\n Short description\n <textarea rows=\"2\" [(ngModel)]=\"draft.shortDesc\"></textarea>\n </label>\n </section>\n\n <section class=\"x-cat-section\">\n <div class=\"x-cat-section-title\">Category & brand</div>\n <div class=\"x-cat-f-row\">\n <label class=\"x-cat-f\">\n Category\n <select [(ngModel)]=\"draft.primaryCategoryId\" (ngModelChange)=\"onCategoryChange()\">\n <option value=\"\">— none —</option>\n @for (c of categories; track c.id) { <option [value]=\"c.id\">{{ c.name }}</option> }\n </select>\n </label>\n <label class=\"x-cat-f\">\n Brand\n <select [(ngModel)]=\"draft.brandId\">\n <option value=\"\">— none —</option>\n @for (b of brands; track b.id) { <option [value]=\"b.id\">{{ b.name }}</option> }\n </select>\n </label>\n </div>\n </section>\n\n @if (attributeDefs.length) {\n <section class=\"x-cat-section\">\n <div class=\"x-cat-section-title\">Attributes</div>\n <div class=\"x-cat-attr-grid\">\n @for (def of attributeDefs; track def.id) {\n <label class=\"x-cat-f x-cat-attr\">\n {{ def.label }}{{ def.unit ? ' (' + def.unit + ')' : '' }}\n @if (def.required) {\n <span class=\"x-cat-required\">*</span>\n }\n @switch (def.dataType) {\n @case ('boolean') {\n <input type=\"checkbox\" [(ngModel)]=\"attributeValues[def.id].valueBool\" />\n }\n @case ('enum') {\n <select [(ngModel)]=\"attributeValues[def.id].valueText\">\n <option value=\"\">— choose —</option>\n @for (opt of def.allowedValues; track opt) { <option [value]=\"opt\">{{ opt }}</option> }\n </select>\n }\n @case ('range') {\n <div class=\"x-cat-range\">\n <input type=\"number\" placeholder=\"min\" [(ngModel)]=\"attributeValues[def.id].valueNumber\" />\n <span>–</span>\n <input\n type=\"number\"\n placeholder=\"max\"\n [(ngModel)]=\"attributeValues[def.id].valueNumberHigh\"\n />\n </div>\n }\n @case ('number') {\n <input type=\"number\" [(ngModel)]=\"attributeValues[def.id].valueNumber\" />\n }\n @default {\n <input type=\"text\" [(ngModel)]=\"attributeValues[def.id].valueText\" />\n }\n }\n </label>\n }\n </div>\n </section>\n }\n\n <section class=\"x-cat-section\">\n <div class=\"x-cat-section-title\">Variant, price & stock</div>\n @if (variant) {\n <div class=\"x-cat-f-row\">\n <label class=\"x-cat-f\">\n SKU\n <input type=\"text\" [(ngModel)]=\"variant.sku\" />\n </label>\n <label class=\"x-cat-f\">\n Weight (kg)\n <input type=\"number\" [(ngModel)]=\"variant.weight\" />\n </label>\n <label class=\"x-cat-f\">\n Handling class\n <select [(ngModel)]=\"variant.handlingClass\">\n <option value=\"standard\">standard</option>\n <option value=\"bulky\">bulky</option>\n <option value=\"freight\">freight</option>\n <option value=\"hazmat\">hazmat</option>\n </select>\n </label>\n </div>\n }\n <div class=\"x-cat-f-row\">\n <label class=\"x-cat-f\">\n Price (₦)\n <input type=\"number\" [(ngModel)]=\"price!.amount\" [disabled]=\"!variant?.sku\" />\n </label>\n <label class=\"x-cat-f\">\n Stock location\n <select [(ngModel)]=\"stock!.locationId\" [disabled]=\"!variant?.sku\">\n @for (loc of stockLocations; track loc.id) { <option [value]=\"loc.id\">{{ loc.name }}</option> }\n </select>\n </label>\n <label class=\"x-cat-f\">\n Available\n <input type=\"number\" [(ngModel)]=\"stock!.available\" [disabled]=\"!variant?.sku\" />\n </label>\n </div>\n @if (!variant?.sku) {\n <div class=\"x-cat-hint\">Enter a SKU above, then price/stock can be saved.</div>\n }\n </section>\n\n <section class=\"x-cat-section\">\n <div class=\"x-cat-section-title\">Media</div>\n @if (!draft.id) {\n <div class=\"x-cat-hint\">Save the product once first — media needs a real product to attach to.</div>\n } @else {\n <div class=\"x-cat-media-grid\">\n @for (m of media; track m.id) {\n <div class=\"x-cat-media-item\">\n <img [src]=\"m.objectUrl\" [alt]=\"m.altText\" />\n <button type=\"button\" class=\"x-cat-media-remove\" (click)=\"removeMedia(m)\">Remove</button>\n </div>\n }\n </div>\n <label class=\"x-cat-btn x-cat-upload\">\n {{ uploadingMedia ? 'Uploading…' : '+ Add image' }}\n <input type=\"file\" accept=\"image/*\" hidden [disabled]=\"uploadingMedia\" (change)=\"onMediaSelected($event)\" />\n </label>\n }\n </section>\n </div>\n}\n","import { NgModule } from '@angular/core';\nimport { RouterModule } from '@angular/router';\nimport { SharedModule } from '@thescaffold/ngx-core';\nimport { ElementsModule, WebgetsModule } from '@thescaffold/ngx-ui';\nimport { CatalogComponent } from './catalog.component';\n\n@NgModule({\n declarations: [CatalogComponent],\n imports: [\n SharedModule,\n ElementsModule,\n WebgetsModule,\n RouterModule.forChild([{ path: '', component: CatalogComponent }]),\n ],\n})\nexport class CatalogModule {}\n"],"names":["i1"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"isaiahiroko-tilmart-ngx-apps-admin-orders.module-Cfeb0QjH.mjs","sources":["../../../projects/admin/src/lib/pages/orders/orders.component.ts","../../../projects/admin/src/lib/pages/orders/orders.component.html","../../../projects/admin/src/lib/pages/orders/orders.module.ts"],"sourcesContent":["import { Component, TemplateRef, ViewChild, inject } from '@angular/core';\nimport { ActivatedRoute } from '@angular/router';\nimport { notify, using } from '@thescaffold/ngx-core';\nimport { FlyoutService } from '@thescaffold/ngx-ui';\nimport { takeUntil } from 'rxjs';\nimport { ListPageDirective } from '../_shared/list-page.base';\n\nfunction naira(amount: number, currency = 'NGN'): string {\n return `${currency} ${Math.round(amount).toLocaleString('en-US')}`;\n}\n\n// Ops action buttons per current status — each entry is a permitted\n// `OrderWorkflow.transition` target. Matches the PRD Appendix B matrix;\n// fulfilment-driven statuses (dispatched, delivered, …) are set by the\n// Shipments page, not here.\nconst ACTIONS: Record<string, { to: string; label: string }[]> = {\n payment_received: [{ to: 'confirmed', label: 'Confirm' }, { to: 'on_hold', label: 'Hold' }],\n on_hold: [{ to: 'confirmed', label: 'Release' }, { to: 'cancelled', label: 'Cancel' }],\n confirmed: [{ to: 'processing', label: 'Start preparing' }, { to: 'cancelled', label: 'Cancel' }],\n processing: [{ to: 'cancelled', label: 'Cancel' }],\n pending_payment: [{ to: 'cancelled', label: 'Cancel' }],\n};\n\n@Component({\n standalone: false,\n selector: 'x-orders',\n templateUrl: './orders.component.html',\n styleUrl: './orders.component.scss',\n})\nexport class OrdersComponent extends ListPageDirective {\n private readonly flyoutService = inject(FlyoutService);\n private readonly route = inject(ActivatedRoute);\n\n protected pluralName = 'orders';\n protected dataSource = this.apiService.on('apps/commerce/order');\n private readonly lineSource = this.apiService.on('apps/commerce/order-line');\n private readonly historySource = this.apiService.on('apps/commerce/order-status-history');\n private readonly paymentSource = this.apiService.on('apps/commerce/payment');\n private readonly shipmentSource = this.apiService.on('apps/commerce/shipment');\n\n protected columns = [\n { key: 'orderNumber', value: 'Order' },\n { key: 'status', value: 'Status', type: 'class', class: 'badge text-bg-light border' },\n { key: 'grandTotalLabel', value: 'Total' },\n { key: 'paidLabel', value: 'Paid' },\n { key: 'placedAt', value: 'Placed', type: 'date' },\n ];\n\n detail: any = null;\n detailActions: { to: string; label: string }[] = [];\n naira = naira;\n\n @ViewChild('detailFlyout', { read: TemplateRef, static: true })\n detailFlyout!: TemplateRef<any>;\n\n override init = () => {\n this.query = this.route.snapshot.queryParamMap.get('q') ?? '';\n this.list();\n };\n\n view(item: any) {\n this.detail = null;\n this.detailActions = ACTIONS[item.status] ?? [];\n this.flyoutService.open(this.detailFlyout);\n\n this.lineSource\n .getMany({ orderId: item.id, page: 1, perPage: 200 } as any)\n .pipe(takeUntil(this.$))\n .subscribe(\n using(({ data: lines }: { data: any[] }) => {\n this.detail = {\n id: item.id,\n orderNumber: item.orderNumber,\n status: item.status,\n currency: item.currency,\n businessName: item.businessName,\n recipientName: item.recipientName,\n recipientPhone: item.recipientPhone,\n subtotal: Number(item.subtotal ?? 0),\n deliveryTotal: Number(item.deliveryTotal ?? 0),\n taxTotal: Number(item.taxTotal ?? 0),\n grandTotal: Number(item.grandTotal ?? 0),\n amountPaid: Number(item.amountPaid ?? 0),\n codAmountDue: Number(item.codAmountDue ?? 0),\n lines: lines ?? [],\n history: [],\n payments: [],\n shipments: [],\n };\n\n this.historySource\n .getMany({ orderId: item.id, page: 1, perPage: 100 } as any)\n .pipe(takeUntil(this.$))\n .subscribe(using(({ data }: { data: any[] }) => {\n if (this.detail) this.detail.history = data ?? [];\n }));\n this.paymentSource\n .getMany({ orderId: item.id, page: 1, perPage: 20 } as any)\n .pipe(takeUntil(this.$))\n .subscribe(using(({ data }: { data: any[] }) => {\n if (this.detail) this.detail.payments = data ?? [];\n }));\n this.shipmentSource\n .getMany({ orderId: item.id, page: 1, perPage: 50 } as any)\n .pipe(takeUntil(this.$))\n .subscribe(using(({ data }: { data: any[] }) => {\n if (this.detail) this.detail.shipments = data ?? [];\n }));\n }),\n );\n }\n\n transition(to: string) {\n if (!this.detail) return;\n this.apiService\n .post(`apps/commerce/order/${this.detail.id}/transition`, { toStatus: to })\n .pipe(takeUntil(this.$))\n .subscribe(\n using((res: any) => {\n if (res?.status === 'error') {\n notify(res.message || 'That transition is not allowed.', undefined, 'error');\n return;\n }\n notify(`Order moved to ${to.replace(/_/g, ' ')}.`, undefined, 'success');\n this.flyoutService.dismiss();\n this.list();\n }),\n );\n }\n\n protected override mapRow(order: any) {\n return {\n ...order,\n grandTotalLabel: naira(Number(order.grandTotal ?? 0), order.currency),\n paidLabel: naira(Number(order.amountPaid ?? 0), order.currency),\n };\n }\n\n protected override extraCollectionFields() {\n return {\n links: {\n secondary: [{ title: 'View', fn: (_link: any, item: any) => this.view(item) }],\n },\n };\n }\n}\n","<div class=\"x-page-head\">\n <div class=\"x-page-title\">Orders</div>\n <div class=\"x-page-subtitle\">Every order — search, drill in, move it forward.</div>\n</div>\n\n@if (list$ | async; as list) {\n <x-webget-collection [data]=\"list\"></x-webget-collection>\n} @else {\n <x-element-loader></x-element-loader>\n}\n\n<ng-template #detailFlyout>\n <x-webget-flyout [data]=\"{ title: 'Order detail' }\">\n <div class=\"p-4 d-flex flex-column gap-3\">\n @if (detail) {\n <div>\n <div class=\"fw-bold font-monospace\">\n {{ detail.orderNumber }}\n <a\n class=\"small ms-2\"\n [routerLink]=\"['/admin/trace']\"\n [queryParams]=\"{ ref: detail.orderNumber }\"\n >full trace →</a>\n </div>\n <span class=\"badge text-bg-light border mt-1\">{{ detail.status }}</span>\n @if (detail.businessName) {\n <div class=\"text-secondary small mt-1\">Invoice to: {{ detail.businessName }}</div>\n }\n @if (detail.recipientName) {\n <div class=\"text-secondary small\">Recipient: {{ detail.recipientName }} · {{ detail.recipientPhone }}</div>\n }\n </div>\n\n @if (detailActions.length) {\n <div class=\"d-flex flex-wrap gap-2\">\n @for (action of detailActions; track action.to) {\n <button type=\"button\" class=\"btn btn-sm btn-outline-dark\" (click)=\"transition(action.to)\">\n {{ action.label }}\n </button>\n }\n </div>\n }\n\n <table class=\"table table-sm\">\n <thead><tr><th>Item</th><th>Qty</th><th class=\"text-end\">Amount</th></tr></thead>\n <tbody>\n @for (line of detail.lines; track line.id) {\n <tr>\n <td>{{ line.nameSnapshot || line.variantId }}</td>\n <td>{{ line.quantity }}</td>\n <td class=\"text-end\">{{ naira(line.unitPrice * line.quantity, detail.currency) }}</td>\n </tr>\n } @empty {\n <tr><td colspan=\"3\" class=\"text-secondary\">No lines.</td></tr>\n }\n </tbody>\n </table>\n\n <div class=\"small\">\n <div class=\"d-flex justify-content-between\"><span>Subtotal</span><span>{{ naira(detail.subtotal, detail.currency) }}</span></div>\n <div class=\"d-flex justify-content-between\"><span>Delivery</span><span>{{ naira(detail.deliveryTotal, detail.currency) }}</span></div>\n <div class=\"d-flex justify-content-between\"><span>VAT (incl.)</span><span>{{ naira(detail.taxTotal, detail.currency) }}</span></div>\n <div class=\"d-flex justify-content-between fw-bold\"><span>Total</span><span>{{ naira(detail.grandTotal, detail.currency) }}</span></div>\n <div class=\"d-flex justify-content-between\"><span>Paid</span><span>{{ naira(detail.amountPaid, detail.currency) }}</span></div>\n @if (detail.codAmountDue > 0) {\n <div class=\"d-flex justify-content-between text-warning\"><span>Due on delivery</span><span>{{ naira(detail.codAmountDue, detail.currency) }}</span></div>\n }\n </div>\n\n <hr class=\"my-1\" />\n <div>\n <div class=\"fw-bold small mb-1\">Payments</div>\n @for (payment of detail.payments; track payment.id) {\n <div class=\"small text-secondary\">\n {{ payment.provider }} · {{ payment.method || 'card' }} · {{ payment.status }}\n · {{ naira(payment.amount, payment.currency) }}\n </div>\n } @empty {\n <div class=\"small text-secondary\">None.</div>\n }\n </div>\n\n <div>\n <div class=\"fw-bold small mb-1\">Shipments</div>\n @for (shipment of detail.shipments; track shipment.id) {\n <div class=\"small text-secondary\">\n {{ shipment.status }}@if (shipment.trackingRef) { · {{ shipment.trackingRef }} }\n </div>\n } @empty {\n <div class=\"small text-secondary\">None yet — create one on the Shipments page.</div>\n }\n </div>\n\n <div>\n <div class=\"fw-bold small mb-1\">History</div>\n @for (row of detail.history; track row.id) {\n <div class=\"small text-secondary\">\n {{ row.toStatus }} · {{ row.createdAt | date: 'MMM d, h:mm a' }}\n @if (row.reason) { — {{ row.reason }} }\n </div>\n } @empty {\n <div class=\"small text-secondary\">No transitions recorded.</div>\n }\n </div>\n } @else {\n <x-element-loader></x-element-loader>\n }\n </div>\n </x-webget-flyout>\n</ng-template>\n","import { NgModule } from '@angular/core';\nimport { RouterModule } from '@angular/router';\nimport { SharedModule } from '@thescaffold/ngx-core';\nimport { ElementsModule, WebgetsModule } from '@thescaffold/ngx-ui';\nimport { OrdersComponent } from './orders.component';\n\n@NgModule({\n declarations: [OrdersComponent],\n imports: [\n SharedModule,\n ElementsModule,\n WebgetsModule,\n RouterModule.forChild([{ path: '', component: OrdersComponent }]),\n ],\n})\nexport class OrdersModule {}\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"isaiahiroko-tilmart-ngx-apps-admin-settings.module-Cz6xPNwB.mjs","sources":["../../../projects/admin/src/lib/pages/settings/settings.component.ts","../../../projects/admin/src/lib/pages/settings/settings.component.html","../../../projects/admin/src/lib/pages/settings/settings.module.ts"],"sourcesContent":["import { Component } from '@angular/core';\nimport { BaseDirective, notify, titleCase, using } from '@thescaffold/ngx-core';\nimport { BehaviorSubject, firstValueFrom, map, takeUntil } from 'rxjs';\nimport { CrudFieldSpec } from '../_shared/simple-crud.base';\n\ninterface Section {\n key: string;\n title: string;\n singularLabel: string;\n mount: string;\n columns: { key: string; value: string; type?: string; class?: string }[];\n fields: CrudFieldSpec[];\n data$: BehaviorSubject<any>;\n page: number;\n query?: string;\n}\n\n// R1 production-readiness pass — ADM-12 / ORD-05. P7.1's original\n// version stacked these four config resources as read-only lists; ops\n// had no way to add a channel, shipping zone, shipping method or return\n// policy \"without a deploy\" (ADM-12's own words). Same field-by-field\n// form idea as `SimpleCrudDirective`, adapted for four resources sharing\n// one tabbed page rather than one resource per route.\n@Component({\n standalone: false,\n selector: 'x-settings',\n templateUrl: './settings.component.html',\n styleUrl: './settings.component.scss',\n})\nexport class SettingsComponent extends BaseDirective {\n readonly sections: Section[] = [\n {\n key: 'channels',\n title: 'Channels',\n singularLabel: 'channel',\n mount: 'apps/commerce/channel',\n columns: [\n { key: 'name', value: 'Name' },\n { key: 'code', value: 'Code' },\n { key: 'currency', value: 'Currency' },\n ],\n fields: [\n { key: 'name', label: 'Name', type: 'text', required: true },\n { key: 'code', label: 'Code', type: 'text', required: true, placeholder: 'e.g. web-ng' },\n { key: 'currency', label: 'Currency', type: 'text', placeholder: 'NGN' },\n {\n key: 'taxMode',\n label: 'Tax mode',\n type: 'select',\n options: [\n { value: 'inclusive', label: 'Inclusive' },\n { value: 'exclusive', label: 'Exclusive' },\n ],\n },\n ],\n data$: new BehaviorSubject<any>(null),\n page: 1,\n },\n {\n key: 'zones',\n title: 'Shipping zones',\n singularLabel: 'shipping zone',\n mount: 'apps/commerce/delivery-zone',\n columns: [\n { key: 'name', value: 'Name' },\n { key: 'state', value: 'State' },\n { key: 'lga', value: 'LGA' },\n ],\n fields: [\n { key: 'name', label: 'Name', type: 'text', required: true },\n { key: 'state', label: 'State', type: 'text', required: true },\n { key: 'lga', label: 'LGA', type: 'text' },\n ],\n data$: new BehaviorSubject<any>(null),\n page: 1,\n },\n {\n key: 'methods',\n title: 'Shipping methods',\n singularLabel: 'shipping method',\n mount: 'apps/commerce/delivery-method',\n columns: [\n { key: 'name', value: 'Name' },\n { key: 'flatFee', value: 'Flat fee' },\n { key: 'perKg', value: 'Per kg' },\n {\n key: 'enabled',\n value: 'Enabled',\n type: 'class',\n class: 'badge text-bg-light border',\n },\n ],\n fields: [\n { key: 'name', label: 'Name', type: 'text', required: true },\n {\n key: 'type',\n label: 'Type',\n type: 'select',\n options: [\n { value: 'door', label: 'Door delivery' },\n { value: 'express', label: 'Express' },\n { value: 'pickup', label: 'Pickup' },\n { value: 'scheduled', label: 'Scheduled' },\n { value: 'freight', label: 'Freight' },\n ],\n },\n { key: 'estimateDaysMin', label: 'Estimate — min days', type: 'number' },\n { key: 'estimateDaysMax', label: 'Estimate — max days', type: 'number' },\n { key: 'enabled', label: 'Enabled', type: 'boolean' },\n {\n key: 'rateRules',\n label: 'Rate rules (JSON array)',\n type: 'json',\n placeholder: '[{\"zoneId\": null, \"flatFee\": 2000, \"perKg\": 150}]',\n },\n ],\n data$: new BehaviorSubject<any>(null),\n page: 1,\n },\n {\n key: 'returns',\n title: 'Return policies',\n singularLabel: 'return policy',\n mount: 'apps/commerce/return-policy',\n columns: [\n { key: 'windowDays', value: 'Window (days)' },\n { key: 'restockingFeePct', value: 'Restock fee %' },\n { key: 'whoPaysReturn', value: 'Who pays' },\n {\n key: 'enabled',\n value: 'Enabled',\n type: 'class',\n class: 'badge text-bg-light border',\n },\n ],\n fields: [\n { key: 'windowDays', label: 'Return window (days)', type: 'number', required: true },\n {\n key: 'reasonCode',\n label: 'Reason code (blank = default policy)',\n type: 'select',\n options: [\n { value: 'damaged_in_transit', label: 'Damaged in transit' },\n { value: 'wrong_item', label: 'Wrong item' },\n { value: 'not_as_described', label: 'Not as described' },\n { value: 'faulty_on_arrival', label: 'Faulty on arrival' },\n { value: 'changed_mind', label: 'Changed mind' },\n { value: 'missing_parts', label: 'Missing parts' },\n ],\n },\n { key: 'restockingFeePct', label: 'Restocking fee %', type: 'number' },\n {\n key: 'whoPaysReturn',\n label: 'Who pays for return shipping',\n type: 'select',\n options: [\n { value: 'customer', label: 'Customer' },\n { value: 'tilmart', label: 'Tilmart' },\n { value: 'seller', label: 'Seller' },\n ],\n },\n { key: 'allowChangeOfMind', label: 'Allow change-of-mind returns', type: 'boolean' },\n { key: 'enabled', label: 'Enabled', type: 'boolean' },\n ],\n data$: new BehaviorSubject<any>(null),\n page: 1,\n },\n ];\n\n active = this.sections[0].key;\n editing = false;\n saving = false;\n draft: Record<string, any> | null = null;\n\n get activeSection(): Section {\n return this.sections.find((s) => s.key === this.active)!;\n }\n\n override init = () => {\n for (const section of this.sections) this.load(section);\n };\n\n private load(section: Section, page = section.page, query = section.query): void {\n section.page = page;\n section.query = query;\n const params: any = { page, perPage: 100 };\n if (query) params.query = query;\n this.apiService\n .on(section.mount)\n .getMany(params)\n .pipe(\n takeUntil(this.$),\n map((response: any) => ({\n title: titleCase(section.title),\n columns: section.columns,\n rows: response?.data,\n hasHeaders: true,\n hasTextFilter: true,\n page: response?.meta?.current_page,\n perPage: response?.meta?.per_page,\n total: response?.meta?.total,\n onPage: (p: number) => this.load(section, p, query),\n onSearch: (q: string) => this.load(section, 1, q),\n onRefresh: () => this.load(section, page, query),\n links: {\n secondary: [{ title: 'Edit', fn: (_l: any, item: any) => this.edit(item) }],\n },\n })),\n )\n .subscribe(using((data) => section.data$.next(data)));\n }\n\n selectTab(key: string): void {\n this.active = key;\n this.editing = false;\n this.draft = null;\n }\n\n startCreate(): void {\n this.editing = true;\n const draft: Record<string, any> = {};\n for (const field of this.activeSection.fields) {\n draft[field.key] = field.type === 'boolean' ? false : '';\n }\n this.draft = draft;\n }\n\n edit(item: any): void {\n this.editing = true;\n const draft = { ...item };\n for (const field of this.activeSection.fields) {\n if (field.type === 'json' && draft[field.key] != null && typeof draft[field.key] !== 'string') {\n draft[field.key] = JSON.stringify(draft[field.key], null, 2);\n }\n }\n this.draft = draft;\n }\n\n cancelEdit(): void {\n this.editing = false;\n this.draft = null;\n }\n\n async save(): Promise<void> {\n if (!this.draft) return;\n const section = this.activeSection;\n this.saving = true;\n try {\n const payload: Record<string, any> = {};\n for (const field of section.fields) {\n const raw = this.draft[field.key];\n if (field.type === 'number') {\n payload[field.key] = raw !== null && raw !== undefined && `${raw}` !== '' ? Number(raw) : undefined;\n } else if (field.type === 'boolean') {\n payload[field.key] = !!raw;\n } else if (field.type === 'json') {\n try {\n payload[field.key] = raw && `${raw}`.trim() ? JSON.parse(raw) : undefined;\n } catch {\n payload[field.key] = undefined;\n }\n } else {\n payload[field.key] = raw || undefined;\n }\n }\n\n const source = this.apiService.on(section.mount);\n if (this.draft['id']) {\n await firstValueFrom(source.update(this.draft['id'], payload));\n } else {\n await firstValueFrom(source.create(payload));\n }\n notify(`${titleCase(section.singularLabel)} saved.`, undefined, 'success');\n this.editing = false;\n this.draft = null;\n this.load(section, section.page, section.query);\n } catch {\n notify('Could not save (check required fields).', undefined, 'error');\n } finally {\n this.saving = false;\n }\n }\n\n async remove(): Promise<void> {\n if (!this.draft?.['id']) return;\n const section = this.activeSection;\n try {\n await firstValueFrom(this.apiService.on(section.mount).remove(this.draft['id']));\n notify(`${titleCase(section.singularLabel)} deleted.`, undefined, 'success');\n this.editing = false;\n this.draft = null;\n this.load(section, section.page, section.query);\n } catch {\n notify('Could not delete — it may still be referenced elsewhere.', undefined, 'error');\n }\n }\n}\n","<div class=\"x-page-head\">\n <div class=\"x-page-title\">Settings</div>\n <div class=\"x-page-subtitle\">\n Channels, shipping and returns configuration.\n </div>\n</div>\n\n<nav class=\"x-settings-tabs\">\n @for (s of sections; track s.key) {\n <button\n type=\"button\"\n class=\"x-settings-tab\"\n [class.is-active]=\"active === s.key\"\n (click)=\"selectTab(s.key)\"\n >\n {{ s.title }}\n </button>\n }\n</nav>\n\n@for (s of sections; track s.key) {\n @if (active === s.key) {\n @if (!editing) {\n <div class=\"x-settings-toolbar\">\n <button type=\"button\" class=\"x-settings-btn x-settings-btn-primary\" (click)=\"startCreate()\">\n + New {{ s.singularLabel }}\n </button>\n </div>\n @if (s.data$ | async; as list) {\n <x-webget-collection [data]=\"list\"></x-webget-collection>\n } @else {\n <x-element-loader></x-element-loader>\n }\n } @else if (draft) {\n <div class=\"x-settings-editor\">\n <div class=\"x-settings-editor-head\">\n <div class=\"x-settings-editor-title\">{{ draft['id'] ? 'Edit' : 'New' }} {{ s.singularLabel }}</div>\n <div class=\"x-settings-editor-actions\">\n @if (draft['id']) {\n <button type=\"button\" class=\"x-settings-btn x-settings-danger\" (click)=\"remove()\">Delete</button>\n }\n <button type=\"button\" class=\"x-settings-btn\" (click)=\"cancelEdit()\">Close</button>\n <button type=\"button\" class=\"x-settings-btn x-settings-btn-primary\" [disabled]=\"saving\" (click)=\"save()\">\n {{ saving ? 'Saving…' : 'Save' }}\n </button>\n </div>\n </div>\n\n <div class=\"x-settings-grid\">\n @for (f of s.fields; track f.key) {\n <label class=\"x-settings-f\" [class.x-settings-f-wide]=\"f.type === 'textarea' || f.type === 'json'\">\n {{ f.label }}\n @if (f.required) {\n <span class=\"x-settings-required\">*</span>\n }\n @switch (f.type) {\n @case ('boolean') {\n <input type=\"checkbox\" [(ngModel)]=\"draft[f.key]\" />\n }\n @case ('select') {\n <select [(ngModel)]=\"draft[f.key]\">\n <option value=\"\">— choose —</option>\n @for (opt of f.options; track opt.value) {\n <option [value]=\"opt.value\">{{ opt.label }}</option>\n }\n </select>\n }\n @case ('json') {\n <textarea rows=\"4\" class=\"x-settings-json\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || '{}'\"></textarea>\n }\n @case ('number') {\n <input type=\"number\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\" />\n }\n @default {\n <input type=\"text\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\" />\n }\n }\n </label>\n }\n </div>\n </div>\n }\n }\n}\n\n<div class=\"x-settings-more\">\n <p>\n <strong>Users & roles</strong> —\n <a routerLink=\"/admin/users\">manage accounts</a>.\n </p>\n <p>\n <strong>Notifications</strong> — transactional and marketing templates\n are seeded per environment (NotificationTemplates); per-customer\n preferences are on the customer record.\n </p>\n <p class=\"x-settings-audit\">\n <strong>Audit log</strong> — every privileged action is recorded\n (ntx-apps-audit); <a routerLink=\"/admin/audit\">open the viewer</a>.\n </p>\n</div>\n","import { NgModule } from '@angular/core';\nimport { RouterModule } from '@angular/router';\nimport { SharedModule } from '@thescaffold/ngx-core';\nimport { ElementsModule, WebgetsModule } from '@thescaffold/ngx-ui';\nimport { SettingsComponent } from './settings.component';\n\n@NgModule({\n declarations: [SettingsComponent],\n imports: [\n SharedModule,\n ElementsModule,\n WebgetsModule,\n RouterModule.forChild([{ path: '', component: SettingsComponent }]),\n ],\n})\nexport class SettingsModule {}\n"],"names":["i2","i3","i4","i1"],"mappings":"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"}
|