@argusoft/medplat-product-management 1.0.3 → 1.0.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/dist/{BrandsPage-NSvaMXWg.js → BrandsPage-BE3kn-8b.js} +79 -78
- package/dist/{BrandsPage-NSvaMXWg.js.map → BrandsPage-BE3kn-8b.js.map} +1 -1
- package/dist/{CategoriesPage-aZBZrDOi.js → CategoriesPage-COqi3pMi.js} +70 -69
- package/dist/{CategoriesPage-aZBZrDOi.js.map → CategoriesPage-COqi3pMi.js.map} +1 -1
- package/dist/{DashboardPage-DjwlOhrd.js → DashboardPage-C_H1Jrey.js} +91 -90
- package/dist/{DashboardPage-DjwlOhrd.js.map → DashboardPage-C_H1Jrey.js.map} +1 -1
- package/dist/{FacilityPicker-Chh-ZaR0.js → FacilityPicker-Diq2hnYg.js} +2 -2
- package/dist/{FacilityPicker-Chh-ZaR0.js.map → FacilityPicker-Diq2hnYg.js.map} +1 -1
- package/dist/{InventoryPage-cy76UsMp.js → InventoryPage-Bjpw6vTz.js} +113 -112
- package/dist/{InventoryPage-cy76UsMp.js.map → InventoryPage-Bjpw6vTz.js.map} +1 -1
- package/dist/{MemberProfileCard-CinPt09F.js → MemberProfileCard-BLUVRILO.js} +6 -5
- package/dist/{MemberProfileCard-CinPt09F.js.map → MemberProfileCard-BLUVRILO.js.map} +1 -1
- package/dist/{PaymentCreatePage-BJe3LyFF.js → PaymentCreatePage-B5VOgTx9.js} +125 -124
- package/dist/{PaymentCreatePage-BJe3LyFF.js.map → PaymentCreatePage-B5VOgTx9.js.map} +1 -1
- package/dist/{PaymentsPage-DxHoKksN.js → PaymentsPage-DY6BclkN.js} +21 -20
- package/dist/{PaymentsPage-DxHoKksN.js.map → PaymentsPage-DY6BclkN.js.map} +1 -1
- package/dist/{PickupCreatePage-Cq8zJ62Y.js → PickupCreatePage-CCSiyFQF.js} +63 -62
- package/dist/{PickupCreatePage-Cq8zJ62Y.js.map → PickupCreatePage-CCSiyFQF.js.map} +1 -1
- package/dist/{PickupsPage-BOygBQAb.js → PickupsPage-DGi6T5Of.js} +42 -41
- package/dist/{PickupsPage-BOygBQAb.js.map → PickupsPage-DGi6T5Of.js.map} +1 -1
- package/dist/PmGuard-C90yhpsN.js +592 -0
- package/dist/PmGuard-C90yhpsN.js.map +1 -0
- package/dist/{PmTable-CCpaJEA_.js → PmTable-BkK65bJQ.js} +96 -96
- package/dist/{PmTable-CCpaJEA_.js.map → PmTable-BkK65bJQ.js.map} +1 -1
- package/dist/{ProductEditPage-DmdHO-fS.js → ProductEditPage-CQj9egzW.js} +130 -129
- package/dist/{ProductEditPage-DmdHO-fS.js.map → ProductEditPage-CQj9egzW.js.map} +1 -1
- package/dist/{ProductsPage-BglMe8EM.js → ProductsPage-i8QVw_Jm.js} +64 -63
- package/dist/{ProductsPage-BglMe8EM.js.map → ProductsPage-i8QVw_Jm.js.map} +1 -1
- package/dist/{PurchaseCreatePage-1tYk41RS.js → PurchaseCreatePage-Bp6bl9n8.js} +120 -119
- package/dist/{PurchaseCreatePage-1tYk41RS.js.map → PurchaseCreatePage-Bp6bl9n8.js.map} +1 -1
- package/dist/{PurchaseRequestDetailPage-BYLx3aBI.js → PurchaseRequestDetailPage-CNAqIFef.js} +216 -215
- package/dist/{PurchaseRequestDetailPage-BYLx3aBI.js.map → PurchaseRequestDetailPage-CNAqIFef.js.map} +1 -1
- package/dist/{PurchaseRequestsPage-D2yorc4s.js → PurchaseRequestsPage-BJqDlNrc.js} +57 -56
- package/dist/{PurchaseRequestsPage-D2yorc4s.js.map → PurchaseRequestsPage-BJqDlNrc.js.map} +1 -1
- package/dist/{PurchasesPage-CanQTjlw.js → PurchasesPage-BQEToymQ.js} +76 -75
- package/dist/{PurchasesPage-CanQTjlw.js.map → PurchasesPage-BQEToymQ.js.map} +1 -1
- package/dist/{SaleCreatePage-DxFvPvju.js → SaleCreatePage-DbfBK4PH.js} +89 -88
- package/dist/{SaleCreatePage-DxFvPvju.js.map → SaleCreatePage-DbfBK4PH.js.map} +1 -1
- package/dist/{SalesPage-CPMrdr5-.js → SalesPage-CTBJMxZe.js} +46 -45
- package/dist/{SalesPage-CPMrdr5-.js.map → SalesPage-CTBJMxZe.js.map} +1 -1
- package/dist/{SettingsPage-CEy922rW.js → SettingsPage-CiwVmzM3.js} +47 -46
- package/dist/{SettingsPage-CEy922rW.js.map → SettingsPage-CiwVmzM3.js.map} +1 -1
- package/dist/{StorageUnitsPage-DfLT6xC_.js → StorageUnitsPage-BV7nK_iE.js} +55 -54
- package/dist/{StorageUnitsPage-DfLT6xC_.js.map → StorageUnitsPage-BV7nK_iE.js.map} +1 -1
- package/dist/{TransactionsPage-KFUJ4O5g.js → TransactionsPage-Cocn4901.js} +54 -53
- package/dist/{TransactionsPage-KFUJ4O5g.js.map → TransactionsPage-Cocn4901.js.map} +1 -1
- package/dist/{TransferCreatePage-k1tsRGB3.js → TransferCreatePage-DbjcjuOg.js} +74 -73
- package/dist/{TransferCreatePage-k1tsRGB3.js.map → TransferCreatePage-DbjcjuOg.js.map} +1 -1
- package/dist/{TransfersPage-CDafSVO9.js → TransfersPage-BFVF7Xvc.js} +108 -107
- package/dist/{TransfersPage-CDafSVO9.js.map → TransfersPage-BFVF7Xvc.js.map} +1 -1
- package/dist/VialsPage-BNzYTLVd.js +321 -0
- package/dist/VialsPage-BNzYTLVd.js.map +1 -0
- package/dist/index.js +652 -34
- package/dist/index.js.map +1 -1
- package/dist/settingsStore-KW217unV.js +417 -0
- package/dist/settingsStore-KW217unV.js.map +1 -0
- package/package.json +1 -1
- package/dist/VialsPage-DPsYFgaQ.js +0 -897
- package/dist/VialsPage-DPsYFgaQ.js.map +0 -1
- package/dist/currency-bVQ7aEk2.js +0 -1007
- package/dist/currency-bVQ7aEk2.js.map +0 -1
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { c as
|
|
3
|
-
import { i as
|
|
4
|
-
import { t as
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { Alert as
|
|
9
|
-
import w from "
|
|
10
|
-
import he from "
|
|
11
|
-
import ge from "
|
|
12
|
-
import
|
|
13
|
-
import E from "
|
|
14
|
-
import
|
|
1
|
+
import { Z as e, p as t, r as n } from "./settingsStore-KW217unV.js";
|
|
2
|
+
import { c as r, n as i, s as a, t as ee } from "./PmTable-BkK65bJQ.js";
|
|
3
|
+
import { i as te, m as o, t as s } from "./validation-Ba7puFIO.js";
|
|
4
|
+
import { t as c } from "./useFieldErrors-hDG8ox_x.js";
|
|
5
|
+
import { a as ne, i as re, n as ie, r as ae, t as l } from "./PmGuard-C90yhpsN.js";
|
|
6
|
+
import { useState as u } from "react";
|
|
7
|
+
import { jsx as d, jsxs as f } from "react/jsx-runtime";
|
|
8
|
+
import { Alert as oe, Box as p, Button as m, Checkbox as se, Chip as ce, Dialog as le, DialogActions as ue, DialogContent as h, DialogTitle as de, FormControlLabel as g, InputAdornment as fe, Skeleton as _, Stack as v, TableBody as y, TableCell as b, TableHead as pe, TableRow as x, TextField as S, Typography as C } from "@mui/material";
|
|
9
|
+
import { showToast as w } from "@/common/toaster/toaster";
|
|
10
|
+
import { findCountry as me, validatePhoneForCountry as he } from "@/common/constants/countries";
|
|
11
|
+
import { v4 as ge } from "uuid";
|
|
12
|
+
import T from "@mui/icons-material/AddRounded";
|
|
13
|
+
import E from "@mui/icons-material/RefreshRounded";
|
|
14
|
+
import D from "@mui/icons-material/SellRounded";
|
|
15
|
+
import O from "@/views/custom-components/CustomSwitch";
|
|
15
16
|
//#region src/views/BrandsPage.jsx
|
|
16
17
|
function k(e) {
|
|
17
18
|
if (!e) return {
|
|
@@ -36,7 +37,7 @@ function A({ phone: e, email: t }) {
|
|
|
36
37
|
return e?.trim() && (n.phone = e.trim()), t?.trim() && (n.email = t.trim()), Object.keys(n).length ? JSON.stringify(n) : null;
|
|
37
38
|
}
|
|
38
39
|
function j() {
|
|
39
|
-
let j =
|
|
40
|
+
let j = re().has("update.manage.productManagement.brand"), M = me(n()?.countryCode), [N, P] = u([]), [F, I] = u(!1), [L, R] = u(""), [_e, z] = u(!1), [B, V] = u(null), [H, ve] = u(!1), [U, W] = u(K()), G = c();
|
|
40
41
|
function K() {
|
|
41
42
|
return {
|
|
42
43
|
id: "",
|
|
@@ -50,10 +51,10 @@ function j() {
|
|
|
50
51
|
async function q() {
|
|
51
52
|
I(!0), R("");
|
|
52
53
|
try {
|
|
53
|
-
P(await
|
|
54
|
+
P(await t(void 0, !0));
|
|
54
55
|
} catch (e) {
|
|
55
56
|
let t = e?.response?.data?.message ?? e?.message ?? "Failed to load brands";
|
|
56
|
-
R(t),
|
|
57
|
+
R(t), w({
|
|
57
58
|
message: t,
|
|
58
59
|
type: "error"
|
|
59
60
|
});
|
|
@@ -61,13 +62,13 @@ function j() {
|
|
|
61
62
|
I(!1);
|
|
62
63
|
}
|
|
63
64
|
}
|
|
64
|
-
|
|
65
|
+
ae("view.manage.productManagement.brand", () => {
|
|
65
66
|
q();
|
|
66
67
|
}, []);
|
|
67
68
|
function J() {
|
|
68
69
|
V(null), W({
|
|
69
70
|
...K(),
|
|
70
|
-
id:
|
|
71
|
+
id: ge()
|
|
71
72
|
}), G.reset(), R(""), z(!0);
|
|
72
73
|
}
|
|
73
74
|
function ye(e) {
|
|
@@ -81,19 +82,19 @@ function j() {
|
|
|
81
82
|
isActive: e.isActive !== !1
|
|
82
83
|
}), z(!0);
|
|
83
84
|
}
|
|
84
|
-
let Y =
|
|
85
|
-
name:
|
|
85
|
+
let Y = o(U.manufacturerCode, "Manufacturer code"), X = U.manufacturerCode.trim().toUpperCase(), be = !Y && X && N.some((e) => e.id !== U.id && (e.manufacturerCode || "").toUpperCase() === X), Z = {
|
|
86
|
+
name: o(U.name, "Name"),
|
|
86
87
|
manufacturerCode: Y || (be ? "Code is already in use — edit it manually to make it unique." : ""),
|
|
87
|
-
contactPhone:
|
|
88
|
-
contactEmail:
|
|
89
|
-
}, Q =
|
|
88
|
+
contactPhone: he(U.contactPhone, M),
|
|
89
|
+
contactEmail: te(U.contactEmail)
|
|
90
|
+
}, Q = s(Z);
|
|
90
91
|
async function xe() {
|
|
91
92
|
if (!Q) {
|
|
92
93
|
G.markAllTouched(), R("Please fix the highlighted fields.");
|
|
93
94
|
return;
|
|
94
95
|
}
|
|
95
96
|
try {
|
|
96
|
-
await
|
|
97
|
+
await e({
|
|
97
98
|
id: U.id,
|
|
98
99
|
name: U.name.trim(),
|
|
99
100
|
manufacturerCode: U.manufacturerCode.trim().toUpperCase(),
|
|
@@ -102,54 +103,54 @@ function j() {
|
|
|
102
103
|
email: U.contactEmail
|
|
103
104
|
}),
|
|
104
105
|
isActive: U.isActive
|
|
105
|
-
}),
|
|
106
|
+
}), w({
|
|
106
107
|
message: "Brand saved.",
|
|
107
108
|
type: "success"
|
|
108
109
|
}), z(!1), await q();
|
|
109
110
|
} catch (e) {
|
|
110
111
|
let t = e?.response?.data?.message ?? e?.message ?? "Failed to save brand";
|
|
111
|
-
R(t),
|
|
112
|
+
R(t), w({
|
|
112
113
|
message: t,
|
|
113
114
|
type: "error"
|
|
114
115
|
});
|
|
115
116
|
}
|
|
116
117
|
}
|
|
117
118
|
let $ = H ? N : N.filter((e) => e.isActive !== !1);
|
|
118
|
-
return /* @__PURE__ */
|
|
119
|
+
return /* @__PURE__ */ f(p, { children: [/* @__PURE__ */ d(ie, {}), /* @__PURE__ */ f(l, {
|
|
119
120
|
perm: "view.manage.productManagement.brand",
|
|
120
|
-
children: [/* @__PURE__ */
|
|
121
|
+
children: [/* @__PURE__ */ f(ne, {
|
|
121
122
|
title: "Brands",
|
|
122
123
|
subtitle: "The manufacturer or supplier of each product.",
|
|
123
124
|
chips: ["Catalog"],
|
|
124
|
-
actions: /* @__PURE__ */
|
|
125
|
+
actions: /* @__PURE__ */ f(v, {
|
|
125
126
|
direction: "row",
|
|
126
127
|
spacing: 1,
|
|
127
|
-
children: [/* @__PURE__ */
|
|
128
|
+
children: [/* @__PURE__ */ d(m, {
|
|
128
129
|
variant: "outlined",
|
|
129
|
-
startIcon: /* @__PURE__ */
|
|
130
|
+
startIcon: /* @__PURE__ */ d(E, {}),
|
|
130
131
|
onClick: () => void q(),
|
|
131
132
|
children: "Refresh"
|
|
132
|
-
}), j ? /* @__PURE__ */
|
|
133
|
+
}), j ? /* @__PURE__ */ d(m, {
|
|
133
134
|
variant: "contained",
|
|
134
|
-
startIcon: /* @__PURE__ */
|
|
135
|
+
startIcon: /* @__PURE__ */ d(T, {}),
|
|
135
136
|
onClick: J,
|
|
136
137
|
children: "New Brand"
|
|
137
138
|
}) : null]
|
|
138
139
|
}),
|
|
139
|
-
children: [L ? /* @__PURE__ */
|
|
140
|
+
children: [L ? /* @__PURE__ */ d(oe, {
|
|
140
141
|
severity: "error",
|
|
141
142
|
sx: { mb: 2 },
|
|
142
143
|
children: L
|
|
143
|
-
}) : null, /* @__PURE__ */
|
|
144
|
+
}) : null, /* @__PURE__ */ d(r, {
|
|
144
145
|
eyebrow: "Master data",
|
|
145
146
|
title: "Brands",
|
|
146
147
|
subtitle: F ? "Loading…" : `${$.length} ${$.length === 1 ? "brand" : "brands"}`,
|
|
147
|
-
actions: /* @__PURE__ */
|
|
148
|
-
control: /* @__PURE__ */
|
|
148
|
+
actions: /* @__PURE__ */ d(g, {
|
|
149
|
+
control: /* @__PURE__ */ d(O, {
|
|
149
150
|
checked: H,
|
|
150
151
|
onChange: (e) => ve(e.target.checked)
|
|
151
152
|
}),
|
|
152
|
-
label: /* @__PURE__ */
|
|
153
|
+
label: /* @__PURE__ */ d(C, {
|
|
153
154
|
variant: "body2",
|
|
154
155
|
sx: { fontWeight: 600 },
|
|
155
156
|
children: "Show inactive"
|
|
@@ -160,35 +161,35 @@ function j() {
|
|
|
160
161
|
ml: 0
|
|
161
162
|
}
|
|
162
163
|
}),
|
|
163
|
-
children: /* @__PURE__ */
|
|
164
|
-
/* @__PURE__ */
|
|
165
|
-
/* @__PURE__ */
|
|
166
|
-
/* @__PURE__ */
|
|
167
|
-
/* @__PURE__ */
|
|
168
|
-
/* @__PURE__ */
|
|
164
|
+
children: /* @__PURE__ */ f(a, { children: [/* @__PURE__ */ d(pe, { children: /* @__PURE__ */ f(x, { children: [
|
|
165
|
+
/* @__PURE__ */ d(b, { children: "Name" }),
|
|
166
|
+
/* @__PURE__ */ d(b, { children: "Manufacturer Code" }),
|
|
167
|
+
/* @__PURE__ */ d(b, { children: "Contact" }),
|
|
168
|
+
/* @__PURE__ */ d(b, { children: "Status" }),
|
|
169
|
+
/* @__PURE__ */ d(b, {
|
|
169
170
|
align: "right",
|
|
170
171
|
children: "Action"
|
|
171
172
|
})
|
|
172
|
-
] }) }), /* @__PURE__ */
|
|
173
|
+
] }) }), /* @__PURE__ */ d(y, { children: F ? Array.from({ length: 4 }).map((e, t) => /* @__PURE__ */ d(x, { children: Array.from({ length: 5 }).map((e, t) => /* @__PURE__ */ d(b, { children: /* @__PURE__ */ d(_, { height: 22 }) }, t)) }, t)) : $.length === 0 ? /* @__PURE__ */ d(ee, {
|
|
173
174
|
colSpan: 5,
|
|
174
|
-
icon:
|
|
175
|
+
icon: D,
|
|
175
176
|
title: N.length === 0 ? "No brands yet" : "No active brands",
|
|
176
177
|
hint: N.length === 0 ? "Add manufacturers so you can link them to your products." : "Turn on “Show inactive” to see deactivated brands.",
|
|
177
|
-
action: N.length === 0 && j ? /* @__PURE__ */
|
|
178
|
+
action: N.length === 0 && j ? /* @__PURE__ */ d(m, {
|
|
178
179
|
variant: "contained",
|
|
179
180
|
size: "small",
|
|
180
|
-
startIcon: /* @__PURE__ */
|
|
181
|
+
startIcon: /* @__PURE__ */ d(T, {}),
|
|
181
182
|
onClick: J,
|
|
182
183
|
children: "Create first brand"
|
|
183
184
|
}) : null
|
|
184
185
|
}) : $.map((e) => {
|
|
185
186
|
let { phone: t, email: n } = k(e.contactInfo);
|
|
186
|
-
return /* @__PURE__ */
|
|
187
|
+
return /* @__PURE__ */ f(x, {
|
|
187
188
|
hover: !0,
|
|
188
189
|
children: [
|
|
189
|
-
/* @__PURE__ */
|
|
190
|
+
/* @__PURE__ */ d(b, {
|
|
190
191
|
sx: { maxWidth: 240 },
|
|
191
|
-
children: /* @__PURE__ */
|
|
192
|
+
children: /* @__PURE__ */ d(C, {
|
|
192
193
|
variant: "body2",
|
|
193
194
|
sx: {
|
|
194
195
|
fontWeight: 700,
|
|
@@ -197,9 +198,9 @@ function j() {
|
|
|
197
198
|
children: e.name
|
|
198
199
|
})
|
|
199
200
|
}),
|
|
200
|
-
/* @__PURE__ */
|
|
201
|
+
/* @__PURE__ */ d(b, {
|
|
201
202
|
sx: { maxWidth: 160 },
|
|
202
|
-
children: /* @__PURE__ */
|
|
203
|
+
children: /* @__PURE__ */ d(p, {
|
|
203
204
|
component: "span",
|
|
204
205
|
sx: {
|
|
205
206
|
display: "inline-block",
|
|
@@ -216,23 +217,23 @@ function j() {
|
|
|
216
217
|
children: e.manufacturerCode
|
|
217
218
|
})
|
|
218
219
|
}),
|
|
219
|
-
/* @__PURE__ */
|
|
220
|
+
/* @__PURE__ */ d(b, { children: t || n ? /* @__PURE__ */ f(v, {
|
|
220
221
|
spacing: .25,
|
|
221
|
-
children: [t ? /* @__PURE__ */
|
|
222
|
+
children: [t ? /* @__PURE__ */ d(C, {
|
|
222
223
|
variant: "caption",
|
|
223
224
|
sx: { fontWeight: 600 },
|
|
224
225
|
children: t
|
|
225
|
-
}) : null, n ? /* @__PURE__ */
|
|
226
|
+
}) : null, n ? /* @__PURE__ */ d(C, {
|
|
226
227
|
variant: "caption",
|
|
227
228
|
color: "text.secondary",
|
|
228
229
|
children: n
|
|
229
230
|
}) : null]
|
|
230
|
-
}) : /* @__PURE__ */
|
|
231
|
+
}) : /* @__PURE__ */ d(C, {
|
|
231
232
|
variant: "caption",
|
|
232
233
|
color: "text.disabled",
|
|
233
234
|
children: "—"
|
|
234
235
|
}) }),
|
|
235
|
-
/* @__PURE__ */
|
|
236
|
+
/* @__PURE__ */ d(b, { children: /* @__PURE__ */ d(ce, {
|
|
236
237
|
size: "small",
|
|
237
238
|
label: e.isActive ? "Active" : "Inactive",
|
|
238
239
|
color: e.isActive ? "success" : "default",
|
|
@@ -243,9 +244,9 @@ function j() {
|
|
|
243
244
|
height: 22
|
|
244
245
|
}
|
|
245
246
|
}) }),
|
|
246
|
-
/* @__PURE__ */
|
|
247
|
+
/* @__PURE__ */ d(b, {
|
|
247
248
|
align: "right",
|
|
248
|
-
children: j ? /* @__PURE__ */
|
|
249
|
+
children: j ? /* @__PURE__ */ d(m, {
|
|
249
250
|
size: "small",
|
|
250
251
|
variant: "outlined",
|
|
251
252
|
onClick: () => ye(e),
|
|
@@ -256,20 +257,20 @@ function j() {
|
|
|
256
257
|
}, e.id);
|
|
257
258
|
}) })] })
|
|
258
259
|
})]
|
|
259
|
-
}), /* @__PURE__ */
|
|
260
|
+
}), /* @__PURE__ */ f(le, {
|
|
260
261
|
open: _e,
|
|
261
262
|
onClose: () => z(!1),
|
|
262
263
|
fullWidth: !0,
|
|
263
264
|
maxWidth: "sm",
|
|
264
265
|
children: [
|
|
265
|
-
/* @__PURE__ */
|
|
266
|
-
/* @__PURE__ */
|
|
266
|
+
/* @__PURE__ */ d(de, { children: B ? "Edit Brand" : "New Brand" }),
|
|
267
|
+
/* @__PURE__ */ d(h, {
|
|
267
268
|
dividers: !0,
|
|
268
|
-
children: /* @__PURE__ */
|
|
269
|
+
children: /* @__PURE__ */ f(v, {
|
|
269
270
|
spacing: 2,
|
|
270
271
|
sx: { pt: 1 },
|
|
271
272
|
children: [
|
|
272
|
-
/* @__PURE__ */
|
|
273
|
+
/* @__PURE__ */ d(S, {
|
|
273
274
|
required: !0,
|
|
274
275
|
label: "Name",
|
|
275
276
|
size: "small",
|
|
@@ -287,13 +288,13 @@ function j() {
|
|
|
287
288
|
onBlur: G.onBlur("name"),
|
|
288
289
|
error: G.show("name") && !!Z.name,
|
|
289
290
|
FormHelperTextProps: { component: "div" },
|
|
290
|
-
helperText: /* @__PURE__ */
|
|
291
|
+
helperText: /* @__PURE__ */ d(i, {
|
|
291
292
|
message: G.show("name") ? Z.name : "",
|
|
292
293
|
value: U.name,
|
|
293
294
|
max: 255
|
|
294
295
|
})
|
|
295
296
|
}),
|
|
296
|
-
/* @__PURE__ */
|
|
297
|
+
/* @__PURE__ */ d(S, {
|
|
297
298
|
required: !0,
|
|
298
299
|
label: "Manufacturer code",
|
|
299
300
|
size: "small",
|
|
@@ -307,13 +308,13 @@ function j() {
|
|
|
307
308
|
onBlur: G.onBlur("manufacturerCode"),
|
|
308
309
|
error: G.show("manufacturerCode") && !!Z.manufacturerCode,
|
|
309
310
|
FormHelperTextProps: { component: "div" },
|
|
310
|
-
helperText: /* @__PURE__ */
|
|
311
|
+
helperText: /* @__PURE__ */ d(i, {
|
|
311
312
|
message: G.show("manufacturerCode") && Z.manufacturerCode ? Z.manufacturerCode : "Auto-generated from the name as initials. Edit if needed to make it unique.",
|
|
312
313
|
value: U.manufacturerCode,
|
|
313
314
|
max: 100
|
|
314
315
|
})
|
|
315
316
|
}),
|
|
316
|
-
/* @__PURE__ */
|
|
317
|
+
/* @__PURE__ */ d(S, {
|
|
317
318
|
label: "Contact Number",
|
|
318
319
|
size: "small",
|
|
319
320
|
fullWidth: !0,
|
|
@@ -327,9 +328,9 @@ function j() {
|
|
|
327
328
|
onBlur: G.onBlur("contactPhone"),
|
|
328
329
|
error: G.show("contactPhone") && !!Z.contactPhone,
|
|
329
330
|
helperText: G.show("contactPhone") && Z.contactPhone ? Z.contactPhone : M ? `Format for ${M.name}: ${M.phoneCode} followed by ${M.phoneMin}${M.phoneMin === M.phoneMax ? "" : `–${M.phoneMax}`} digits.` : "Local number, digits only.",
|
|
330
|
-
InputProps: M ? { startAdornment: /* @__PURE__ */
|
|
331
|
+
InputProps: M ? { startAdornment: /* @__PURE__ */ d(fe, {
|
|
331
332
|
position: "start",
|
|
332
|
-
children: /* @__PURE__ */
|
|
333
|
+
children: /* @__PURE__ */ d(p, {
|
|
333
334
|
component: "span",
|
|
334
335
|
sx: {
|
|
335
336
|
fontWeight: 700,
|
|
@@ -339,7 +340,7 @@ function j() {
|
|
|
339
340
|
})
|
|
340
341
|
}) } : void 0
|
|
341
342
|
}),
|
|
342
|
-
/* @__PURE__ */
|
|
343
|
+
/* @__PURE__ */ d(S, {
|
|
343
344
|
label: "Email",
|
|
344
345
|
size: "small",
|
|
345
346
|
fullWidth: !0,
|
|
@@ -354,8 +355,8 @@ function j() {
|
|
|
354
355
|
error: G.show("contactEmail") && !!Z.contactEmail,
|
|
355
356
|
helperText: G.show("contactEmail") ? Z.contactEmail : ""
|
|
356
357
|
}),
|
|
357
|
-
/* @__PURE__ */
|
|
358
|
-
control: /* @__PURE__ */
|
|
358
|
+
/* @__PURE__ */ d(g, {
|
|
359
|
+
control: /* @__PURE__ */ d(se, {
|
|
359
360
|
checked: U.isActive,
|
|
360
361
|
onChange: (e) => W({
|
|
361
362
|
...U,
|
|
@@ -367,10 +368,10 @@ function j() {
|
|
|
367
368
|
]
|
|
368
369
|
})
|
|
369
370
|
}),
|
|
370
|
-
/* @__PURE__ */
|
|
371
|
+
/* @__PURE__ */ f(ue, { children: [/* @__PURE__ */ d(m, {
|
|
371
372
|
onClick: () => z(!1),
|
|
372
373
|
children: "Cancel"
|
|
373
|
-
}), /* @__PURE__ */
|
|
374
|
+
}), /* @__PURE__ */ d(m, {
|
|
374
375
|
variant: "contained",
|
|
375
376
|
disabled: !Q,
|
|
376
377
|
onClick: () => void xe(),
|
|
@@ -383,4 +384,4 @@ function j() {
|
|
|
383
384
|
//#endregion
|
|
384
385
|
export { j as default };
|
|
385
386
|
|
|
386
|
-
//# sourceMappingURL=BrandsPage-
|
|
387
|
+
//# sourceMappingURL=BrandsPage-BE3kn-8b.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BrandsPage-NSvaMXWg.js","names":[],"sources":["../src/views/BrandsPage.jsx"],"sourcesContent":["import { useState } from 'react';\nimport { v4 as uuidv4 } from 'uuid';\nimport {\n Alert,\n Box,\n Button,\n Checkbox,\n Chip,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n FormControlLabel,\n InputAdornment,\n Skeleton,\n Stack,\n TableBody,\n TableCell,\n TableHead,\n TableRow,\n TextField,\n Typography,\n} from '@mui/material';\nimport AddRoundedIcon from '@mui/icons-material/AddRounded';\nimport RefreshRoundedIcon from '@mui/icons-material/RefreshRounded';\nimport SellRoundedIcon from '@mui/icons-material/SellRounded';\nimport { showToast } from '@/common/toaster/toaster';\nimport CustomSwitch from '@/views/custom-components/CustomSwitch';\nimport PmPageShell from '@pm/components/PmPageShell';\nimport PmNav from '@pm/components/PmNav';\nimport PmGuard from '@pm/components/PmGuard';\nimport { usePermissionedEffect, usePmPermissions } from '@pm/utils/permissions';\nimport { PmEmptyRow, PmFieldHelp, PmTable, PmTableCard } from '@pm/components/PmTable';\nimport { getBrands, upsertBrand } from '@pm/services/pmApi';\nimport { isClean, validateEmail, validateRequired } from '@pm/utils/validation';\nimport { findCountry, validatePhoneForCountry } from '@/common/constants/countries';\nimport { usePmSettings } from '@pm/utils/settingsStore';\nimport { useFieldErrors } from '@pm/utils/useFieldErrors';\n\n// Backend stores contact_info as a JSON-encoded string. We keep the discrete\n// fields here so the UI is form-friendly, and only ever round-trip the JSON.\nfunction parseContactInfo(raw) {\n if (!raw) return { phone: '', email: '' };\n try {\n const obj = JSON.parse(raw);\n return {\n phone: typeof obj?.phone === 'string' ? obj.phone : '',\n email: typeof obj?.email === 'string' ? obj.email : '',\n };\n } catch {\n return { phone: '', email: '' };\n }\n}\n\nfunction serializeContactInfo({ phone, email }) {\n const out = {};\n if (phone?.trim()) out.phone = phone.trim();\n if (email?.trim()) out.email = email.trim();\n return Object.keys(out).length ? JSON.stringify(out) : null;\n}\n\nexport default function BrandsPage() {\n const perms = usePmPermissions();\n const canWrite = perms.has('update.manage.productManagement.brand');\n const settings = usePmSettings();\n const country = findCountry(settings?.countryCode);\n const [items, setItems] = useState([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState('');\n const [openDialog, setOpenDialog] = useState(false);\n const [editing, setEditing] = useState(null);\n // Default to active-only; the toggle above the table reveals inactive rows.\n const [showInactive, setShowInactive] = useState(false);\n const [form, setForm] = useState(emptyForm());\n const fieldErrors = useFieldErrors();\n\n function emptyForm() {\n return {\n id: '',\n name: '',\n manufacturerCode: '',\n contactPhone: '',\n contactEmail: '',\n isActive: true,\n };\n }\n\n async function load() {\n setLoading(true);\n setError('');\n try {\n const data = await getBrands(undefined, true);\n setItems(data);\n } catch (err) {\n const message = err?.response?.data?.message ?? err?.message ?? 'Failed to load brands';\n setError(message);\n showToast({ message, type: 'error' });\n } finally {\n setLoading(false);\n }\n }\n\n usePermissionedEffect('view.manage.productManagement.brand', () => {\n void load();\n }, []);\n\n function openCreate() {\n setEditing(null);\n setForm({ ...emptyForm(), id: uuidv4() });\n fieldErrors.reset();\n setError('');\n setOpenDialog(true);\n }\n\n function openEdit(item) {\n const { phone, email } = parseContactInfo(item.contactInfo);\n setEditing(item);\n fieldErrors.reset();\n setError('');\n setForm({\n id: item.id,\n name: item.name ?? '',\n manufacturerCode: item.manufacturerCode ?? '',\n contactPhone: phone,\n contactEmail: email,\n isActive: item.isActive !== false,\n });\n setOpenDialog(true);\n }\n\n const mfrCodeBase = validateRequired(form.manufacturerCode, 'Manufacturer code');\n const mfrNorm = form.manufacturerCode.trim().toUpperCase();\n const mfrClash = !mfrCodeBase\n && mfrNorm\n && items.some((b) => b.id !== form.id && (b.manufacturerCode || '').toUpperCase() === mfrNorm);\n const formErrors = {\n name: validateRequired(form.name, 'Name'),\n manufacturerCode: mfrCodeBase || (mfrClash ? 'Code is already in use — edit it manually to make it unique.' : ''),\n contactPhone: validatePhoneForCountry(form.contactPhone, country),\n contactEmail: validateEmail(form.contactEmail),\n };\n const formIsValid = isClean(formErrors);\n\n async function save() {\n if (!formIsValid) {\n fieldErrors.markAllTouched();\n setError('Please fix the highlighted fields.');\n return;\n }\n try {\n await upsertBrand({\n id: form.id,\n name: form.name.trim(),\n manufacturerCode: form.manufacturerCode.trim().toUpperCase(),\n contactInfo: serializeContactInfo({\n phone: form.contactPhone,\n email: form.contactEmail,\n }),\n isActive: form.isActive,\n });\n showToast({ message: 'Brand saved.', type: 'success' });\n setOpenDialog(false);\n await load();\n } catch (err) {\n const message = err?.response?.data?.message ?? err?.message ?? 'Failed to save brand';\n setError(message);\n showToast({ message, type: 'error' });\n }\n }\n\n const visible = showInactive ? items : items.filter((b) => b.isActive !== false);\n\n return (\n <Box>\n <PmNav />\n <PmGuard perm={'view.manage.productManagement.brand'}>\n <PmPageShell\n title=\"Brands\"\n subtitle=\"The manufacturer or supplier of each product.\"\n chips={['Catalog']}\n actions={\n <Stack direction=\"row\" spacing={1}>\n <Button variant=\"outlined\" startIcon={<RefreshRoundedIcon />} onClick={() => void load()}>Refresh</Button>\n {canWrite ? (\n <Button variant=\"contained\" startIcon={<AddRoundedIcon />} onClick={openCreate}>New Brand</Button>\n ) : null}\n </Stack>\n }\n >\n {error ? <Alert severity=\"error\" sx={{ mb: 2 }}>{error}</Alert> : null}\n\n <PmTableCard\n eyebrow=\"Master data\"\n title=\"Brands\"\n subtitle={loading ? 'Loading…' : `${visible.length} ${visible.length === 1 ? 'brand' : 'brands'}`}\n actions={\n <FormControlLabel\n control={<CustomSwitch checked={showInactive}\n onChange={(e) => setShowInactive(e.target.checked)} />}\n label={<Typography variant=\"body2\" sx={{ fontWeight: 600 }}>Show inactive</Typography>}\n labelPlacement=\"start\"\n sx={{ mr: 0.5, ml: 0 }}\n />\n }\n >\n <PmTable>\n <TableHead>\n <TableRow>\n <TableCell>Name</TableCell>\n <TableCell>Manufacturer Code</TableCell>\n <TableCell>Contact</TableCell>\n <TableCell>Status</TableCell>\n <TableCell align=\"right\">Action</TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {loading ? (\n Array.from({ length: 4 }).map((_, i) => (\n <TableRow key={i}>\n {Array.from({ length: 5 }).map((__, j) => (\n <TableCell key={j}><Skeleton height={22} /></TableCell>\n ))}\n </TableRow>\n ))\n ) : visible.length === 0 ? (\n <PmEmptyRow\n colSpan={5}\n icon={SellRoundedIcon}\n title={items.length === 0 ? 'No brands yet' : 'No active brands'}\n hint={items.length === 0\n ? 'Add manufacturers so you can link them to your products.'\n : 'Turn on “Show inactive” to see deactivated brands.'}\n action={items.length === 0 && canWrite ? (\n <Button variant=\"contained\" size=\"small\" startIcon={<AddRoundedIcon />} onClick={openCreate}>\n Create first brand\n </Button>\n ) : null}\n />\n ) : visible.map((b) => {\n const { phone, email } = parseContactInfo(b.contactInfo);\n return (\n <TableRow key={b.id} hover>\n <TableCell sx={{ maxWidth: 240 }}>\n <Typography variant=\"body2\" sx={{ fontWeight: 700, wordBreak: 'break-word' }}>{b.name}</Typography>\n </TableCell>\n <TableCell sx={{ maxWidth: 160 }}>\n <Box component=\"span\" sx={{\n display: 'inline-block', px: 0.85, py: 0.25, borderRadius: 1,\n bgcolor: 'grey.100', fontFamily: 'monospace', fontSize: '0.72rem', fontWeight: 800,\n maxWidth: '100%', wordBreak: 'break-all',\n }}>\n {b.manufacturerCode}\n </Box>\n </TableCell>\n <TableCell>\n {phone || email ? (\n <Stack spacing={0.25}>\n {phone ? <Typography variant=\"caption\" sx={{ fontWeight: 600 }}>{phone}</Typography> : null}\n {email ? <Typography variant=\"caption\" color=\"text.secondary\">{email}</Typography> : null}\n </Stack>\n ) : <Typography variant=\"caption\" color=\"text.disabled\">—</Typography>}\n </TableCell>\n <TableCell>\n <Chip\n size=\"small\"\n label={b.isActive ? 'Active' : 'Inactive'}\n color={b.isActive ? 'success' : 'default'}\n variant={b.isActive ? 'filled' : 'outlined'}\n sx={{ fontWeight: 700, borderRadius: 1.5, height: 22 }}\n />\n </TableCell>\n <TableCell align=\"right\">\n {canWrite ? (\n <Button size=\"small\" variant=\"outlined\" onClick={() => openEdit(b)}>Edit</Button>\n ) : null}\n </TableCell>\n </TableRow>\n );\n })}\n </TableBody>\n </PmTable>\n </PmTableCard>\n </PmPageShell>\n\n <Dialog open={openDialog} onClose={() => setOpenDialog(false)} fullWidth maxWidth=\"sm\">\n <DialogTitle>{editing ? 'Edit Brand' : 'New Brand'}</DialogTitle>\n <DialogContent dividers>\n <Stack spacing={2} sx={{ pt: 1 }}>\n <TextField\n required\n label=\"Name\" size=\"small\" fullWidth\n value={form.name}\n inputProps={{ maxLength: 255 }}\n onChange={(e) => {\n const nextName = e.target.value;\n // Auto-derive manufacturer code from initials of every word — but\n // only on create (when editing an existing brand we never overwrite\n // a code the user has already curated).\n const initialsFromName = nextName\n .split(/\\s+/)\n .filter(Boolean)\n .map((w) => w[0])\n .join('')\n .toUpperCase();\n setForm((f) => ({\n ...f,\n name: nextName,\n manufacturerCode: editing ? f.manufacturerCode : initialsFromName,\n }));\n }}\n onBlur={fieldErrors.onBlur('name')}\n error={fieldErrors.show('name') && !!formErrors.name}\n FormHelperTextProps={{ component: 'div' }}\n helperText={<PmFieldHelp message={fieldErrors.show('name') ? formErrors.name : ''} value={form.name} max={255} />}\n />\n <TextField\n required\n label=\"Manufacturer code\" size=\"small\" fullWidth\n value={form.manufacturerCode}\n inputProps={{ maxLength: 100 }}\n onChange={(e) => setForm({ ...form, manufacturerCode: e.target.value.toUpperCase() })}\n onBlur={fieldErrors.onBlur('manufacturerCode')}\n error={fieldErrors.show('manufacturerCode') && !!formErrors.manufacturerCode}\n FormHelperTextProps={{ component: 'div' }}\n helperText={\n <PmFieldHelp\n message={fieldErrors.show('manufacturerCode') && formErrors.manufacturerCode\n ? formErrors.manufacturerCode\n : 'Auto-generated from the name as initials. Edit if needed to make it unique.'}\n value={form.manufacturerCode}\n max={100}\n />\n }\n />\n <TextField\n label=\"Contact Number\"\n size=\"small\"\n fullWidth\n type=\"tel\"\n placeholder={country\n ? (country.phoneMin === country.phoneMax\n ? `${country.phoneMin}-digit local number`\n : `${country.phoneMin}–${country.phoneMax} digit local number`)\n : 'Local number'}\n value={form.contactPhone}\n // Keep only digits and spaces — the dial code lives in the\n // adornment, not in the value.\n onChange={(e) => setForm({ ...form, contactPhone: e.target.value.replace(/[^\\d\\s]/g, '') })}\n onBlur={fieldErrors.onBlur('contactPhone')}\n error={fieldErrors.show('contactPhone') && !!formErrors.contactPhone}\n helperText={\n fieldErrors.show('contactPhone') && formErrors.contactPhone\n ? formErrors.contactPhone\n : country\n ? `Format for ${country.name}: ${country.phoneCode} followed by ${country.phoneMin}${country.phoneMin === country.phoneMax ? '' : `–${country.phoneMax}`} digits.`\n : 'Local number, digits only.'\n }\n InputProps={country ? {\n startAdornment: (\n <InputAdornment position=\"start\">\n <Box component=\"span\" sx={{ fontWeight: 700, color: 'text.secondary' }}>{country.phoneCode}</Box>\n </InputAdornment>\n ),\n } : undefined}\n />\n <TextField\n label=\"Email\"\n size=\"small\"\n fullWidth\n type=\"email\"\n placeholder=\"e.g. contact@manufacturer.example\"\n value={form.contactEmail}\n onChange={(e) => setForm({ ...form, contactEmail: e.target.value })}\n onBlur={fieldErrors.onBlur('contactEmail')}\n error={fieldErrors.show('contactEmail') && !!formErrors.contactEmail}\n helperText={fieldErrors.show('contactEmail') ? formErrors.contactEmail : ''}\n />\n <FormControlLabel\n control={<Checkbox checked={form.isActive}\n onChange={(e) => setForm({ ...form, isActive: e.target.checked })} />}\n label=\"Active\" />\n </Stack>\n </DialogContent>\n <DialogActions>\n <Button onClick={() => setOpenDialog(false)}>Cancel</Button>\n <Button variant=\"contained\" disabled={!formIsValid} onClick={() => void save()}>Save</Button>\n </DialogActions>\n </Dialog>\n </PmGuard>\n </Box>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"BrandsPage-BE3kn-8b.js","names":[],"sources":["../src/views/BrandsPage.jsx"],"sourcesContent":["import { useState } from 'react';\nimport { v4 as uuidv4 } from 'uuid';\nimport {\n Alert,\n Box,\n Button,\n Checkbox,\n Chip,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n FormControlLabel,\n InputAdornment,\n Skeleton,\n Stack,\n TableBody,\n TableCell,\n TableHead,\n TableRow,\n TextField,\n Typography,\n} from '@mui/material';\nimport AddRoundedIcon from '@mui/icons-material/AddRounded';\nimport RefreshRoundedIcon from '@mui/icons-material/RefreshRounded';\nimport SellRoundedIcon from '@mui/icons-material/SellRounded';\nimport { showToast } from '@/common/toaster/toaster';\nimport CustomSwitch from '@/views/custom-components/CustomSwitch';\nimport PmPageShell from '@pm/components/PmPageShell';\nimport PmNav from '@pm/components/PmNav';\nimport PmGuard from '@pm/components/PmGuard';\nimport { usePermissionedEffect, usePmPermissions } from '@pm/utils/permissions';\nimport { PmEmptyRow, PmFieldHelp, PmTable, PmTableCard } from '@pm/components/PmTable';\nimport { getBrands, upsertBrand } from '@pm/services/pmApi';\nimport { isClean, validateEmail, validateRequired } from '@pm/utils/validation';\nimport { findCountry, validatePhoneForCountry } from '@/common/constants/countries';\nimport { usePmSettings } from '@pm/utils/settingsStore';\nimport { useFieldErrors } from '@pm/utils/useFieldErrors';\n\n// Backend stores contact_info as a JSON-encoded string. We keep the discrete\n// fields here so the UI is form-friendly, and only ever round-trip the JSON.\nfunction parseContactInfo(raw) {\n if (!raw) return { phone: '', email: '' };\n try {\n const obj = JSON.parse(raw);\n return {\n phone: typeof obj?.phone === 'string' ? obj.phone : '',\n email: typeof obj?.email === 'string' ? obj.email : '',\n };\n } catch {\n return { phone: '', email: '' };\n }\n}\n\nfunction serializeContactInfo({ phone, email }) {\n const out = {};\n if (phone?.trim()) out.phone = phone.trim();\n if (email?.trim()) out.email = email.trim();\n return Object.keys(out).length ? JSON.stringify(out) : null;\n}\n\nexport default function BrandsPage() {\n const perms = usePmPermissions();\n const canWrite = perms.has('update.manage.productManagement.brand');\n const settings = usePmSettings();\n const country = findCountry(settings?.countryCode);\n const [items, setItems] = useState([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState('');\n const [openDialog, setOpenDialog] = useState(false);\n const [editing, setEditing] = useState(null);\n // Default to active-only; the toggle above the table reveals inactive rows.\n const [showInactive, setShowInactive] = useState(false);\n const [form, setForm] = useState(emptyForm());\n const fieldErrors = useFieldErrors();\n\n function emptyForm() {\n return {\n id: '',\n name: '',\n manufacturerCode: '',\n contactPhone: '',\n contactEmail: '',\n isActive: true,\n };\n }\n\n async function load() {\n setLoading(true);\n setError('');\n try {\n const data = await getBrands(undefined, true);\n setItems(data);\n } catch (err) {\n const message = err?.response?.data?.message ?? err?.message ?? 'Failed to load brands';\n setError(message);\n showToast({ message, type: 'error' });\n } finally {\n setLoading(false);\n }\n }\n\n usePermissionedEffect('view.manage.productManagement.brand', () => {\n void load();\n }, []);\n\n function openCreate() {\n setEditing(null);\n setForm({ ...emptyForm(), id: uuidv4() });\n fieldErrors.reset();\n setError('');\n setOpenDialog(true);\n }\n\n function openEdit(item) {\n const { phone, email } = parseContactInfo(item.contactInfo);\n setEditing(item);\n fieldErrors.reset();\n setError('');\n setForm({\n id: item.id,\n name: item.name ?? '',\n manufacturerCode: item.manufacturerCode ?? '',\n contactPhone: phone,\n contactEmail: email,\n isActive: item.isActive !== false,\n });\n setOpenDialog(true);\n }\n\n const mfrCodeBase = validateRequired(form.manufacturerCode, 'Manufacturer code');\n const mfrNorm = form.manufacturerCode.trim().toUpperCase();\n const mfrClash = !mfrCodeBase\n && mfrNorm\n && items.some((b) => b.id !== form.id && (b.manufacturerCode || '').toUpperCase() === mfrNorm);\n const formErrors = {\n name: validateRequired(form.name, 'Name'),\n manufacturerCode: mfrCodeBase || (mfrClash ? 'Code is already in use — edit it manually to make it unique.' : ''),\n contactPhone: validatePhoneForCountry(form.contactPhone, country),\n contactEmail: validateEmail(form.contactEmail),\n };\n const formIsValid = isClean(formErrors);\n\n async function save() {\n if (!formIsValid) {\n fieldErrors.markAllTouched();\n setError('Please fix the highlighted fields.');\n return;\n }\n try {\n await upsertBrand({\n id: form.id,\n name: form.name.trim(),\n manufacturerCode: form.manufacturerCode.trim().toUpperCase(),\n contactInfo: serializeContactInfo({\n phone: form.contactPhone,\n email: form.contactEmail,\n }),\n isActive: form.isActive,\n });\n showToast({ message: 'Brand saved.', type: 'success' });\n setOpenDialog(false);\n await load();\n } catch (err) {\n const message = err?.response?.data?.message ?? err?.message ?? 'Failed to save brand';\n setError(message);\n showToast({ message, type: 'error' });\n }\n }\n\n const visible = showInactive ? items : items.filter((b) => b.isActive !== false);\n\n return (\n <Box>\n <PmNav />\n <PmGuard perm={'view.manage.productManagement.brand'}>\n <PmPageShell\n title=\"Brands\"\n subtitle=\"The manufacturer or supplier of each product.\"\n chips={['Catalog']}\n actions={\n <Stack direction=\"row\" spacing={1}>\n <Button variant=\"outlined\" startIcon={<RefreshRoundedIcon />} onClick={() => void load()}>Refresh</Button>\n {canWrite ? (\n <Button variant=\"contained\" startIcon={<AddRoundedIcon />} onClick={openCreate}>New Brand</Button>\n ) : null}\n </Stack>\n }\n >\n {error ? <Alert severity=\"error\" sx={{ mb: 2 }}>{error}</Alert> : null}\n\n <PmTableCard\n eyebrow=\"Master data\"\n title=\"Brands\"\n subtitle={loading ? 'Loading…' : `${visible.length} ${visible.length === 1 ? 'brand' : 'brands'}`}\n actions={\n <FormControlLabel\n control={<CustomSwitch checked={showInactive}\n onChange={(e) => setShowInactive(e.target.checked)} />}\n label={<Typography variant=\"body2\" sx={{ fontWeight: 600 }}>Show inactive</Typography>}\n labelPlacement=\"start\"\n sx={{ mr: 0.5, ml: 0 }}\n />\n }\n >\n <PmTable>\n <TableHead>\n <TableRow>\n <TableCell>Name</TableCell>\n <TableCell>Manufacturer Code</TableCell>\n <TableCell>Contact</TableCell>\n <TableCell>Status</TableCell>\n <TableCell align=\"right\">Action</TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {loading ? (\n Array.from({ length: 4 }).map((_, i) => (\n <TableRow key={i}>\n {Array.from({ length: 5 }).map((__, j) => (\n <TableCell key={j}><Skeleton height={22} /></TableCell>\n ))}\n </TableRow>\n ))\n ) : visible.length === 0 ? (\n <PmEmptyRow\n colSpan={5}\n icon={SellRoundedIcon}\n title={items.length === 0 ? 'No brands yet' : 'No active brands'}\n hint={items.length === 0\n ? 'Add manufacturers so you can link them to your products.'\n : 'Turn on “Show inactive” to see deactivated brands.'}\n action={items.length === 0 && canWrite ? (\n <Button variant=\"contained\" size=\"small\" startIcon={<AddRoundedIcon />} onClick={openCreate}>\n Create first brand\n </Button>\n ) : null}\n />\n ) : visible.map((b) => {\n const { phone, email } = parseContactInfo(b.contactInfo);\n return (\n <TableRow key={b.id} hover>\n <TableCell sx={{ maxWidth: 240 }}>\n <Typography variant=\"body2\" sx={{ fontWeight: 700, wordBreak: 'break-word' }}>{b.name}</Typography>\n </TableCell>\n <TableCell sx={{ maxWidth: 160 }}>\n <Box component=\"span\" sx={{\n display: 'inline-block', px: 0.85, py: 0.25, borderRadius: 1,\n bgcolor: 'grey.100', fontFamily: 'monospace', fontSize: '0.72rem', fontWeight: 800,\n maxWidth: '100%', wordBreak: 'break-all',\n }}>\n {b.manufacturerCode}\n </Box>\n </TableCell>\n <TableCell>\n {phone || email ? (\n <Stack spacing={0.25}>\n {phone ? <Typography variant=\"caption\" sx={{ fontWeight: 600 }}>{phone}</Typography> : null}\n {email ? <Typography variant=\"caption\" color=\"text.secondary\">{email}</Typography> : null}\n </Stack>\n ) : <Typography variant=\"caption\" color=\"text.disabled\">—</Typography>}\n </TableCell>\n <TableCell>\n <Chip\n size=\"small\"\n label={b.isActive ? 'Active' : 'Inactive'}\n color={b.isActive ? 'success' : 'default'}\n variant={b.isActive ? 'filled' : 'outlined'}\n sx={{ fontWeight: 700, borderRadius: 1.5, height: 22 }}\n />\n </TableCell>\n <TableCell align=\"right\">\n {canWrite ? (\n <Button size=\"small\" variant=\"outlined\" onClick={() => openEdit(b)}>Edit</Button>\n ) : null}\n </TableCell>\n </TableRow>\n );\n })}\n </TableBody>\n </PmTable>\n </PmTableCard>\n </PmPageShell>\n\n <Dialog open={openDialog} onClose={() => setOpenDialog(false)} fullWidth maxWidth=\"sm\">\n <DialogTitle>{editing ? 'Edit Brand' : 'New Brand'}</DialogTitle>\n <DialogContent dividers>\n <Stack spacing={2} sx={{ pt: 1 }}>\n <TextField\n required\n label=\"Name\" size=\"small\" fullWidth\n value={form.name}\n inputProps={{ maxLength: 255 }}\n onChange={(e) => {\n const nextName = e.target.value;\n // Auto-derive manufacturer code from initials of every word — but\n // only on create (when editing an existing brand we never overwrite\n // a code the user has already curated).\n const initialsFromName = nextName\n .split(/\\s+/)\n .filter(Boolean)\n .map((w) => w[0])\n .join('')\n .toUpperCase();\n setForm((f) => ({\n ...f,\n name: nextName,\n manufacturerCode: editing ? f.manufacturerCode : initialsFromName,\n }));\n }}\n onBlur={fieldErrors.onBlur('name')}\n error={fieldErrors.show('name') && !!formErrors.name}\n FormHelperTextProps={{ component: 'div' }}\n helperText={<PmFieldHelp message={fieldErrors.show('name') ? formErrors.name : ''} value={form.name} max={255} />}\n />\n <TextField\n required\n label=\"Manufacturer code\" size=\"small\" fullWidth\n value={form.manufacturerCode}\n inputProps={{ maxLength: 100 }}\n onChange={(e) => setForm({ ...form, manufacturerCode: e.target.value.toUpperCase() })}\n onBlur={fieldErrors.onBlur('manufacturerCode')}\n error={fieldErrors.show('manufacturerCode') && !!formErrors.manufacturerCode}\n FormHelperTextProps={{ component: 'div' }}\n helperText={\n <PmFieldHelp\n message={fieldErrors.show('manufacturerCode') && formErrors.manufacturerCode\n ? formErrors.manufacturerCode\n : 'Auto-generated from the name as initials. Edit if needed to make it unique.'}\n value={form.manufacturerCode}\n max={100}\n />\n }\n />\n <TextField\n label=\"Contact Number\"\n size=\"small\"\n fullWidth\n type=\"tel\"\n placeholder={country\n ? (country.phoneMin === country.phoneMax\n ? `${country.phoneMin}-digit local number`\n : `${country.phoneMin}–${country.phoneMax} digit local number`)\n : 'Local number'}\n value={form.contactPhone}\n // Keep only digits and spaces — the dial code lives in the\n // adornment, not in the value.\n onChange={(e) => setForm({ ...form, contactPhone: e.target.value.replace(/[^\\d\\s]/g, '') })}\n onBlur={fieldErrors.onBlur('contactPhone')}\n error={fieldErrors.show('contactPhone') && !!formErrors.contactPhone}\n helperText={\n fieldErrors.show('contactPhone') && formErrors.contactPhone\n ? formErrors.contactPhone\n : country\n ? `Format for ${country.name}: ${country.phoneCode} followed by ${country.phoneMin}${country.phoneMin === country.phoneMax ? '' : `–${country.phoneMax}`} digits.`\n : 'Local number, digits only.'\n }\n InputProps={country ? {\n startAdornment: (\n <InputAdornment position=\"start\">\n <Box component=\"span\" sx={{ fontWeight: 700, color: 'text.secondary' }}>{country.phoneCode}</Box>\n </InputAdornment>\n ),\n } : undefined}\n />\n <TextField\n label=\"Email\"\n size=\"small\"\n fullWidth\n type=\"email\"\n placeholder=\"e.g. contact@manufacturer.example\"\n value={form.contactEmail}\n onChange={(e) => setForm({ ...form, contactEmail: e.target.value })}\n onBlur={fieldErrors.onBlur('contactEmail')}\n error={fieldErrors.show('contactEmail') && !!formErrors.contactEmail}\n helperText={fieldErrors.show('contactEmail') ? formErrors.contactEmail : ''}\n />\n <FormControlLabel\n control={<Checkbox checked={form.isActive}\n onChange={(e) => setForm({ ...form, isActive: e.target.checked })} />}\n label=\"Active\" />\n </Stack>\n </DialogContent>\n <DialogActions>\n <Button onClick={() => setOpenDialog(false)}>Cancel</Button>\n <Button variant=\"contained\" disabled={!formIsValid} onClick={() => void save()}>Save</Button>\n </DialogActions>\n </Dialog>\n </PmGuard>\n </Box>\n );\n}\n"],"mappings":"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"}
|