@argusoft/medplat-product-management 1.0.0

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.
Files changed (65) hide show
  1. package/dist/BrandsPage-DCMCVvDY.js +334 -0
  2. package/dist/BrandsPage-DCMCVvDY.js.map +1 -0
  3. package/dist/CategoriesPage-BpRhwfrc.js +284 -0
  4. package/dist/CategoriesPage-BpRhwfrc.js.map +1 -0
  5. package/dist/DashboardPage-BNKUQj46.js +436 -0
  6. package/dist/DashboardPage-BNKUQj46.js.map +1 -0
  7. package/dist/FacilityPicker-Coi8I3yE.js +79 -0
  8. package/dist/FacilityPicker-Coi8I3yE.js.map +1 -0
  9. package/dist/InventoryPage-BR6jOzg2.js +517 -0
  10. package/dist/InventoryPage-BR6jOzg2.js.map +1 -0
  11. package/dist/MemberProfileCard-DbHZCS5n.js +272 -0
  12. package/dist/MemberProfileCard-DbHZCS5n.js.map +1 -0
  13. package/dist/PaymentCreatePage-Ci3ERnby.js +487 -0
  14. package/dist/PaymentCreatePage-Ci3ERnby.js.map +1 -0
  15. package/dist/PaymentsPage-sdg902zX.js +157 -0
  16. package/dist/PaymentsPage-sdg902zX.js.map +1 -0
  17. package/dist/PickupCreatePage-CieMsgWV.js +310 -0
  18. package/dist/PickupCreatePage-CieMsgWV.js.map +1 -0
  19. package/dist/PickupsPage-Ci2Ll0Kn.js +566 -0
  20. package/dist/PickupsPage-Ci2Ll0Kn.js.map +1 -0
  21. package/dist/PmGuard-CjJBisaN.js +1195 -0
  22. package/dist/PmGuard-CjJBisaN.js.map +1 -0
  23. package/dist/PmTable-BuXZQZCU.js +302 -0
  24. package/dist/PmTable-BuXZQZCU.js.map +1 -0
  25. package/dist/ProductEditPage-DL8gy85Y.js +666 -0
  26. package/dist/ProductEditPage-DL8gy85Y.js.map +1 -0
  27. package/dist/ProductsPage-BANTKxLb.js +221 -0
  28. package/dist/ProductsPage-BANTKxLb.js.map +1 -0
  29. package/dist/PurchaseCreatePage-C3KMfBxJ.js +626 -0
  30. package/dist/PurchaseCreatePage-C3KMfBxJ.js.map +1 -0
  31. package/dist/PurchaseRequestDetailPage-C0GYFJDl.js +586 -0
  32. package/dist/PurchaseRequestDetailPage-C0GYFJDl.js.map +1 -0
  33. package/dist/PurchaseRequestsPage-DvFH_tWe.js +265 -0
  34. package/dist/PurchaseRequestsPage-DvFH_tWe.js.map +1 -0
  35. package/dist/PurchasesPage-BCvLvSp4.js +295 -0
  36. package/dist/PurchasesPage-BCvLvSp4.js.map +1 -0
  37. package/dist/SaleCreatePage-DpkQMoTq.js +548 -0
  38. package/dist/SaleCreatePage-DpkQMoTq.js.map +1 -0
  39. package/dist/SalesPage-DUwgkEO-.js +315 -0
  40. package/dist/SalesPage-DUwgkEO-.js.map +1 -0
  41. package/dist/SettingsPage-CusC0jqJ.js +710 -0
  42. package/dist/SettingsPage-CusC0jqJ.js.map +1 -0
  43. package/dist/StorageUnitsPage-BlC2AgrJ.js +469 -0
  44. package/dist/StorageUnitsPage-BlC2AgrJ.js.map +1 -0
  45. package/dist/TransactionsPage-DDaK4VyY.js +714 -0
  46. package/dist/TransactionsPage-DDaK4VyY.js.map +1 -0
  47. package/dist/TransferCreatePage-BxudLfhS.js +363 -0
  48. package/dist/TransferCreatePage-BxudLfhS.js.map +1 -0
  49. package/dist/TransfersPage-zgmt7teZ.js +480 -0
  50. package/dist/TransfersPage-zgmt7teZ.js.map +1 -0
  51. package/dist/VialsPage-CjqPfgpV.js +855 -0
  52. package/dist/VialsPage-CjqPfgpV.js.map +1 -0
  53. package/dist/constants-BrA_hfAI.js +254 -0
  54. package/dist/constants-BrA_hfAI.js.map +1 -0
  55. package/dist/currency-BDDCDgeE.js +169 -0
  56. package/dist/currency-BDDCDgeE.js.map +1 -0
  57. package/dist/format-UOyOu75i.js +52 -0
  58. package/dist/format-UOyOu75i.js.map +1 -0
  59. package/dist/index.js +45 -0
  60. package/dist/index.js.map +1 -0
  61. package/dist/useFieldErrors-hDG8ox_x.js +29 -0
  62. package/dist/useFieldErrors-hDG8ox_x.js.map +1 -0
  63. package/dist/validation-Ba7puFIO.js +109 -0
  64. package/dist/validation-Ba7puFIO.js.map +1 -0
  65. package/package.json +36 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SettingsPage-CusC0jqJ.js","names":[],"sources":["../src/views/SettingsPage.jsx"],"sourcesContent":["import { useEffect, useMemo, useState } from 'react';\nimport {\n Alert,\n Autocomplete,\n Box,\n Button,\n Card,\n CardContent,\n Grid,\n Stack,\n TextField,\n Typography,\n} from '@mui/material';\nimport CustomSwitch from '@/views/custom-components/CustomSwitch';\nimport { alpha } from '@mui/material/styles';\nimport SaveRoundedIcon from '@mui/icons-material/SaveRounded';\nimport RefreshRoundedIcon from '@mui/icons-material/RefreshRounded';\nimport PaymentsRoundedIcon from '@mui/icons-material/PaymentsRounded';\nimport PhoneIphoneRoundedIcon from '@mui/icons-material/PhoneIphoneRounded';\nimport { showToast } from '@/common/toaster/toaster';\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 { PmFormSection } from '@pm/components/PmTable';\nimport {\n getSettings,\n listDateColumns,\n listPublicTables,\n listTextColumns,\n listUuidColumns,\n upsertSettings,\n} from '@pm/services/pmApi';\nimport { loadPmSettings, updateLocalPmSettings } from '@pm/utils/settingsStore';\nimport { COUNTRIES, findCountry } from '@pm/utils/countries';\n\nfunction emptyForm() {\n return {\n memberTableName: '',\n memberIdColumn: '',\n memberIdentifierColumn: '',\n memberFamilyIdColumn: '',\n memberNameColumn: '',\n memberDobColumn: '',\n countryCode: 'IN',\n managePurchaseAmounts: true,\n manageSales: true,\n allowPersonalPurchase: true,\n requirePurchaseConfirmation: false,\n };\n}\n\nfunction applySettings(s) {\n return {\n memberTableName: s?.memberTableName ?? '',\n memberIdColumn: s?.memberIdColumn ?? '',\n memberIdentifierColumn: s?.memberIdentifierColumn ?? '',\n memberFamilyIdColumn: s?.memberFamilyIdColumn ?? '',\n memberNameColumn: s?.memberNameColumn ?? '',\n memberDobColumn: s?.memberDobColumn ?? '',\n countryCode: s?.countryCode ?? 'IN',\n managePurchaseAmounts: s?.managePurchaseAmounts !== false,\n manageSales: s?.manageSales !== false,\n allowPersonalPurchase: s?.allowPersonalPurchase !== false,\n requirePurchaseConfirmation: s?.requirePurchaseConfirmation === true,\n };\n}\n\nexport default function SettingsPage() {\n const perms = usePmPermissions();\n const canWrite = perms.has('update.manage.productManagement.settings');\n const [form, setForm] = useState(emptyForm());\n const [loading, setLoading] = useState(true);\n const [saving, setSaving] = useState(false);\n const [error, setError] = useState('');\n const [tables, setTables] = useState([]);\n // Cache: tableName -> UUID column list. We fetch lazily when a subject's\n // table is set and reuse on rerenders.\n const [uuidColsByTable, setUuidColsByTable] = useState({});\n // Cache: tableName -> text column list. Member uses it for the\n // identifier / family-id / name columns. Cache is keyed by table name\n // so each table fetches once.\n const [textColsByTable, setTextColsByTable] = useState({});\n // Cache: tableName -> date/timestamp column list. Today only the member\n // table needs it (DOB picker). Same lazy-load pattern as the other caches.\n const [dateColsByTable, setDateColsByTable] = useState({});\n\n async function load() {\n setLoading(true);\n setError('');\n try {\n const [s, t] = await Promise.all([getSettings(), listPublicTables().catch(() => [])]);\n setForm(applySettings(s));\n setTables(t);\n } catch (err) {\n setError(err?.response?.data?.message ?? err?.message ?? 'Failed to load settings');\n } finally {\n setLoading(false);\n }\n }\n\n usePermissionedEffect('view.manage.productManagement.settings', () => { void load(); }, []);\n\n // Whenever a subject's table is set, lazy-load its UUID columns (idempotent).\n useEffect(() => {\n const needed = [form.memberTableName]\n .filter(Boolean)\n .filter((t) => uuidColsByTable[t] === undefined);\n if (needed.length === 0) return;\n let cancelled = false;\n (async () => {\n const updates = {};\n await Promise.all(needed.map(async (t) => {\n try {\n updates[t] = await listUuidColumns(t);\n } catch {\n updates[t] = [];\n }\n }));\n if (!cancelled) {\n setUuidColsByTable((prev) => ({ ...prev, ...updates }));\n }\n })();\n return () => { cancelled = true; };\n }, [form.memberTableName, uuidColsByTable]);\n\n // Lazy-load text columns for tables that need a text-column picker. Today\n // facility uses it for its display-name column and member uses it for its\n // search column. Cache is keyed by table name so each table is fetched once.\n useEffect(() => {\n const needed = [form.memberTableName]\n .filter(Boolean)\n .filter((t) => textColsByTable[t] === undefined);\n if (needed.length === 0) return;\n let cancelled = false;\n (async () => {\n const updates = {};\n await Promise.all(needed.map(async (t) => {\n try {\n updates[t] = await listTextColumns(t);\n } catch {\n updates[t] = [];\n }\n }));\n if (!cancelled) {\n setTextColsByTable((prev) => ({ ...prev, ...updates }));\n }\n })();\n return () => { cancelled = true; };\n }, [form.memberTableName, textColsByTable]);\n\n // Lazy-load date columns for the member table — drives the DOB picker.\n useEffect(() => {\n const needed = [form.memberTableName]\n .filter(Boolean)\n .filter((t) => dateColsByTable[t] === undefined);\n if (needed.length === 0) return;\n let cancelled = false;\n (async () => {\n const updates = {};\n await Promise.all(needed.map(async (t) => {\n try {\n updates[t] = await listDateColumns(t);\n } catch {\n updates[t] = [];\n }\n }));\n if (!cancelled) {\n setDateColsByTable((prev) => ({ ...prev, ...updates }));\n }\n })();\n return () => { cancelled = true; };\n }, [form.memberTableName, dateColsByTable]);\n\n function patch(k, v) {\n setForm((f) => ({ ...f, [k]: v }));\n }\n\n // When the table changes, clear every column previously mapped against the\n // old table so the operator can't ship a stale (now-invalid) mapping.\n function patchTable(tableKey, columnKeys, nextTable) {\n const keys = Array.isArray(columnKeys) ? columnKeys : [columnKeys];\n setForm((f) => {\n const cleared = keys.reduce((acc, k) => ({ ...acc, [k]: '' }), {});\n return { ...f, [tableKey]: nextTable, ...cleared };\n });\n }\n\n const countryErr = !form.countryCode ? 'Country is required.' : '';\n const formIsValid = !countryErr;\n const previewCountry = findCountry(form.countryCode);\n\n async function save() {\n if (!formIsValid) return;\n setSaving(true);\n setError('');\n try {\n const saved = await upsertSettings({\n memberTableName: form.memberTableName || null,\n memberIdColumn: form.memberIdColumn || null,\n memberIdentifierColumn: form.memberIdentifierColumn || null,\n memberFamilyIdColumn: form.memberFamilyIdColumn || null,\n memberNameColumn: form.memberNameColumn || null,\n memberDobColumn: form.memberDobColumn || null,\n countryCode: form.countryCode,\n // Sales-on always implies purchase-amounts-on; enforce it at save time\n // too so direct API callers can't ship an inconsistent pair.\n managePurchaseAmounts: form.manageSales ? true : !!form.managePurchaseAmounts,\n manageSales: !!form.manageSales,\n allowPersonalPurchase: !!form.allowPersonalPurchase,\n requirePurchaseConfirmation: !!form.requirePurchaseConfirmation,\n });\n setForm(applySettings(saved));\n updateLocalPmSettings(saved);\n void loadPmSettings(true).catch(() => {});\n showToast({ message: 'Settings saved.', type: 'success' });\n } catch (err) {\n const message = err?.response?.data?.message ?? err?.message ?? 'Failed to save settings';\n setError(message);\n showToast({ message, type: 'error' });\n } finally {\n setSaving(false);\n }\n }\n\n return (\n <Box>\n <PmNav />\n <PmGuard perm={'view.manage.productManagement.settings'}>\n <PmPageShell\n title=\"Settings\"\n subtitle=\"Set up the module for your deployment. Choose your country, link to your database, and enable the features you need.\"\n chips={['Configuration']}\n actions={\n <Stack direction=\"row\" spacing={1}>\n <Button variant=\"outlined\" startIcon={<RefreshRoundedIcon />} onClick={() => void load()}>Refresh</Button>\n <Button variant=\"contained\" startIcon={<SaveRoundedIcon />} disabled={!formIsValid || saving || loading || !canWrite}\n onClick={() => void save()}>\n {saving ? 'Saving…' : 'Save'}\n </Button>\n </Stack>\n }\n >\n {error ? <Alert severity=\"error\" sx={{ mb: 2 }}>{error}</Alert> : null}\n\n {/* ---------- Country (drives currency + phone) ---------- */}\n <Card sx={{\n borderRadius: 4, mb: 2,\n border: '1px solid', borderColor: 'divider',\n boxShadow: '0 12px 32px rgba(15, 23, 42, 0.045)',\n }}>\n <CardContent sx={{ p: 2.5 }}>\n <PmFormSection\n eyebrow=\"Locale\"\n title=\"Implementation country\"\n hint=\"The country controls currency display and phone number formats.\"\n sx={{ mb: 2 }}\n />\n <Grid container spacing={2}>\n <Grid item xs={12} md={6}>\n <Autocomplete\n size=\"small\"\n options={COUNTRIES}\n value={previewCountry}\n onChange={(_, next) => patch('countryCode', next?.code ?? '')}\n disableClearable\n getOptionLabel={(c) => (c ? `${c.name} (${c.code})` : '')}\n isOptionEqualToValue={(a, b) => a?.code === b?.code}\n filterOptions={(opts, { inputValue }) => {\n const q = inputValue.trim().toLowerCase();\n if (!q) return opts;\n return opts.filter((c) =>\n c.name.toLowerCase().includes(q)\n || c.code.toLowerCase().includes(q)\n || c.currencyCode.toLowerCase().includes(q)\n || c.phoneCode.includes(q)\n );\n }}\n renderOption={(props, c) => (\n <Box component=\"li\" {...props} key={c.code}>\n <Stack direction=\"row\" alignItems=\"baseline\" spacing={1.25} sx={{ width: '100%' }}>\n <Box component=\"span\" sx={{ fontWeight: 800, minWidth: 32 }}>{c.code}</Box>\n <Box component=\"span\" sx={{ fontWeight: 700 }}>{c.name}</Box>\n <Typography component=\"span\" variant=\"caption\" color=\"text.secondary\" sx={{ ml: 'auto' }}>\n {c.currencyCode} · {c.currencySymbol} · {c.phoneCode}\n </Typography>\n </Stack>\n </Box>\n )}\n renderInput={(params) => (\n <TextField\n {...params}\n required\n label=\"Country\"\n error={!!countryErr}\n helperText={countryErr || 'Type to search by name, code, currency, or dial code.'}\n />\n )}\n />\n </Grid>\n <Grid item xs={12} md={6}>\n <Stack direction=\"row\" spacing={1.5} sx={{ height: '100%' }}>\n <PreviewTile\n icon={<PaymentsRoundedIcon fontSize=\"small\" />}\n label=\"Currency\"\n primary={`${previewCountry?.currencySymbol ?? '—'} 1,234.50`}\n secondary={previewCountry?.currencyCode ?? '—'}\n />\n <PreviewTile\n icon={<PhoneIphoneRoundedIcon fontSize=\"small\" />}\n label=\"Phone\"\n primary={previewCountry?.phoneCode ?? '—'}\n secondary={previewCountry\n ? `${previewCountry.phoneMin}${previewCountry.phoneMin === previewCountry.phoneMax ? '' : `–${previewCountry.phoneMax}`} digits`\n : '—'}\n />\n </Stack>\n </Grid>\n </Grid>\n </CardContent>\n </Card>\n\n {/* ---------- Feature toggles ---------- */}\n <Card sx={{\n borderRadius: 4, mb: 2,\n border: '1px solid', borderColor: 'divider',\n boxShadow: '0 12px 32px rgba(15, 23, 42, 0.045)',\n }}>\n <CardContent sx={{ p: 2.5 }}>\n <PmFormSection\n eyebrow=\"Scope\"\n title=\"Features\"\n hint=\"Turn on only the features you need.\"\n sx={{ mb: 2 }}\n />\n <Stack spacing={1.5}>\n <ToggleRow\n label=\"Manage sales and payments\"\n hint=\"Turn off to hide sales and payment features.\"\n value={form.manageSales}\n onChange={(v) => patch('manageSales', v)}\n />\n <ToggleRow\n label=\"Manage purchase amounts\"\n hint=\"Turn off if you only track stock, not money.\"\n value={form.manageSales ? true : form.managePurchaseAmounts}\n onChange={(v) => patch('managePurchaseAmounts', v)}\n disabled={form.manageSales}\n lockNote=\"Required while sales and payments are on — sales need purchase costs to compute margins.\"\n />\n <ToggleRow\n label=\"Allow personal purchases\"\n hint=\"Turn off to hide the personal purchase option.\"\n value={form.allowPersonalPurchase}\n onChange={(v) => patch('allowPersonalPurchase', v)}\n />\n <ToggleRow\n label=\"Require purchase confirmation\"\n hint=\"Turn on to require a manager to approve purchases before stock is added.\"\n value={form.requirePurchaseConfirmation}\n onChange={(v) => patch('requirePurchaseConfirmation', v)}\n />\n </Stack>\n </CardContent>\n </Card>\n\n {/* ---------- Subject mappings ---------- */}\n <Card sx={{\n borderRadius: 4,\n border: '1px solid', borderColor: 'divider',\n boxShadow: '0 12px 32px rgba(15, 23, 42, 0.045)',\n }}>\n <CardContent sx={{ p: 2.5 }}>\n <PmFormSection\n eyebrow=\"Identity mappings\"\n title=\"Subjects\"\n hint=\"Connect customer, user, and facility data from your system. This links real people to the app.\"\n sx={{ mb: 2 }}\n />\n\n <Stack spacing={3}>\n <MemberSubjectRow\n tables={tables}\n tableValue={form.memberTableName}\n onTableChange={(v) => patchTable(\n 'memberTableName',\n ['memberIdColumn', 'memberIdentifierColumn', 'memberFamilyIdColumn', 'memberNameColumn', 'memberDobColumn'],\n v,\n )}\n uuidColumns={uuidColsByTable[form.memberTableName]}\n textColumns={textColsByTable[form.memberTableName]}\n dateColumns={dateColsByTable[form.memberTableName]}\n idColumnValue={form.memberIdColumn}\n onIdColumnChange={(v) => patch('memberIdColumn', v)}\n identifierColumnValue={form.memberIdentifierColumn}\n onIdentifierColumnChange={(v) => patch('memberIdentifierColumn', v)}\n familyIdColumnValue={form.memberFamilyIdColumn}\n onFamilyIdColumnChange={(v) => patch('memberFamilyIdColumn', v)}\n nameColumnValue={form.memberNameColumn}\n onNameColumnChange={(v) => patch('memberNameColumn', v)}\n dobColumnValue={form.memberDobColumn}\n onDobColumnChange={(v) => patch('memberDobColumn', v)}\n />\n </Stack>\n </CardContent>\n </Card>\n </PmPageShell>\n </PmGuard>\n </Box>\n );\n}\n\nfunction ToggleRow({ label, hint, value, onChange, disabled = false, lockNote = '' }) {\n const checked = !!value;\n const interactive = !disabled;\n return (\n <Box\n role=\"button\"\n tabIndex={interactive ? 0 : -1}\n aria-disabled={disabled || undefined}\n onClick={interactive ? () => onChange(!checked) : undefined}\n onKeyDown={interactive ? (e) => {\n if (e.key === ' ' || e.key === 'Enter') {\n e.preventDefault();\n onChange(!checked);\n }\n } : undefined}\n sx={(theme) => ({\n display: 'flex',\n alignItems: 'center',\n gap: 2,\n p: 2,\n borderRadius: 3,\n cursor: interactive ? 'pointer' : 'not-allowed',\n opacity: interactive ? 1 : 0.75,\n border: '1px solid',\n borderColor: checked ? alpha(theme.palette.primary.main, 0.35) : 'divider',\n bgcolor: checked ? alpha(theme.palette.primary.main, 0.04) : 'transparent',\n transition: 'all 180ms ease',\n '&:hover': interactive ? {\n borderColor: checked ? theme.palette.primary.main : alpha(theme.palette.primary.main, 0.35),\n bgcolor: checked ? alpha(theme.palette.primary.main, 0.06) : alpha(theme.palette.primary.main, 0.02),\n } : undefined,\n })}\n >\n <Box sx={{ flexGrow: 1, minWidth: 0 }}>\n <Stack direction=\"row\" alignItems=\"center\" spacing={1}>\n <Typography variant=\"subtitle1\" sx={{ fontWeight: 800, lineHeight: 1.2 }}>{label}</Typography>\n <Box\n sx={(theme) => ({\n px: 0.9,\n py: 0.15,\n borderRadius: 999,\n fontSize: '0.65rem',\n fontWeight: 800,\n letterSpacing: 0.6,\n textTransform: 'uppercase',\n color: checked ? theme.palette.success.dark : theme.palette.text.disabled,\n bgcolor: checked ? alpha(theme.palette.success.main, 0.12) : alpha(theme.palette.text.disabled, 0.1),\n })}\n >\n {checked ? 'Enabled' : 'Disabled'}\n </Box>\n {disabled && lockNote ? (\n <Box\n sx={(theme) => ({\n px: 0.9,\n py: 0.15,\n borderRadius: 999,\n fontSize: '0.65rem',\n fontWeight: 800,\n letterSpacing: 0.6,\n textTransform: 'uppercase',\n color: theme.palette.warning.dark,\n bgcolor: alpha(theme.palette.warning.main, 0.14),\n })}\n >\n Locked\n </Box>\n ) : null}\n </Stack>\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ display: 'block', mt: 0.5 }}>\n {disabled && lockNote ? lockNote : hint}\n </Typography>\n </Box>\n <CustomSwitch\n checked={checked}\n disabled={disabled}\n onClick={(e) => e.stopPropagation()}\n onChange={(e) => onChange(e.target.checked)}\n />\n </Box>\n );\n}\n\nfunction PreviewTile({ icon, label, primary, secondary }) {\n return (\n <Box\n sx={(theme) => ({\n flex: 1,\n minWidth: 0,\n p: 1.25,\n borderRadius: 3,\n border: '1px solid',\n borderColor: 'divider',\n bgcolor: alpha(theme.palette.primary.main, 0.03),\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n })}\n >\n <Stack direction=\"row\" alignItems=\"center\" spacing={0.75} sx={{ color: 'text.secondary', mb: 0.25 }}>\n {icon}\n <Typography variant=\"caption\" sx={{ fontWeight: 800, letterSpacing: 0.6, textTransform: 'uppercase' }}>\n {label}\n </Typography>\n </Stack>\n <Typography sx={{ fontWeight: 800, fontSize: '1.1rem', fontVariantNumeric: 'tabular-nums', lineHeight: 1.2 }} noWrap>\n {primary}\n </Typography>\n <Typography variant=\"caption\" color=\"text.secondary\" noWrap>{secondary}</Typography>\n </Box>\n );\n}\n\n// Dedicated members row — five column mappings (uuid + identifier + family\n// id + name + dob), one of which is sourced from date-typed columns. Sales\n// and Payments build the member profile card off these.\nfunction MemberSubjectRow({\n tables,\n tableValue,\n onTableChange,\n uuidColumns,\n textColumns,\n dateColumns,\n idColumnValue,\n onIdColumnChange,\n identifierColumnValue,\n onIdentifierColumnChange,\n familyIdColumnValue,\n onFamilyIdColumnChange,\n nameColumnValue,\n onNameColumnChange,\n dobColumnValue,\n onDobColumnChange,\n}) {\n const uuidLoaded = Array.isArray(uuidColumns);\n const textLoaded = Array.isArray(textColumns);\n const dateLoaded = Array.isArray(dateColumns);\n const noUuid = uuidLoaded && uuidColumns.length === 0;\n const noText = textLoaded && textColumns.length === 0;\n const noDate = dateLoaded && dateColumns.length === 0;\n\n const tableOptions = useMemo(() => {\n const base = tables ?? [];\n if (!tableValue || base.includes(tableValue)) return base;\n return [tableValue, ...base];\n }, [tableValue, tables]);\n\n // Pin the currently-saved value into options even if the live list doesn't\n // know about it, so a setting picked before a schema change still renders.\n function withSavedValue(list, value) {\n const arr = list ?? [];\n if (!value || arr.includes(value)) return arr;\n return [value, ...arr];\n }\n\n const uuidOptions = useMemo(\n () => withSavedValue(uuidLoaded ? uuidColumns : [], idColumnValue),\n [uuidColumns, uuidLoaded, idColumnValue],\n );\n const identifierOptions = useMemo(\n () => withSavedValue(textLoaded ? textColumns : [], identifierColumnValue),\n [textColumns, textLoaded, identifierColumnValue],\n );\n const familyIdOptions = useMemo(\n () => withSavedValue(textLoaded ? textColumns : [], familyIdColumnValue),\n [textColumns, textLoaded, familyIdColumnValue],\n );\n const nameOptions = useMemo(\n () => withSavedValue(textLoaded ? textColumns : [], nameColumnValue),\n [textColumns, textLoaded, nameColumnValue],\n );\n const dobOptions = useMemo(\n () => withSavedValue(dateLoaded ? dateColumns : [], dobColumnValue),\n [dateColumns, dateLoaded, dobColumnValue],\n );\n\n const uuidHelp = !tableValue\n ? 'Pick a table first.'\n : !uuidLoaded ? 'Loading columns…'\n : noUuid ? 'No UUID columns found in this table.'\n : 'Column that holds the member’s primary key.';\n\n function textHelp(description) {\n if (!tableValue) return 'Pick a table first.';\n if (!textLoaded) return 'Loading columns…';\n if (noText) return 'No text columns found in this table.';\n return description;\n }\n\n const dobHelp = !tableValue\n ? 'Pick a table first.'\n : !dateLoaded ? 'Loading columns…'\n : noDate ? 'No date/timestamp columns found in this table.'\n : 'Age is derived from this column in the UI.';\n\n return (\n <Box>\n <Typography variant=\"subtitle1\" sx={{ fontWeight: 800, lineHeight: 1.2 }}>Members</Typography>\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ display: 'block', mb: 1.5 }}>\n Patients / customers who can be sold to, charged dues, and administered vaccines. These columns build the member profile card on Sales and Payments.\n </Typography>\n <Grid container spacing={2}>\n <Grid item xs={12} md={6}>\n <Autocomplete\n size=\"small\"\n options={tableOptions}\n value={tableValue || null}\n onChange={(_, next) => onTableChange(next ?? '')}\n renderInput={(params) => (\n <TextField {...params} label=\"Table name\" placeholder=\"Type to search…\"\n helperText=\"Public-schema table that holds members.\" />\n )}\n />\n </Grid>\n <Grid item xs={12} md={6}>\n <Autocomplete\n size=\"small\"\n disabled={!tableValue || !uuidLoaded || noUuid}\n options={uuidOptions}\n value={idColumnValue || null}\n onChange={(_, next) => onIdColumnChange(next ?? '')}\n renderInput={(params) => (\n <TextField {...params} label=\"UUID column\" placeholder=\"Type to search…\" helperText={uuidHelp} />\n )}\n />\n </Grid>\n <Grid item xs={12} md={6}>\n <Autocomplete\n size=\"small\"\n disabled={!tableValue || !textLoaded || noText}\n options={identifierOptions}\n value={identifierColumnValue || null}\n onChange={(_, next) => onIdentifierColumnChange(next ?? '')}\n renderInput={(params) => (\n <TextField {...params} label=\"Identifier column\" placeholder=\"Type to search…\"\n helperText={textHelp('Unique identifier shown on the profile card (e.g. national id).')} />\n )}\n />\n </Grid>\n <Grid item xs={12} md={6}>\n <Autocomplete\n size=\"small\"\n disabled={!tableValue || !textLoaded || noText}\n options={familyIdOptions}\n value={familyIdColumnValue || null}\n onChange={(_, next) => onFamilyIdColumnChange(next ?? '')}\n renderInput={(params) => (\n <TextField {...params} label=\"Family ID column\" placeholder=\"Type to search…\"\n helperText={textHelp('Groups members by household.')} />\n )}\n />\n </Grid>\n <Grid item xs={12} md={6}>\n <Autocomplete\n size=\"small\"\n disabled={!tableValue || !textLoaded || noText}\n options={nameOptions}\n value={nameColumnValue || null}\n onChange={(_, next) => onNameColumnChange(next ?? '')}\n renderInput={(params) => (\n <TextField {...params} label=\"Name column\" placeholder=\"Type to search…\"\n helperText={textHelp('Display name. Also used by the recent-payments / sales tables.')} />\n )}\n />\n </Grid>\n <Grid item xs={12} md={6}>\n <Autocomplete\n size=\"small\"\n disabled={!tableValue || !dateLoaded || noDate}\n options={dobOptions}\n value={dobColumnValue || null}\n onChange={(_, next) => onDobColumnChange(next ?? '')}\n renderInput={(params) => (\n <TextField {...params} label=\"Date of birth column\" placeholder=\"Type to search…\"\n helperText={dobHelp} />\n )}\n />\n </Grid>\n </Grid>\n </Box>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,469 @@
1
+ import { C as e, N as t, a as n, i as r, lt as ee, n as te, r as ne, t as re } from "./PmGuard-CjJBisaN.js";
2
+ import { a as ie, o as ae, t as oe } from "./PmTable-BuXZQZCU.js";
3
+ import { h as se, m as i, n as a, t as o } from "./validation-Ba7puFIO.js";
4
+ import { t as s } from "./useFieldErrors-hDG8ox_x.js";
5
+ import { o as c, p as ce } from "./constants-BrA_hfAI.js";
6
+ import { t as l } from "./FacilityPicker-Coi8I3yE.js";
7
+ import { useState as u } from "react";
8
+ import { jsx as d, jsxs as f } from "react/jsx-runtime";
9
+ import { v4 as le } from "uuid";
10
+ import { Alert as ue, Box as p, Button as m, Checkbox as de, Chip as h, Dialog as fe, DialogActions as g, DialogContent as pe, DialogTitle as me, Divider as he, FormControl as _, FormControlLabel as v, FormHelperText as ge, InputLabel as y, MenuItem as b, Select as x, Skeleton as _e, Stack as S, TableBody as ve, TableCell as C, TableHead as ye, TableRow as w, TextField as T, Typography as E } from "@mui/material";
11
+ import D from "@mui/icons-material/AddRounded";
12
+ import O from "@mui/icons-material/RefreshRounded";
13
+ import { showToast as k } from "@/common/toaster/toaster";
14
+ import A from "@mui/icons-material/WarehouseRounded";
15
+ //#region src/views/StorageUnitsPage.jsx
16
+ var j = [{
17
+ value: "FACILITY",
18
+ label: "Facility"
19
+ }];
20
+ function M() {
21
+ let M = r().has("update.manage.productManagement.storageUnit"), [N, P] = u([]), [be, F] = u({}), [I, L] = u(!1), [R, z] = u(""), [xe, B] = u(!1), [V, H] = u(null), [U, W] = u(K()), G = s();
22
+ function K() {
23
+ return {
24
+ id: "",
25
+ ownerType: "FACILITY",
26
+ ownerId: "",
27
+ unitName: "",
28
+ unitCode: "",
29
+ unitType: "REFRIGERATOR",
30
+ make: "",
31
+ model: "",
32
+ comments: "",
33
+ operatingTempMinCelsius: "",
34
+ operatingTempMaxCelsius: "",
35
+ isActive: !0
36
+ };
37
+ }
38
+ async function q() {
39
+ L(!0), z("");
40
+ try {
41
+ let n = await t({ activeOnly: !1 });
42
+ P(n);
43
+ let r = Array.from(new Set(n.map((e) => e.ownerId).filter(Boolean)));
44
+ if (r.length === 0) F({});
45
+ else try {
46
+ let t = await e(r), n = {};
47
+ t.forEach((e) => {
48
+ n[e.id] = e.name;
49
+ }), F(n);
50
+ } catch {
51
+ F({});
52
+ }
53
+ } catch (e) {
54
+ let t = e?.response?.data?.message ?? e?.message ?? "Failed to load storage units";
55
+ z(t), k({
56
+ message: t,
57
+ type: "error"
58
+ });
59
+ } finally {
60
+ L(!1);
61
+ }
62
+ }
63
+ ne("view.manage.productManagement.storageUnit", () => {
64
+ q();
65
+ }, []);
66
+ function Se(e) {
67
+ return be[e] ?? e;
68
+ }
69
+ function J() {
70
+ H(null), W({
71
+ ...K(),
72
+ id: le()
73
+ }), G.reset(), z(""), B(!0);
74
+ }
75
+ function Ce(e) {
76
+ H(e), G.reset(), z(""), W({
77
+ id: e.id,
78
+ ownerType: e.ownerType ?? "FACILITY",
79
+ ownerId: e.ownerId ?? "",
80
+ unitName: e.unitName ?? "",
81
+ unitCode: e.unitCode ?? "",
82
+ unitType: e.unitType ?? "REFRIGERATOR",
83
+ make: e.make ?? "",
84
+ model: e.model ?? "",
85
+ comments: e.comments ?? "",
86
+ operatingTempMinCelsius: e.operatingTempMinCelsius ?? "",
87
+ operatingTempMaxCelsius: e.operatingTempMaxCelsius ?? "",
88
+ isActive: e.isActive !== !1
89
+ }), B(!0);
90
+ }
91
+ let Y = se(U.operatingTempMinCelsius, U.operatingTempMaxCelsius), X = a(U.unitCode, { required: !0 }), Z = (U.unitCode || "").trim().toUpperCase(), we = !X && Z && U.ownerId && N.some((e) => e.id !== U.id && e.ownerId === U.ownerId && (e.unitCode || "").toUpperCase() === Z), Q = {
92
+ ownerType: i(U.ownerType, "Owner type"),
93
+ ownerId: i(U.ownerId, "Facility"),
94
+ unitName: i(U.unitName, "Name"),
95
+ unitCode: X || (we ? "Code is already in use for this facility." : ""),
96
+ unitType: i(U.unitType, "Type"),
97
+ operatingTempMinCelsius: Y.min,
98
+ operatingTempMaxCelsius: Y.max
99
+ }, $ = o(Q);
100
+ async function Te() {
101
+ if (!$) {
102
+ G.markAllTouched(), z("Please fix the highlighted fields.");
103
+ return;
104
+ }
105
+ try {
106
+ await ee({
107
+ id: U.id,
108
+ ownerId: U.ownerId,
109
+ unitName: U.unitName.trim(),
110
+ unitCode: U.unitCode.trim().toUpperCase(),
111
+ unitType: U.unitType,
112
+ make: U.make?.trim() || null,
113
+ model: U.model?.trim() || null,
114
+ comments: U.comments?.trim() || null,
115
+ operatingTempMinCelsius: U.operatingTempMinCelsius === "" ? null : Number(U.operatingTempMinCelsius),
116
+ operatingTempMaxCelsius: U.operatingTempMaxCelsius === "" ? null : Number(U.operatingTempMaxCelsius),
117
+ isActive: U.isActive
118
+ }), k({
119
+ message: "Storage unit saved.",
120
+ type: "success"
121
+ }), B(!1), await q();
122
+ } catch (e) {
123
+ let t = e?.response?.data?.message ?? e?.message ?? "Failed to save storage unit";
124
+ z(t), k({
125
+ message: t,
126
+ type: "error"
127
+ });
128
+ }
129
+ }
130
+ return /* @__PURE__ */ f(p, { children: [/* @__PURE__ */ d(te, {}), /* @__PURE__ */ f(re, {
131
+ perm: "view.manage.productManagement.storageUnit",
132
+ children: [/* @__PURE__ */ f(n, {
133
+ title: "Storage Units",
134
+ subtitle: "Cold-chain equipment for storing vaccine and product batches. Currently managed per facility.",
135
+ chips: ["Catalog", "Facility-owned"],
136
+ actions: /* @__PURE__ */ f(S, {
137
+ direction: "row",
138
+ spacing: 1,
139
+ children: [/* @__PURE__ */ d(m, {
140
+ variant: "outlined",
141
+ startIcon: /* @__PURE__ */ d(O, {}),
142
+ onClick: () => void q(),
143
+ children: "Refresh"
144
+ }), M ? /* @__PURE__ */ d(m, {
145
+ variant: "contained",
146
+ startIcon: /* @__PURE__ */ d(D, {}),
147
+ onClick: J,
148
+ children: "New Storage Unit"
149
+ }) : null]
150
+ }),
151
+ children: [R ? /* @__PURE__ */ d(ue, {
152
+ severity: "error",
153
+ sx: { mb: 2 },
154
+ children: R
155
+ }) : null, /* @__PURE__ */ d(ae, {
156
+ eyebrow: "Cold-chain network",
157
+ title: "Storage units",
158
+ subtitle: I ? "Loading…" : `${N.length} ${N.length === 1 ? "unit" : "units"}`,
159
+ children: /* @__PURE__ */ f(ie, { children: [/* @__PURE__ */ d(ye, { children: /* @__PURE__ */ f(w, { children: [
160
+ /* @__PURE__ */ d(C, { children: "Code" }),
161
+ /* @__PURE__ */ d(C, { children: "Name" }),
162
+ /* @__PURE__ */ d(C, { children: "Facility" }),
163
+ /* @__PURE__ */ d(C, { children: "Type" }),
164
+ /* @__PURE__ */ d(C, { children: "Operating range" }),
165
+ /* @__PURE__ */ d(C, { children: "Status" }),
166
+ /* @__PURE__ */ d(C, {
167
+ align: "right",
168
+ children: "Action"
169
+ })
170
+ ] }) }), /* @__PURE__ */ d(ve, { children: I ? Array.from({ length: 4 }).map((e, t) => /* @__PURE__ */ d(w, { children: Array.from({ length: 7 }).map((e, t) => /* @__PURE__ */ d(C, { children: /* @__PURE__ */ d(_e, { height: 22 }) }, t)) }, t)) : N.length === 0 ? /* @__PURE__ */ d(oe, {
171
+ colSpan: 7,
172
+ icon: A,
173
+ title: "No storage units yet",
174
+ hint: "You need storage equipment to keep vaccine batches safe.",
175
+ action: M ? /* @__PURE__ */ d(m, {
176
+ variant: "contained",
177
+ size: "small",
178
+ startIcon: /* @__PURE__ */ d(D, {}),
179
+ onClick: J,
180
+ children: "Create first unit"
181
+ }) : null
182
+ }) : N.map((e) => /* @__PURE__ */ f(w, {
183
+ hover: !0,
184
+ children: [
185
+ /* @__PURE__ */ d(C, { children: /* @__PURE__ */ d(p, {
186
+ component: "span",
187
+ sx: {
188
+ display: "inline-flex",
189
+ px: .85,
190
+ py: .25,
191
+ borderRadius: 1,
192
+ bgcolor: "grey.100",
193
+ fontFamily: "monospace",
194
+ fontSize: "0.72rem",
195
+ fontWeight: 800
196
+ },
197
+ children: e.unitCode
198
+ }) }),
199
+ /* @__PURE__ */ d(C, { children: /* @__PURE__ */ d(E, {
200
+ variant: "body2",
201
+ sx: { fontWeight: 700 },
202
+ children: e.unitName
203
+ }) }),
204
+ /* @__PURE__ */ d(C, { children: /* @__PURE__ */ d(E, {
205
+ variant: "caption",
206
+ color: "text.secondary",
207
+ children: Se(e.ownerId)
208
+ }) }),
209
+ /* @__PURE__ */ d(C, { children: /* @__PURE__ */ d(h, {
210
+ size: "small",
211
+ label: ce(c, e.unitType),
212
+ variant: "outlined",
213
+ sx: {
214
+ fontWeight: 700,
215
+ borderRadius: 1.5,
216
+ height: 22
217
+ }
218
+ }) }),
219
+ /* @__PURE__ */ d(C, { children: e.operatingTempMinCelsius != null && e.operatingTempMaxCelsius != null ? /* @__PURE__ */ f(E, {
220
+ variant: "caption",
221
+ sx: {
222
+ fontWeight: 700,
223
+ fontVariantNumeric: "tabular-nums"
224
+ },
225
+ children: [
226
+ e.operatingTempMinCelsius,
227
+ "°C → ",
228
+ e.operatingTempMaxCelsius,
229
+ "°C"
230
+ ]
231
+ }) : /* @__PURE__ */ d(E, {
232
+ variant: "caption",
233
+ color: "text.disabled",
234
+ children: "—"
235
+ }) }),
236
+ /* @__PURE__ */ d(C, { children: /* @__PURE__ */ d(h, {
237
+ size: "small",
238
+ label: e.isActive ? "Active" : "Inactive",
239
+ color: e.isActive ? "success" : "default",
240
+ variant: e.isActive ? "filled" : "outlined",
241
+ sx: {
242
+ fontWeight: 700,
243
+ borderRadius: 1.5,
244
+ height: 22
245
+ }
246
+ }) }),
247
+ /* @__PURE__ */ d(C, {
248
+ align: "right",
249
+ children: M ? /* @__PURE__ */ d(m, {
250
+ size: "small",
251
+ variant: "outlined",
252
+ onClick: () => Ce(e),
253
+ children: "Edit"
254
+ }) : null
255
+ })
256
+ ]
257
+ }, e.id)) })] })
258
+ })]
259
+ }), /* @__PURE__ */ f(fe, {
260
+ open: xe,
261
+ onClose: () => B(!1),
262
+ fullWidth: !0,
263
+ maxWidth: "sm",
264
+ children: [
265
+ /* @__PURE__ */ d(me, { children: V ? "Edit Storage Unit" : "New Storage Unit" }),
266
+ /* @__PURE__ */ d(pe, {
267
+ dividers: !0,
268
+ children: /* @__PURE__ */ f(S, {
269
+ spacing: 2,
270
+ sx: { pt: 1 },
271
+ children: [
272
+ /* @__PURE__ */ f(_, {
273
+ required: !0,
274
+ fullWidth: !0,
275
+ size: "small",
276
+ disabled: !!V,
277
+ error: G.show("ownerType") && !!Q.ownerType,
278
+ children: [
279
+ /* @__PURE__ */ d(y, { children: "Owner Type" }),
280
+ /* @__PURE__ */ d(x, {
281
+ label: "Owner Type",
282
+ value: U.ownerType,
283
+ onChange: (e) => W({
284
+ ...U,
285
+ ownerType: e.target.value,
286
+ ownerId: ""
287
+ }),
288
+ onBlur: G.onBlur("ownerType"),
289
+ children: j.map((e) => /* @__PURE__ */ d(b, {
290
+ value: e.value,
291
+ children: e.label
292
+ }, e.value))
293
+ }),
294
+ /* @__PURE__ */ d(ge, { children: G.show("ownerType") && Q.ownerType ? Q.ownerType : "Only Facility is available currently." })
295
+ ]
296
+ }),
297
+ /* @__PURE__ */ d(l, {
298
+ required: !0,
299
+ disabled: !!V || U.ownerType !== "FACILITY",
300
+ value: U.ownerId,
301
+ onChange: (e) => W({
302
+ ...U,
303
+ ownerId: e
304
+ }),
305
+ onBlur: G.onBlur("ownerId"),
306
+ error: G.show("ownerId") && !!Q.ownerId,
307
+ helperText: G.show("ownerId") && Q.ownerId ? Q.ownerId : "Search by name. The owner cannot be changed once created."
308
+ }),
309
+ /* @__PURE__ */ d(he, {}),
310
+ /* @__PURE__ */ d(T, {
311
+ required: !0,
312
+ label: "Unit name",
313
+ size: "small",
314
+ fullWidth: !0,
315
+ value: U.unitName,
316
+ onChange: (e) => {
317
+ let t = e.target.value, n = t.split(/\s+/).filter(Boolean).map((e) => e[0]).join("").toUpperCase().replace(/[^A-Z0-9_]/g, "");
318
+ W((e) => ({
319
+ ...e,
320
+ unitName: t,
321
+ unitCode: V ? e.unitCode : n
322
+ }));
323
+ },
324
+ onBlur: G.onBlur("unitName"),
325
+ error: G.show("unitName") && !!Q.unitName,
326
+ helperText: G.show("unitName") ? Q.unitName : ""
327
+ }),
328
+ /* @__PURE__ */ d(T, {
329
+ required: !0,
330
+ label: "Unit code (unique within facility)",
331
+ size: "small",
332
+ fullWidth: !0,
333
+ value: U.unitCode,
334
+ onChange: (e) => W({
335
+ ...U,
336
+ unitCode: e.target.value.toUpperCase()
337
+ }),
338
+ onBlur: G.onBlur("unitCode"),
339
+ error: G.show("unitCode") && !!Q.unitCode,
340
+ helperText: G.show("unitCode") && Q.unitCode ? Q.unitCode : "Auto-generated from the name. Edit if needed to make it unique within this facility."
341
+ }),
342
+ /* @__PURE__ */ f(_, {
343
+ required: !0,
344
+ fullWidth: !0,
345
+ size: "small",
346
+ error: G.show("unitType") && !!Q.unitType,
347
+ children: [/* @__PURE__ */ d(y, { children: "Type" }), /* @__PURE__ */ d(x, {
348
+ label: "Type",
349
+ value: U.unitType,
350
+ onChange: (e) => W({
351
+ ...U,
352
+ unitType: e.target.value
353
+ }),
354
+ onBlur: G.onBlur("unitType"),
355
+ children: c.map((e) => /* @__PURE__ */ d(b, {
356
+ value: e.value,
357
+ children: e.label
358
+ }, e.value))
359
+ })]
360
+ }),
361
+ /* @__PURE__ */ f(S, {
362
+ direction: "row",
363
+ spacing: 2,
364
+ children: [/* @__PURE__ */ d(T, {
365
+ label: "Make",
366
+ size: "small",
367
+ fullWidth: !0,
368
+ value: U.make,
369
+ onChange: (e) => W({
370
+ ...U,
371
+ make: e.target.value
372
+ }),
373
+ helperText: "Example: Godrej, Vestfrost"
374
+ }), /* @__PURE__ */ d(T, {
375
+ label: "Model",
376
+ size: "small",
377
+ fullWidth: !0,
378
+ value: U.model,
379
+ onChange: (e) => W({
380
+ ...U,
381
+ model: e.target.value
382
+ }),
383
+ helperText: "Example: GVR-100"
384
+ })]
385
+ }),
386
+ /* @__PURE__ */ f(S, {
387
+ direction: "row",
388
+ spacing: 2,
389
+ children: [/* @__PURE__ */ d(T, {
390
+ label: "Min °C",
391
+ size: "small",
392
+ type: "number",
393
+ fullWidth: !0,
394
+ inputProps: {
395
+ step: "0.1",
396
+ min: -90,
397
+ max: 30
398
+ },
399
+ value: U.operatingTempMinCelsius,
400
+ onChange: (e) => W({
401
+ ...U,
402
+ operatingTempMinCelsius: e.target.value
403
+ }),
404
+ onBlur: G.onBlur("operatingTempMinCelsius"),
405
+ error: G.show("operatingTempMinCelsius") && !!Q.operatingTempMinCelsius,
406
+ helperText: G.show("operatingTempMinCelsius") && Q.operatingTempMinCelsius ? Q.operatingTempMinCelsius : "Allowed range: −90°C to +30°C"
407
+ }), /* @__PURE__ */ d(T, {
408
+ label: "Max °C",
409
+ size: "small",
410
+ type: "number",
411
+ fullWidth: !0,
412
+ inputProps: {
413
+ step: "0.1",
414
+ min: -90,
415
+ max: 30
416
+ },
417
+ value: U.operatingTempMaxCelsius,
418
+ onChange: (e) => W({
419
+ ...U,
420
+ operatingTempMaxCelsius: e.target.value
421
+ }),
422
+ onBlur: G.onBlur("operatingTempMaxCelsius"),
423
+ error: G.show("operatingTempMaxCelsius") && !!Q.operatingTempMaxCelsius,
424
+ helperText: G.show("operatingTempMaxCelsius") && Q.operatingTempMaxCelsius ? Q.operatingTempMaxCelsius : "Allowed range: −90°C to +30°C"
425
+ })]
426
+ }),
427
+ /* @__PURE__ */ d(T, {
428
+ label: "Comments",
429
+ size: "small",
430
+ multiline: !0,
431
+ minRows: 2,
432
+ fullWidth: !0,
433
+ value: U.comments,
434
+ onChange: (e) => W({
435
+ ...U,
436
+ comments: e.target.value
437
+ }),
438
+ helperText: "Notes about placement, maintenance schedule, or other details."
439
+ }),
440
+ /* @__PURE__ */ d(v, {
441
+ control: /* @__PURE__ */ d(de, {
442
+ checked: U.isActive,
443
+ onChange: (e) => W({
444
+ ...U,
445
+ isActive: e.target.checked
446
+ })
447
+ }),
448
+ label: "Active"
449
+ })
450
+ ]
451
+ })
452
+ }),
453
+ /* @__PURE__ */ f(g, { children: [/* @__PURE__ */ d(m, {
454
+ onClick: () => B(!1),
455
+ children: "Cancel"
456
+ }), /* @__PURE__ */ d(m, {
457
+ variant: "contained",
458
+ disabled: !$,
459
+ onClick: () => void Te(),
460
+ children: "Save"
461
+ })] })
462
+ ]
463
+ })]
464
+ })] });
465
+ }
466
+ //#endregion
467
+ export { M as default };
468
+
469
+ //# sourceMappingURL=StorageUnitsPage-BlC2AgrJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StorageUnitsPage-BlC2AgrJ.js","names":[],"sources":["../src/views/StorageUnitsPage.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 Divider,\n FormControl,\n FormControlLabel,\n FormHelperText,\n InputLabel,\n MenuItem,\n Select,\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 WarehouseRoundedIcon from '@mui/icons-material/WarehouseRounded';\nimport { showToast } from '@/common/toaster/toaster';\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, PmTable, PmTableCard } from '@pm/components/PmTable';\nimport { STORAGE_UNIT_TYPES, labelOf } from '@pm/utils/constants';\nimport {\n getFacilitiesByIds,\n getStorageUnits,\n upsertStorageUnit,\n} from '@pm/services/pmApi';\nimport FacilityPicker from '@pm/components/FacilityPicker';\nimport {\n isClean,\n validateCode,\n validateRequired,\n validateTempRange,\n} from '@pm/utils/validation';\nimport { useFieldErrors } from '@pm/utils/useFieldErrors';\n\n// Today only FACILITY-owned storage units exist. The dropdown is kept so the\n// UI is ready for future owner kinds (REGIONAL_DEPOT, etc.) without a redesign.\nconst OWNER_TYPES = [{ value: 'FACILITY', label: 'Facility' }];\n\nexport default function StorageUnitsPage() {\n const perms = usePmPermissions();\n const canWrite = perms.has('update.manage.productManagement.storageUnit');\n const [items, setItems] = useState([]);\n // Map of facility id → name, hydrated for the ownerIds present on the\n // loaded storage units. Avoids loading the entire facility table just to\n // render the \"Facility\" column.\n const [facilityNames, setFacilityNames] = 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 const [form, setForm] = useState(emptyForm());\n const fieldErrors = useFieldErrors();\n\n function emptyForm() {\n return {\n id: '',\n ownerType: 'FACILITY',\n ownerId: '',\n unitName: '',\n unitCode: '',\n unitType: 'REFRIGERATOR',\n make: '',\n model: '',\n comments: '',\n operatingTempMinCelsius: '',\n operatingTempMaxCelsius: '',\n isActive: true,\n };\n }\n\n async function load() {\n setLoading(true);\n setError('');\n try {\n const units = await getStorageUnits({ activeOnly: false });\n setItems(units);\n // Hydrate display names only for the facilities actually referenced\n // by the loaded units. Storage units are short — even the largest\n // deployment is a few hundred — so this is one cheap call.\n const ids = Array.from(new Set(units.map((u) => u.ownerId).filter(Boolean)));\n if (ids.length === 0) {\n setFacilityNames({});\n } else {\n try {\n const refs = await getFacilitiesByIds(ids);\n const map = {};\n refs.forEach((r) => { map[r.id] = r.name; });\n setFacilityNames(map);\n } catch {\n setFacilityNames({});\n }\n }\n } catch (err) {\n const message = err?.response?.data?.message ?? err?.message ?? 'Failed to load storage units';\n setError(message);\n showToast({ message, type: 'error' });\n } finally {\n setLoading(false);\n }\n }\n\n usePermissionedEffect('view.manage.productManagement.storageUnit', () => {\n void load();\n }, []);\n\n function facilityNameFor(id) {\n return facilityNames[id] ?? id;\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 setEditing(item);\n fieldErrors.reset();\n setError('');\n setForm({\n id: item.id,\n ownerType: item.ownerType ?? 'FACILITY',\n ownerId: item.ownerId ?? '',\n unitName: item.unitName ?? '',\n unitCode: item.unitCode ?? '',\n unitType: item.unitType ?? 'REFRIGERATOR',\n make: item.make ?? '',\n model: item.model ?? '',\n comments: item.comments ?? '',\n operatingTempMinCelsius: item.operatingTempMinCelsius ?? '',\n operatingTempMaxCelsius: item.operatingTempMaxCelsius ?? '',\n isActive: item.isActive !== false,\n });\n setOpenDialog(true);\n }\n\n const tempErrors = validateTempRange(form.operatingTempMinCelsius, form.operatingTempMaxCelsius);\n // Code uniqueness is enforced per facility in the DB. Mirror that scope here so\n // the operator gets the duplicate warning inline instead of as a 500 after save.\n const codeBase = validateCode(form.unitCode, { required: true });\n const codeNorm = (form.unitCode || '').trim().toUpperCase();\n const codeClash = !codeBase\n && codeNorm\n && form.ownerId\n && items.some((u) => u.id !== form.id\n && u.ownerId === form.ownerId\n && (u.unitCode || '').toUpperCase() === codeNorm);\n const formErrors = {\n ownerType: validateRequired(form.ownerType, 'Owner type'),\n ownerId: validateRequired(form.ownerId, 'Facility'),\n unitName: validateRequired(form.unitName, 'Name'),\n unitCode: codeBase || (codeClash ? 'Code is already in use for this facility.' : ''),\n unitType: validateRequired(form.unitType, 'Type'),\n operatingTempMinCelsius: tempErrors.min,\n operatingTempMaxCelsius: tempErrors.max,\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 upsertStorageUnit({\n id: form.id,\n ownerId: form.ownerId,\n unitName: form.unitName.trim(),\n unitCode: form.unitCode.trim().toUpperCase(),\n unitType: form.unitType,\n make: form.make?.trim() || null,\n model: form.model?.trim() || null,\n comments: form.comments?.trim() || null,\n operatingTempMinCelsius: form.operatingTempMinCelsius === '' ? null : Number(form.operatingTempMinCelsius),\n operatingTempMaxCelsius: form.operatingTempMaxCelsius === '' ? null : Number(form.operatingTempMaxCelsius),\n isActive: form.isActive,\n });\n showToast({ message: 'Storage unit saved.', type: 'success' });\n setOpenDialog(false);\n await load();\n } catch (err) {\n const message = err?.response?.data?.message ?? err?.message ?? 'Failed to save storage unit';\n setError(message);\n showToast({ message, type: 'error' });\n }\n }\n\n return (\n <Box>\n <PmNav />\n <PmGuard perm={'view.manage.productManagement.storageUnit'}>\n <PmPageShell\n title=\"Storage Units\"\n subtitle=\"Cold-chain equipment for storing vaccine and product batches. Currently managed per facility.\"\n chips={['Catalog', 'Facility-owned']}\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 Storage Unit</Button>\n ) : null}\n </Stack>\n }\n >\n {error ? <Alert severity=\"error\" sx={{ mb: 2 }}>{error}</Alert> : null}\n\n <PmTableCard\n eyebrow=\"Cold-chain network\"\n title=\"Storage units\"\n subtitle={loading ? 'Loading…' : `${items.length} ${items.length === 1 ? 'unit' : 'units'}`}\n >\n <PmTable>\n <TableHead>\n <TableRow>\n <TableCell>Code</TableCell>\n <TableCell>Name</TableCell>\n <TableCell>Facility</TableCell>\n <TableCell>Type</TableCell>\n <TableCell>Operating range</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: 7 }).map((__, j) => (\n <TableCell key={j}><Skeleton height={22} /></TableCell>\n ))}\n </TableRow>\n ))\n ) : items.length === 0 ? (\n <PmEmptyRow\n colSpan={7}\n icon={WarehouseRoundedIcon}\n title=\"No storage units yet\"\n hint=\"You need storage equipment to keep vaccine batches safe.\"\n action={canWrite ? (\n <Button variant=\"contained\" size=\"small\" startIcon={<AddRoundedIcon />} onClick={openCreate}>\n Create first unit\n </Button>\n ) : null}\n />\n ) : items.map((u) => (\n <TableRow key={u.id} hover>\n <TableCell>\n <Box component=\"span\" sx={{\n display: 'inline-flex', px: 0.85, py: 0.25, borderRadius: 1,\n bgcolor: 'grey.100', fontFamily: 'monospace', fontSize: '0.72rem', fontWeight: 800,\n }}>\n {u.unitCode}\n </Box>\n </TableCell>\n <TableCell><Typography variant=\"body2\" sx={{ fontWeight: 700 }}>{u.unitName}</Typography></TableCell>\n <TableCell><Typography variant=\"caption\" color=\"text.secondary\">{facilityNameFor(u.ownerId)}</Typography></TableCell>\n <TableCell>\n <Chip size=\"small\" label={labelOf(STORAGE_UNIT_TYPES, u.unitType)} variant=\"outlined\"\n sx={{ fontWeight: 700, borderRadius: 1.5, height: 22 }} />\n </TableCell>\n <TableCell>\n {u.operatingTempMinCelsius != null && u.operatingTempMaxCelsius != null ? (\n <Typography variant=\"caption\" sx={{ fontWeight: 700, fontVariantNumeric: 'tabular-nums' }}>\n {u.operatingTempMinCelsius}°C → {u.operatingTempMaxCelsius}°C\n </Typography>\n ) : <Typography variant=\"caption\" color=\"text.disabled\">—</Typography>}\n </TableCell>\n <TableCell>\n <Chip size=\"small\"\n label={u.isActive ? 'Active' : 'Inactive'}\n color={u.isActive ? 'success' : 'default'}\n variant={u.isActive ? 'filled' : 'outlined'}\n sx={{ fontWeight: 700, borderRadius: 1.5, height: 22 }} />\n </TableCell>\n <TableCell align=\"right\">\n {canWrite ? (\n <Button size=\"small\" variant=\"outlined\" onClick={() => openEdit(u)}>Edit</Button>\n ) : null}\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </PmTable>\n </PmTableCard>\n </PmPageShell>\n\n <Dialog open={openDialog} onClose={() => setOpenDialog(false)} fullWidth maxWidth=\"sm\">\n <DialogTitle>{editing ? 'Edit Storage Unit' : 'New Storage Unit'}</DialogTitle>\n <DialogContent dividers>\n <Stack spacing={2} sx={{ pt: 1 }}>\n\n {/* ------- Ownership: who this storage unit belongs to ------- */}\n <FormControl required fullWidth size=\"small\"\n disabled={!!editing}\n error={fieldErrors.show('ownerType') && !!formErrors.ownerType}>\n <InputLabel>Owner Type</InputLabel>\n <Select label=\"Owner Type\" value={form.ownerType}\n onChange={(e) => setForm({ ...form, ownerType: e.target.value, ownerId: '' })}\n onBlur={fieldErrors.onBlur('ownerType')}>\n {OWNER_TYPES.map((o) => <MenuItem key={o.value} value={o.value}>{o.label}</MenuItem>)}\n </Select>\n <FormHelperText>\n {fieldErrors.show('ownerType') && formErrors.ownerType\n ? formErrors.ownerType\n : 'Only Facility is available currently.'}\n </FormHelperText>\n </FormControl>\n\n <FacilityPicker\n required\n disabled={!!editing || form.ownerType !== 'FACILITY'}\n value={form.ownerId}\n onChange={(id) => setForm({ ...form, ownerId: id })}\n onBlur={fieldErrors.onBlur('ownerId')}\n error={fieldErrors.show('ownerId') && !!formErrors.ownerId}\n helperText={\n fieldErrors.show('ownerId') && formErrors.ownerId\n ? formErrors.ownerId\n : 'Search by name. The owner cannot be changed once created.'\n }\n />\n\n <Divider />\n\n {/* ------- Unit details ------- */}\n <TextField\n required\n label=\"Unit name\" size=\"small\" fullWidth\n value={form.unitName}\n onChange={(e) => {\n const nextName = e.target.value;\n // Derive a default code from the name on create — initials, A-Z/0-9\n // only. We never overwrite a code on edit (it's already curated and\n // ownerCode-scoped uniqueness depends on it).\n const auto = nextName\n .split(/\\s+/)\n .filter(Boolean)\n .map((w) => w[0])\n .join('')\n .toUpperCase()\n .replace(/[^A-Z0-9_]/g, '');\n setForm((f) => ({\n ...f,\n unitName: nextName,\n unitCode: editing ? f.unitCode : auto,\n }));\n }}\n onBlur={fieldErrors.onBlur('unitName')}\n error={fieldErrors.show('unitName') && !!formErrors.unitName}\n helperText={fieldErrors.show('unitName') ? formErrors.unitName : ''}\n />\n <TextField\n required\n label=\"Unit code (unique within facility)\" size=\"small\" fullWidth\n value={form.unitCode}\n onChange={(e) => setForm({ ...form, unitCode: e.target.value.toUpperCase() })}\n onBlur={fieldErrors.onBlur('unitCode')}\n error={fieldErrors.show('unitCode') && !!formErrors.unitCode}\n helperText={\n fieldErrors.show('unitCode') && formErrors.unitCode\n ? formErrors.unitCode\n : 'Auto-generated from the name. Edit if needed to make it unique within this facility.'\n }\n />\n <FormControl required fullWidth size=\"small\"\n error={fieldErrors.show('unitType') && !!formErrors.unitType}>\n <InputLabel>Type</InputLabel>\n <Select label=\"Type\" value={form.unitType}\n onChange={(e) => setForm({ ...form, unitType: e.target.value })}\n onBlur={fieldErrors.onBlur('unitType')}>\n {STORAGE_UNIT_TYPES.map((t) => <MenuItem key={t.value} value={t.value}>{t.label}</MenuItem>)}\n </Select>\n </FormControl>\n\n <Stack direction=\"row\" spacing={2}>\n <TextField label=\"Make\" size=\"small\" fullWidth\n value={form.make}\n onChange={(e) => setForm({ ...form, make: e.target.value })}\n helperText=\"Example: Godrej, Vestfrost\" />\n <TextField label=\"Model\" size=\"small\" fullWidth\n value={form.model}\n onChange={(e) => setForm({ ...form, model: e.target.value })}\n helperText=\"Example: GVR-100\" />\n </Stack>\n <Stack direction=\"row\" spacing={2}>\n <TextField\n label=\"Min °C\" size=\"small\" type=\"number\" fullWidth\n inputProps={{ step: '0.1', min: -90, max: 30 }}\n value={form.operatingTempMinCelsius}\n onChange={(e) => setForm({ ...form, operatingTempMinCelsius: e.target.value })}\n onBlur={fieldErrors.onBlur('operatingTempMinCelsius')}\n error={fieldErrors.show('operatingTempMinCelsius') && !!formErrors.operatingTempMinCelsius}\n helperText={\n fieldErrors.show('operatingTempMinCelsius') && formErrors.operatingTempMinCelsius\n ? formErrors.operatingTempMinCelsius\n : 'Allowed range: −90°C to +30°C'\n }\n />\n <TextField\n label=\"Max °C\" size=\"small\" type=\"number\" fullWidth\n inputProps={{ step: '0.1', min: -90, max: 30 }}\n value={form.operatingTempMaxCelsius}\n onChange={(e) => setForm({ ...form, operatingTempMaxCelsius: e.target.value })}\n onBlur={fieldErrors.onBlur('operatingTempMaxCelsius')}\n error={fieldErrors.show('operatingTempMaxCelsius') && !!formErrors.operatingTempMaxCelsius}\n helperText={\n fieldErrors.show('operatingTempMaxCelsius') && formErrors.operatingTempMaxCelsius\n ? formErrors.operatingTempMaxCelsius\n : 'Allowed range: −90°C to +30°C'\n }\n />\n </Stack>\n <TextField label=\"Comments\" size=\"small\" multiline minRows={2} fullWidth\n value={form.comments}\n onChange={(e) => setForm({ ...form, comments: e.target.value })}\n helperText=\"Notes about placement, maintenance schedule, or other details.\" />\n <FormControlLabel control={<Checkbox checked={form.isActive}\n onChange={(e) => setForm({ ...form, isActive: e.target.checked })} />} 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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"}