@burdenoff/microfe-assethandler 2026.813.2 → 2026.817.1
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/assethandler/hooks/useMaintenancePlans.d.ts +2 -0
- package/dist/assethandler/hooks/useMaintenancePlans.d.ts.map +1 -1
- package/dist/assethandler/hooks/useMaintenancePlans.js +1 -0
- package/dist/assethandler/hooks/useMaintenancePlans.js.map +1 -1
- package/dist/assethandler/ops/MaintenancePlanDialog.js +14 -7
- package/dist/assethandler/ops/MaintenancePlanDialog.js.map +1 -1
- package/dist/assethandler/pages/AssetsAssetCreatePage.d.ts.map +1 -1
- package/dist/assethandler/pages/AssetsAssetCreatePage.js +115 -101
- package/dist/assethandler/pages/AssetsAssetCreatePage.js.map +1 -1
- package/dist/assethandler/pages/AssetsAssetDetailPage.d.ts.map +1 -1
- package/dist/assethandler/pages/AssetsAssetDetailPage.js +121 -102
- package/dist/assethandler/pages/AssetsAssetDetailPage.js.map +1 -1
- package/dist/assethandler/pages/MaintenanceMaintenancePlansPage.d.ts.map +1 -1
- package/dist/assethandler/pages/MaintenanceMaintenancePlansPage.js +119 -114
- package/dist/assethandler/pages/MaintenanceMaintenancePlansPage.js.map +1 -1
- package/dist/assethandler/providers/AssetHandlerProvider.d.ts.map +1 -1
- package/dist/assethandler/providers/AssetHandlerProvider.js +85 -35
- package/dist/assethandler/providers/AssetHandlerProvider.js.map +1 -1
- package/dist/assethandler/store/assethandlerStore.d.ts +3 -0
- package/dist/assethandler/store/assethandlerStore.d.ts.map +1 -1
- package/dist/assethandler/store/assethandlerStore.js +20 -19
- package/dist/assethandler/store/assethandlerStore.js.map +1 -1
- package/dist/assethandler/utils/meter.d.ts +51 -0
- package/dist/assethandler/utils/meter.d.ts.map +1 -0
- package/dist/assethandler/utils/meter.js +51 -0
- package/dist/assethandler/utils/meter.js.map +1 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AssetsAssetCreatePage.js","names":[],"sources":["../../../src/assethandler/pages/AssetsAssetCreatePage.tsx"],"sourcesContent":["import { useAssetHandlerNavigate } from '../hooks/useAssetHandlerNavigate';\nimport {\n formatAssetCategory,\n useAssetCategoryPresentation,\n useAssetMoney,\n useHiddenCategoryIds,\n} from '../providers/AssetHandlerProvider';\nimport { useMemo, useRef, useState, type KeyboardEvent } from 'react';\nimport {\n Button,\n GlassCard,\n Input,\n Label,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Textarea,\n GradientText,\n PagePurpose,\n Badge,\n} from '@burdenoff/fe-libs/ui';\nimport { ArrowLeft, Loader2, Save, X, TrendingDown, Info } from 'lucide-react';\nimport { gql } from '@apollo/client';\nimport { useMutation } from '@apollo/client/react';\nimport { notify } from '../utils/toast';\nimport { useAssetHandlerStore } from '../store/assethandlerStore';\nimport { ChartCard, TrendChart } from '../components';\nimport { useCopy } from '../hooks/useCopy';\n\nconst CREATE_ASSET_MUTATION = gql`\n mutation AssetHandlerCreateAsset($input: CreateAssetInput!) {\n createAsset(input: $input) {\n id\n assetNumber\n name\n }\n }\n`;\n\nconst BASE_CATEGORY_OPTIONS = [\n 'electronics',\n 'it_hardware',\n 'furniture',\n 'vehicles',\n 'equipment',\n 'software',\n 'networking',\n 'servers',\n];\n\ninterface FormState {\n name: string;\n description: string;\n category: string;\n status: string;\n condition: string;\n serialNumber: string;\n assetNumber: string;\n locationName: string;\n assignedTo: string;\n purchaseValue: string;\n purchaseDate: string;\n usefulLifeMonths: string;\n salvageValue: string;\n depreciationMethod: string;\n unitsOfProductionCapacity: string;\n unitsProduced: string;\n warrantyExpiry: string;\n supplier: string;\n department: string;\n}\n\nconst INITIAL_FORM: FormState = {\n name: '',\n description: '',\n category: 'it_hardware',\n status: 'ACTIVE',\n condition: 'GOOD',\n serialNumber: '',\n assetNumber: '',\n locationName: '',\n assignedTo: '',\n purchaseValue: '',\n purchaseDate: '',\n usefulLifeMonths: '',\n salvageValue: '',\n depreciationMethod: 'STRAIGHT_LINE',\n unitsOfProductionCapacity: '',\n unitsProduced: '',\n warrantyExpiry: '',\n supplier: '',\n department: '',\n};\n\n// Pure derivation of a book-value schedule from the user's own inputs. Returns\n// an empty array when the essentials are missing — never fabricates a curve.\n// Mirrors wspace-assethandler-svc's computeDepreciation formulas per method\n// (annualized here for a compact preview chart; the server computes the\n// authoritative month-granular currentValue/accumulatedDepreciation).\nfunction buildDepreciationSeries(input: {\n purchaseValue: number | null;\n salvageValue: number | null;\n usefulLifeMonths: number | null;\n method: string;\n unitsOfProductionCapacity: number | null;\n unitsProduced: number | null;\n}): { year: number; bookValue: number }[] {\n const pv = input.purchaseValue;\n const life = input.usefulLifeMonths;\n if (!pv || pv <= 0 || !life || life <= 0) return [];\n const salvage = Math.max(0, Math.min(input.salvageValue ?? 0, pv));\n const method = input.method.toLowerCase();\n const years = Math.max(1, Math.round(life / 12));\n\n if (method === 'units_of_production') {\n const capacity = input.unitsOfProductionCapacity;\n const produced = Math.max(0, input.unitsProduced ?? 0);\n if (!capacity || capacity <= 0) return [];\n // Straight-line-by-usage preview: assumes even production across the\n // asset's life up to the units produced so far, then flat afterward.\n const bvAtProduced = Math.max(\n pv - (pv - salvage) * (Math.min(produced, capacity) / capacity),\n salvage\n );\n return [\n { year: 0, bookValue: Math.round(pv) },\n { year: years, bookValue: Math.round(bvAtProduced) },\n ];\n }\n\n const points: { year: number; bookValue: number }[] = [];\n for (let y = 0; y <= years; y += 1) {\n let bv: number;\n if (method === 'reducing_balance') {\n const rate = salvage > 0 ? 1 - Math.pow(salvage / pv, 1 / years) : Math.min(0.9, 2 / years);\n bv = Math.max(pv * Math.pow(1 - rate, y), salvage);\n } else if (method === 'declining_balance') {\n const rate =\n salvage > 0 ? 1 - Math.pow(salvage / pv, 1 / years) : Math.min(0.75, 1.5 / years);\n bv = Math.max(pv * Math.pow(1 - rate, y), salvage);\n } else if (method === 'sum_of_years_digits') {\n const syd = (years * (years + 1)) / 2;\n const cumulative = syd > 0 ? (pv - salvage) * ((y * years - (y * (y - 1)) / 2) / syd) : 0;\n bv = Math.max(pv - cumulative, salvage);\n } else if (method === 'none') {\n bv = pv;\n } else {\n bv = Math.max(pv - (pv - salvage) * (y / years), salvage);\n }\n points.push({ year: y, bookValue: Math.round(bv) });\n }\n return points;\n}\n\nconst SectionCard = ({\n title,\n description,\n children,\n glow,\n}: {\n title: string;\n description?: string;\n children: React.ReactNode;\n glow?: boolean;\n}) => (\n <GlassCard treatment=\"glass\" glow={glow} className=\"border-border-seam\">\n <div className=\"space-y-4 p-5 sm:p-6\">\n <div>\n <h2 className=\"text-lg font-semibold\">{title}</h2>\n {description ? <p className=\"mt-0.5 text-sm text-text-secondary\">{description}</p> : null}\n </div>\n {children}\n </div>\n </GlassCard>\n);\n\nexport function AssetsAssetCreatePage() {\n const tc = useCopy();\n const navigate = useAssetHandlerNavigate();\n const { symbol: currencySymbolGlyph, compact: moneyCompact } = useAssetMoney();\n const hiddenCategories = useHiddenCategoryIds();\n const { labels: categoryLabels, options: configuredCategoryOptions } =\n useAssetCategoryPresentation();\n const { assets } = useAssetHandlerStore();\n const [formData, setFormData] = useState<FormState>(INITIAL_FORM);\n const [tags, setTags] = useState<string[]>([]);\n const [tagInput, setTagInput] = useState('');\n const [errors, setErrors] = useState<Record<string, string>>({});\n const [submitMode, setSubmitMode] = useState<'create' | 'add' | null>(null);\n const addAnotherRef = useRef(false);\n\n const categoryOptions = useMemo(() => {\n const set = new Set<string>(\n configuredCategoryOptions?.map((category) => category.id) ?? BASE_CATEGORY_OPTIONS\n );\n if (!configuredCategoryOptions) {\n for (const a of assets) if (a.category) set.add(a.category);\n }\n return [...set].filter((c) => !hiddenCategories.has(c)).sort();\n }, [assets, configuredCategoryOptions, hiddenCategories]);\n\n const [createAsset, { loading: creating }] = useMutation<{\n createAsset: { id: string; assetNumber: string; name: string };\n }>(CREATE_ASSET_MUTATION, {\n refetchQueries: ['AssetHandlerBootstrap'],\n onCompleted: (data) => {\n notify.success(\n tc('assethandler.assets.create.toast.title', '{{asset}} created'),\n tc('assethandler.assets.create.toast.body', '{{name}} was registered in the inventory.', {\n name: data.createAsset.name,\n })\n );\n setSubmitMode(null);\n if (addAnotherRef.current) {\n addAnotherRef.current = false;\n setFormData(INITIAL_FORM);\n setTags([]);\n setTagInput('');\n setErrors({});\n if (typeof window !== 'undefined') window.scrollTo({ top: 0, behavior: 'smooth' });\n } else {\n navigate(`/assets/${data.createAsset.id}`);\n }\n },\n onError: (error) => {\n setSubmitMode(null);\n notify.error('Could not create asset', error.message);\n },\n });\n\n const handleChange = (field: keyof FormState, value: string) => {\n setFormData((prev) => ({ ...prev, [field]: value }));\n setErrors((prev) => {\n if (!prev[field]) return prev;\n const next = { ...prev };\n delete next[field];\n return next;\n });\n };\n\n const commitTag = () => {\n const value = tagInput.trim().replace(/,$/, '').trim();\n if (value && !tags.includes(value)) setTags((prev) => [...prev, value]);\n setTagInput('');\n };\n const onTagKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter' || e.key === ',') {\n e.preventDefault();\n commitTag();\n } else if (e.key === 'Backspace' && tagInput === '' && tags.length > 0) {\n setTags((prev) => prev.slice(0, -1));\n }\n };\n\n const depreciationPreview = useMemo(\n () =>\n buildDepreciationSeries({\n purchaseValue: formData.purchaseValue.trim() ? Number(formData.purchaseValue) : null,\n salvageValue: formData.salvageValue.trim() ? Number(formData.salvageValue) : null,\n usefulLifeMonths: formData.usefulLifeMonths.trim()\n ? Number(formData.usefulLifeMonths)\n : null,\n method: formData.depreciationMethod,\n unitsOfProductionCapacity: formData.unitsOfProductionCapacity.trim()\n ? Number(formData.unitsOfProductionCapacity)\n : null,\n unitsProduced: formData.unitsProduced.trim() ? Number(formData.unitsProduced) : null,\n }),\n [\n formData.purchaseValue,\n formData.salvageValue,\n formData.usefulLifeMonths,\n formData.depreciationMethod,\n formData.unitsOfProductionCapacity,\n formData.unitsProduced,\n ]\n );\n\n const submit = (addAnother: boolean) => {\n const nextErrors: Record<string, string> = {};\n if (!formData.name.trim()) nextErrors.name = 'Asset name is required';\n if (!formData.assetNumber.trim()) nextErrors.assetNumber = 'Asset tag is required';\n if (!formData.category.trim()) nextErrors.category = 'Category is required';\n\n const numericField = (value: string, label: string, key: string) => {\n if (value.trim() === '') return;\n const parsed = Number(value);\n if (Number.isNaN(parsed) || parsed < 0)\n nextErrors[key] = `${label} must be a positive number`;\n };\n numericField(formData.purchaseValue, 'Purchase value', 'purchaseValue');\n numericField(formData.salvageValue, 'Salvage value', 'salvageValue');\n numericField(formData.usefulLifeMonths, 'Useful life', 'usefulLifeMonths');\n\n setErrors(nextErrors);\n if (Object.keys(nextErrors).length > 0) {\n notify.warning('Missing required fields', 'Fill in the highlighted fields and try again.');\n return;\n }\n\n const optionalNumber = (value: string): number | null => {\n const trimmed = value.trim();\n if (trimmed === '') return null;\n const parsed = Number(trimmed);\n return Number.isNaN(parsed) ? null : parsed;\n };\n const optionalDate = (value: string): string | null =>\n value.trim() === '' ? null : new Date(value).toISOString();\n\n addAnotherRef.current = addAnother;\n setSubmitMode(addAnother ? 'add' : 'create');\n void createAsset({\n variables: {\n input: {\n name: formData.name.trim(),\n assetNumber: formData.assetNumber.trim(),\n category: formData.category,\n status: formData.status,\n condition: formData.condition,\n description: formData.description.trim() || null,\n serialNumber: formData.serialNumber.trim() || null,\n locationName: formData.locationName.trim() || null,\n assignedTo: formData.assignedTo.trim() || null,\n tags,\n purchaseValue: optionalNumber(formData.purchaseValue),\n purchaseDate: optionalDate(formData.purchaseDate),\n usefulLifeMonths: optionalNumber(formData.usefulLifeMonths),\n salvageValue: optionalNumber(formData.salvageValue),\n depreciationMethod: formData.depreciationMethod,\n unitsOfProductionCapacity: optionalNumber(formData.unitsOfProductionCapacity),\n unitsProduced: optionalNumber(formData.unitsProduced),\n warrantyExpiry: optionalDate(formData.warrantyExpiry),\n supplier: formData.supplier.trim() || null,\n department: formData.department.trim() || null,\n },\n },\n });\n };\n\n return (\n <div className=\"mx-auto max-w-4xl space-y-6 p-4 pb-28 sm:p-6 sm:pb-28\">\n {/* Header */}\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:gap-4\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n aria-label=\"Go back\"\n className=\"w-fit\"\n onClick={() => navigate('/assets/asset-list')}\n >\n <ArrowLeft className=\"h-4 w-4\" />\n </Button>\n <div>\n <h1 className=\"text-2xl font-bold\">\n <GradientText>\n {tc('assethandler.assets.create.title', 'Create New {{asset}}')}\n </GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n {tc(\n 'assethandler.assets.create.subtitle',\n 'Register a new {{assetLower}} in the inventory'\n )}{' '}\n · <span className=\"text-status-error-text\">*</span> required\n </p>\n </div>\n </div>\n\n <PagePurpose>\n {tc(\n 'assethandler.assets.create.purpose',\n 'Register a new {{assetLower}} so it can be tracked, maintained and assigned from day one. Capture its identity, category and condition, then its financials and location — the more you fill in now, the better your reports and audits later.'\n )}\n </PagePurpose>\n\n {/* General Information */}\n <SectionCard\n title=\"General Information\"\n description={tc(\n 'assethandler.assets.create.general.description',\n 'Basic {{assetLower}} details and identification'\n )}\n glow\n >\n <div className=\"grid gap-4 md:grid-cols-2\">\n <div className=\"space-y-2\">\n <Label>\n {tc('assethandler.assets.create.field.name', '{{asset}} Name')}{' '}\n <span className=\"text-status-error-text\">*</span>\n </Label>\n <Input\n placeholder={tc(\n 'assethandler.assets.create.field.namePlaceholder',\n 'e.g., Dell OptiPlex 7090'\n )}\n value={formData.name}\n onChange={(e) => handleChange('name', e.target.value)}\n aria-invalid={!!errors.name}\n />\n {errors.name ? <p className=\"text-xs text-status-error-text\">{errors.name}</p> : null}\n </div>\n <div className=\"space-y-2\">\n <Label>\n {tc('assethandler.assets.create.field.tag', '{{asset}} Tag')}{' '}\n <span className=\"text-status-error-text\">*</span>\n </Label>\n <Input\n placeholder={tc('assethandler.assets.create.field.tagPlaceholder', 'e.g., IT-HW-001')}\n value={formData.assetNumber}\n onChange={(e) => handleChange('assetNumber', e.target.value)}\n aria-invalid={!!errors.assetNumber}\n />\n {errors.assetNumber ? (\n <p className=\"text-xs text-status-error-text\">{errors.assetNumber}</p>\n ) : null}\n </div>\n </div>\n <div className=\"space-y-2\">\n <Label>Description</Label>\n <Textarea\n placeholder={tc(\n 'assethandler.assets.create.field.descriptionPlaceholder',\n 'Brief description of the {{assetLower}}...'\n )}\n value={formData.description}\n onChange={(e) => handleChange('description', e.target.value)}\n rows={3}\n />\n </div>\n <div className=\"grid gap-4 md:grid-cols-3\">\n <div className=\"space-y-2\">\n <Label>\n Category <span className=\"text-status-error-text\">*</span>\n </Label>\n <Select value={formData.category} onValueChange={(v) => handleChange('category', v)}>\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {categoryOptions.map((category) => (\n <SelectItem key={category} value={category} className=\"capitalize\">\n {configuredCategoryOptions?.find((option) => option.id === category)?.label ??\n formatAssetCategory(category, categoryLabels)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"space-y-2\">\n <Label>Status</Label>\n <Select value={formData.status} onValueChange={(v) => handleChange('status', v)}>\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"ACTIVE\">Active</SelectItem>\n <SelectItem value=\"INACTIVE\">Inactive</SelectItem>\n <SelectItem value=\"MAINTENANCE\">Maintenance</SelectItem>\n <SelectItem value=\"RETIRED\">Retired</SelectItem>\n </SelectContent>\n </Select>\n </div>\n <div className=\"space-y-2\">\n <Label>Condition</Label>\n <Select value={formData.condition} onValueChange={(v) => handleChange('condition', v)}>\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"EXCELLENT\">Excellent</SelectItem>\n <SelectItem value=\"GOOD\">Good</SelectItem>\n <SelectItem value=\"FAIR\">Fair</SelectItem>\n <SelectItem value=\"POOR\">Poor</SelectItem>\n <SelectItem value=\"DAMAGED\">Damaged</SelectItem>\n </SelectContent>\n </Select>\n </div>\n </div>\n <div className=\"space-y-2\">\n <Label>Serial Number</Label>\n <Input\n placeholder=\"e.g., DELL-7090-X1A2B3\"\n value={formData.serialNumber}\n onChange={(e) => handleChange('serialNumber', e.target.value)}\n />\n </div>\n </SectionCard>\n\n {/* Financial Details */}\n <SectionCard\n title=\"Financial Details\"\n description=\"Purchase and depreciation data powers book value, TCO and finance reports\"\n >\n <div className=\"grid gap-4 md:grid-cols-3\">\n <div className=\"space-y-2\">\n <Label>Purchase Value</Label>\n <div className=\"relative\">\n <span className=\"pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-sm text-text-secondary\">\n {currencySymbolGlyph}\n </span>\n <Input\n type=\"number\"\n min=\"0\"\n step=\"0.01\"\n placeholder=\"1200\"\n className=\"pl-7\"\n value={formData.purchaseValue}\n onChange={(e) => handleChange('purchaseValue', e.target.value)}\n aria-invalid={!!errors.purchaseValue}\n />\n </div>\n {errors.purchaseValue ? (\n <p className=\"text-xs text-status-error-text\">{errors.purchaseValue}</p>\n ) : null}\n </div>\n <div className=\"space-y-2\">\n <Label>Purchase Date</Label>\n <Input\n type=\"date\"\n value={formData.purchaseDate}\n onChange={(e) => handleChange('purchaseDate', e.target.value)}\n />\n </div>\n <div className=\"space-y-2\">\n <Label>Supplier</Label>\n <Input\n placeholder=\"e.g., Dell Technologies\"\n value={formData.supplier}\n onChange={(e) => handleChange('supplier', e.target.value)}\n />\n </div>\n </div>\n <div className=\"grid gap-4 md:grid-cols-3\">\n <div className=\"space-y-2\">\n <Label>Useful Life</Label>\n <div className=\"relative\">\n <Input\n type=\"number\"\n min=\"0\"\n step=\"1\"\n placeholder=\"60\"\n className=\"pr-16\"\n value={formData.usefulLifeMonths}\n onChange={(e) => handleChange('usefulLifeMonths', e.target.value)}\n aria-invalid={!!errors.usefulLifeMonths}\n />\n <span className=\"pointer-events-none absolute right-3 top-1/2 -translate-y-1/2 text-sm text-text-secondary\">\n months\n </span>\n </div>\n {errors.usefulLifeMonths ? (\n <p className=\"text-xs text-status-error-text\">{errors.usefulLifeMonths}</p>\n ) : null}\n </div>\n <div className=\"space-y-2\">\n <Label>Salvage Value</Label>\n <div className=\"relative\">\n <span className=\"pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-sm text-text-secondary\">\n {currencySymbolGlyph}\n </span>\n <Input\n type=\"number\"\n min=\"0\"\n step=\"0.01\"\n placeholder=\"100\"\n className=\"pl-7\"\n value={formData.salvageValue}\n onChange={(e) => handleChange('salvageValue', e.target.value)}\n aria-invalid={!!errors.salvageValue}\n />\n </div>\n {errors.salvageValue ? (\n <p className=\"text-xs text-status-error-text\">{errors.salvageValue}</p>\n ) : null}\n </div>\n <div className=\"space-y-2\">\n <Label>Depreciation Method</Label>\n <Select\n value={formData.depreciationMethod}\n onValueChange={(v) => handleChange('depreciationMethod', v)}\n >\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"STRAIGHT_LINE\">Straight line</SelectItem>\n <SelectItem value=\"REDUCING_BALANCE\">Reducing balance (200%)</SelectItem>\n <SelectItem value=\"DECLINING_BALANCE\">Declining balance (150%)</SelectItem>\n <SelectItem value=\"SUM_OF_YEARS_DIGITS\">Sum of years' digits</SelectItem>\n <SelectItem value=\"UNITS_OF_PRODUCTION\">Units of production</SelectItem>\n <SelectItem value=\"NONE\">None</SelectItem>\n </SelectContent>\n </Select>\n </div>\n </div>\n {formData.depreciationMethod === 'UNITS_OF_PRODUCTION' ? (\n <div className=\"grid gap-4 md:grid-cols-2\">\n <div className=\"space-y-2\">\n <Label>Lifetime Capacity (units)</Label>\n <Input\n type=\"number\"\n min=\"0\"\n step=\"1\"\n placeholder=\"e.g., 100000 (miles, hours, cycles…)\"\n value={formData.unitsOfProductionCapacity}\n onChange={(e) => handleChange('unitsOfProductionCapacity', e.target.value)}\n />\n </div>\n <div className=\"space-y-2\">\n <Label>Units Produced To Date</Label>\n <Input\n type=\"number\"\n min=\"0\"\n step=\"1\"\n placeholder=\"0\"\n value={formData.unitsProduced}\n onChange={(e) => handleChange('unitsProduced', e.target.value)}\n />\n </div>\n </div>\n ) : null}\n <div className=\"space-y-2\">\n <Label>Warranty Expiry</Label>\n <Input\n type=\"date\"\n value={formData.warrantyExpiry}\n onChange={(e) => handleChange('warrantyExpiry', e.target.value)}\n />\n </div>\n\n {/* Live depreciation preview */}\n <ChartCard\n title=\"Depreciation preview\"\n subtitle={tc(\n 'assethandler.assets.create.depreciation.subtitle',\n \"Projected book value over the {{assetLower}}'s useful life\"\n )}\n icon={TrendingDown}\n >\n {depreciationPreview.length > 0 ? (\n <TrendChart\n data={depreciationPreview}\n xKey=\"year\"\n height={240}\n valueFormat={moneyCompact}\n xTickFormat={(v) => `${v}y`}\n series={[{ key: 'bookValue', label: 'Book value' }]}\n />\n ) : (\n <div className=\"flex flex-col items-center gap-2 py-10 text-center text-sm text-text-secondary\">\n <Info className=\"h-5 w-5 text-text-muted\" />\n Enter a purchase value and useful life to preview the depreciation schedule.\n </div>\n )}\n </ChartCard>\n </SectionCard>\n\n {/* Assignment & Location */}\n <SectionCard title=\"Assignment & Location\" description=\"Who holds it and where it lives\">\n <div className=\"grid gap-4 md:grid-cols-2\">\n <div className=\"space-y-2\">\n <Label>Assigned To</Label>\n <Input\n placeholder=\"e.g., john.smith@company.com\"\n value={formData.assignedTo}\n onChange={(e) => handleChange('assignedTo', e.target.value)}\n />\n </div>\n <div className=\"space-y-2\">\n <Label>Location</Label>\n <Input\n placeholder=\"e.g., Building A, Floor 3, Desk 15\"\n value={formData.locationName}\n onChange={(e) => handleChange('locationName', e.target.value)}\n />\n </div>\n <div className=\"space-y-2\">\n <Label>Department</Label>\n <Input\n placeholder=\"e.g., Engineering\"\n value={formData.department}\n onChange={(e) => handleChange('department', e.target.value)}\n />\n </div>\n <div className=\"space-y-2\">\n <Label>Tags</Label>\n <div className=\"flex flex-wrap items-center gap-1.5 rounded-md border border-border-strong bg-bg-surface px-2 py-1.5 focus-within:border-action-primary-bg\">\n {tags.map((tag) => (\n <Badge key={tag} variant=\"secondary\" className=\"gap-1\">\n {tag}\n <button\n type=\"button\"\n aria-label={`Remove ${tag}`}\n onClick={() => setTags((prev) => prev.filter((x) => x !== tag))}\n className=\"text-text-secondary hover:text-text-primary\"\n >\n <X className=\"h-3 w-3\" />\n </button>\n </Badge>\n ))}\n <input\n value={tagInput}\n onChange={(e) => setTagInput(e.target.value)}\n onKeyDown={onTagKeyDown}\n onBlur={commitTag}\n placeholder={tags.length === 0 ? 'Type a tag and press Enter' : ''}\n className=\"min-w-[8rem] flex-1 border-0 bg-transparent text-sm outline-none placeholder:text-text-secondary\"\n />\n </div>\n </div>\n </div>\n </SectionCard>\n\n {/* Sticky action bar */}\n <div className=\"sticky bottom-0 -mx-4 mt-6 border-t border-border-seam bg-bg-surface/95 px-4 py-3 backdrop-blur sm:-mx-6 sm:px-6\">\n <div className=\"mx-auto flex max-w-4xl flex-col gap-2 sm:flex-row sm:justify-end\">\n <Button\n variant=\"outline\"\n className=\"w-full sm:w-auto\"\n onClick={() => navigate('/assets/asset-list')}\n disabled={creating}\n >\n <X className=\"mr-2 h-4 w-4\" />\n Cancel\n </Button>\n <Button\n variant=\"outline\"\n className=\"w-full sm:w-auto\"\n onClick={() => submit(true)}\n disabled={creating}\n >\n {creating && submitMode === 'add' ? (\n <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" />\n ) : (\n <Save className=\"mr-2 h-4 w-4\" />\n )}\n Save & add another\n </Button>\n <Button className=\"w-full sm:w-auto\" onClick={() => submit(false)} disabled={creating}>\n {creating && submitMode === 'create' ? (\n <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" />\n ) : (\n <Save className=\"mr-2 h-4 w-4\" />\n )}\n {creating ? 'Creating...' : 'Create Asset'}\n </Button>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AssetsAssetCreatePage.js","names":[],"sources":["../../../src/assethandler/pages/AssetsAssetCreatePage.tsx"],"sourcesContent":["import { useAssetHandlerNavigate } from '../hooks/useAssetHandlerNavigate';\nimport {\n formatAssetCategory,\n useAssetCategoryPresentation,\n useAssetMoney,\n useHiddenCategoryIds,\n} from '../providers/AssetHandlerProvider';\nimport { useMemo, useRef, useState, type KeyboardEvent } from 'react';\nimport {\n Button,\n GlassCard,\n Input,\n Label,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Textarea,\n GradientText,\n PagePurpose,\n Badge,\n} from '@burdenoff/fe-libs/ui';\nimport { ArrowLeft, Loader2, Save, X, TrendingDown, Info } from 'lucide-react';\nimport { gql } from '@apollo/client';\nimport { useMutation } from '@apollo/client/react';\nimport { notify } from '../utils/toast';\nimport { useAssetHandlerStore } from '../store/assethandlerStore';\nimport { ChartCard, TrendChart } from '../components';\nimport { METER_UNIT_OPTIONS, meterReadingLabel } from '../utils/meter';\nimport { useCopy } from '../hooks/useCopy';\n\nconst CREATE_ASSET_MUTATION = gql`\n mutation AssetHandlerCreateAsset($input: CreateAssetInput!) {\n createAsset(input: $input) {\n id\n assetNumber\n name\n }\n }\n`;\n\nconst BASE_CATEGORY_OPTIONS = [\n 'electronics',\n 'it_hardware',\n 'furniture',\n 'vehicles',\n 'equipment',\n 'software',\n 'networking',\n 'servers',\n];\n\ninterface FormState {\n name: string;\n description: string;\n category: string;\n status: string;\n condition: string;\n serialNumber: string;\n assetNumber: string;\n locationName: string;\n assignedTo: string;\n purchaseValue: string;\n purchaseDate: string;\n usefulLifeMonths: string;\n salvageValue: string;\n depreciationMethod: string;\n unitsOfProductionCapacity: string;\n unitsProduced: string;\n meterUnit: string;\n warrantyExpiry: string;\n supplier: string;\n department: string;\n}\n\nconst INITIAL_FORM: FormState = {\n name: '',\n description: '',\n category: 'it_hardware',\n status: 'ACTIVE',\n condition: 'GOOD',\n serialNumber: '',\n assetNumber: '',\n locationName: '',\n assignedTo: '',\n purchaseValue: '',\n purchaseDate: '',\n usefulLifeMonths: '',\n salvageValue: '',\n depreciationMethod: 'STRAIGHT_LINE',\n unitsOfProductionCapacity: '',\n unitsProduced: '',\n meterUnit: '',\n warrantyExpiry: '',\n supplier: '',\n department: '',\n};\n\n// Pure derivation of a book-value schedule from the user's own inputs. Returns\n// an empty array when the essentials are missing — never fabricates a curve.\n// Mirrors wspace-assethandler-svc's computeDepreciation formulas per method\n// (annualized here for a compact preview chart; the server computes the\n// authoritative month-granular currentValue/accumulatedDepreciation).\nfunction buildDepreciationSeries(input: {\n purchaseValue: number | null;\n salvageValue: number | null;\n usefulLifeMonths: number | null;\n method: string;\n unitsOfProductionCapacity: number | null;\n unitsProduced: number | null;\n}): { year: number; bookValue: number }[] {\n const pv = input.purchaseValue;\n const life = input.usefulLifeMonths;\n if (!pv || pv <= 0 || !life || life <= 0) return [];\n const salvage = Math.max(0, Math.min(input.salvageValue ?? 0, pv));\n const method = input.method.toLowerCase();\n const years = Math.max(1, Math.round(life / 12));\n\n if (method === 'units_of_production') {\n const capacity = input.unitsOfProductionCapacity;\n const produced = Math.max(0, input.unitsProduced ?? 0);\n if (!capacity || capacity <= 0) return [];\n // Straight-line-by-usage preview: assumes even production across the\n // asset's life up to the units produced so far, then flat afterward.\n const bvAtProduced = Math.max(\n pv - (pv - salvage) * (Math.min(produced, capacity) / capacity),\n salvage\n );\n return [\n { year: 0, bookValue: Math.round(pv) },\n { year: years, bookValue: Math.round(bvAtProduced) },\n ];\n }\n\n const points: { year: number; bookValue: number }[] = [];\n for (let y = 0; y <= years; y += 1) {\n let bv: number;\n if (method === 'reducing_balance') {\n const rate = salvage > 0 ? 1 - Math.pow(salvage / pv, 1 / years) : Math.min(0.9, 2 / years);\n bv = Math.max(pv * Math.pow(1 - rate, y), salvage);\n } else if (method === 'declining_balance') {\n const rate =\n salvage > 0 ? 1 - Math.pow(salvage / pv, 1 / years) : Math.min(0.75, 1.5 / years);\n bv = Math.max(pv * Math.pow(1 - rate, y), salvage);\n } else if (method === 'sum_of_years_digits') {\n const syd = (years * (years + 1)) / 2;\n const cumulative = syd > 0 ? (pv - salvage) * ((y * years - (y * (y - 1)) / 2) / syd) : 0;\n bv = Math.max(pv - cumulative, salvage);\n } else if (method === 'none') {\n bv = pv;\n } else {\n bv = Math.max(pv - (pv - salvage) * (y / years), salvage);\n }\n points.push({ year: y, bookValue: Math.round(bv) });\n }\n return points;\n}\n\nconst SectionCard = ({\n title,\n description,\n children,\n glow,\n}: {\n title: string;\n description?: string;\n children: React.ReactNode;\n glow?: boolean;\n}) => (\n <GlassCard treatment=\"glass\" glow={glow} className=\"border-border-seam\">\n <div className=\"space-y-4 p-5 sm:p-6\">\n <div>\n <h2 className=\"text-lg font-semibold\">{title}</h2>\n {description ? <p className=\"mt-0.5 text-sm text-text-secondary\">{description}</p> : null}\n </div>\n {children}\n </div>\n </GlassCard>\n);\n\nexport function AssetsAssetCreatePage() {\n const tc = useCopy();\n const navigate = useAssetHandlerNavigate();\n const { symbol: currencySymbolGlyph, compact: moneyCompact } = useAssetMoney();\n const hiddenCategories = useHiddenCategoryIds();\n const { labels: categoryLabels, options: configuredCategoryOptions } =\n useAssetCategoryPresentation();\n const { assets } = useAssetHandlerStore();\n const [formData, setFormData] = useState<FormState>(INITIAL_FORM);\n const [tags, setTags] = useState<string[]>([]);\n const [tagInput, setTagInput] = useState('');\n const [errors, setErrors] = useState<Record<string, string>>({});\n const [submitMode, setSubmitMode] = useState<'create' | 'add' | null>(null);\n const addAnotherRef = useRef(false);\n\n const categoryOptions = useMemo(() => {\n const set = new Set<string>(\n configuredCategoryOptions?.map((category) => category.id) ?? BASE_CATEGORY_OPTIONS\n );\n if (!configuredCategoryOptions) {\n for (const a of assets) if (a.category) set.add(a.category);\n }\n return [...set].filter((c) => !hiddenCategories.has(c)).sort();\n }, [assets, configuredCategoryOptions, hiddenCategories]);\n\n const [createAsset, { loading: creating }] = useMutation<{\n createAsset: { id: string; assetNumber: string; name: string };\n }>(CREATE_ASSET_MUTATION, {\n refetchQueries: ['AssetHandlerBootstrap'],\n onCompleted: (data) => {\n notify.success(\n tc('assethandler.assets.create.toast.title', '{{asset}} created'),\n tc('assethandler.assets.create.toast.body', '{{name}} was registered in the inventory.', {\n name: data.createAsset.name,\n })\n );\n setSubmitMode(null);\n if (addAnotherRef.current) {\n addAnotherRef.current = false;\n setFormData(INITIAL_FORM);\n setTags([]);\n setTagInput('');\n setErrors({});\n if (typeof window !== 'undefined') window.scrollTo({ top: 0, behavior: 'smooth' });\n } else {\n navigate(`/assets/${data.createAsset.id}`);\n }\n },\n onError: (error) => {\n setSubmitMode(null);\n notify.error('Could not create asset', error.message);\n },\n });\n\n const handleChange = (field: keyof FormState, value: string) => {\n setFormData((prev) => ({ ...prev, [field]: value }));\n setErrors((prev) => {\n if (!prev[field]) return prev;\n const next = { ...prev };\n delete next[field];\n return next;\n });\n };\n\n const commitTag = () => {\n const value = tagInput.trim().replace(/,$/, '').trim();\n if (value && !tags.includes(value)) setTags((prev) => [...prev, value]);\n setTagInput('');\n };\n const onTagKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter' || e.key === ',') {\n e.preventDefault();\n commitTag();\n } else if (e.key === 'Backspace' && tagInput === '' && tags.length > 0) {\n setTags((prev) => prev.slice(0, -1));\n }\n };\n\n const depreciationPreview = useMemo(\n () =>\n buildDepreciationSeries({\n purchaseValue: formData.purchaseValue.trim() ? Number(formData.purchaseValue) : null,\n salvageValue: formData.salvageValue.trim() ? Number(formData.salvageValue) : null,\n usefulLifeMonths: formData.usefulLifeMonths.trim()\n ? Number(formData.usefulLifeMonths)\n : null,\n method: formData.depreciationMethod,\n unitsOfProductionCapacity: formData.unitsOfProductionCapacity.trim()\n ? Number(formData.unitsOfProductionCapacity)\n : null,\n unitsProduced: formData.unitsProduced.trim() ? Number(formData.unitsProduced) : null,\n }),\n [\n formData.purchaseValue,\n formData.salvageValue,\n formData.usefulLifeMonths,\n formData.depreciationMethod,\n formData.unitsOfProductionCapacity,\n formData.unitsProduced,\n ]\n );\n\n const submit = (addAnother: boolean) => {\n const nextErrors: Record<string, string> = {};\n if (!formData.name.trim()) nextErrors.name = 'Asset name is required';\n if (!formData.assetNumber.trim()) nextErrors.assetNumber = 'Asset tag is required';\n if (!formData.category.trim()) nextErrors.category = 'Category is required';\n\n const numericField = (value: string, label: string, key: string) => {\n if (value.trim() === '') return;\n const parsed = Number(value);\n if (Number.isNaN(parsed) || parsed < 0)\n nextErrors[key] = `${label} must be a positive number`;\n };\n numericField(formData.purchaseValue, 'Purchase value', 'purchaseValue');\n numericField(formData.salvageValue, 'Salvage value', 'salvageValue');\n numericField(formData.usefulLifeMonths, 'Useful life', 'usefulLifeMonths');\n\n setErrors(nextErrors);\n if (Object.keys(nextErrors).length > 0) {\n notify.warning('Missing required fields', 'Fill in the highlighted fields and try again.');\n return;\n }\n\n const optionalNumber = (value: string): number | null => {\n const trimmed = value.trim();\n if (trimmed === '') return null;\n const parsed = Number(trimmed);\n return Number.isNaN(parsed) ? null : parsed;\n };\n const optionalDate = (value: string): string | null =>\n value.trim() === '' ? null : new Date(value).toISOString();\n\n addAnotherRef.current = addAnother;\n setSubmitMode(addAnother ? 'add' : 'create');\n void createAsset({\n variables: {\n input: {\n name: formData.name.trim(),\n assetNumber: formData.assetNumber.trim(),\n category: formData.category,\n status: formData.status,\n condition: formData.condition,\n description: formData.description.trim() || null,\n serialNumber: formData.serialNumber.trim() || null,\n locationName: formData.locationName.trim() || null,\n assignedTo: formData.assignedTo.trim() || null,\n tags,\n purchaseValue: optionalNumber(formData.purchaseValue),\n purchaseDate: optionalDate(formData.purchaseDate),\n usefulLifeMonths: optionalNumber(formData.usefulLifeMonths),\n salvageValue: optionalNumber(formData.salvageValue),\n depreciationMethod: formData.depreciationMethod,\n unitsOfProductionCapacity: optionalNumber(formData.unitsOfProductionCapacity),\n unitsProduced: optionalNumber(formData.unitsProduced),\n meterUnit: formData.meterUnit || null,\n warrantyExpiry: optionalDate(formData.warrantyExpiry),\n supplier: formData.supplier.trim() || null,\n department: formData.department.trim() || null,\n },\n },\n });\n };\n\n return (\n <div className=\"mx-auto max-w-4xl space-y-6 p-4 pb-28 sm:p-6 sm:pb-28\">\n {/* Header */}\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:gap-4\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n aria-label=\"Go back\"\n className=\"w-fit\"\n onClick={() => navigate('/assets/asset-list')}\n >\n <ArrowLeft className=\"h-4 w-4\" />\n </Button>\n <div>\n <h1 className=\"text-2xl font-bold\">\n <GradientText>\n {tc('assethandler.assets.create.title', 'Create New {{asset}}')}\n </GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n {tc(\n 'assethandler.assets.create.subtitle',\n 'Register a new {{assetLower}} in the inventory'\n )}{' '}\n · <span className=\"text-status-error-text\">*</span> required\n </p>\n </div>\n </div>\n\n <PagePurpose>\n {tc(\n 'assethandler.assets.create.purpose',\n 'Register a new {{assetLower}} so it can be tracked, maintained and assigned from day one. Capture its identity, category and condition, then its financials and location — the more you fill in now, the better your reports and audits later.'\n )}\n </PagePurpose>\n\n {/* General Information */}\n <SectionCard\n title=\"General Information\"\n description={tc(\n 'assethandler.assets.create.general.description',\n 'Basic {{assetLower}} details and identification'\n )}\n glow\n >\n <div className=\"grid gap-4 md:grid-cols-2\">\n <div className=\"space-y-2\">\n <Label>\n {tc('assethandler.assets.create.field.name', '{{asset}} Name')}{' '}\n <span className=\"text-status-error-text\">*</span>\n </Label>\n <Input\n placeholder={tc(\n 'assethandler.assets.create.field.namePlaceholder',\n 'e.g., Dell OptiPlex 7090'\n )}\n value={formData.name}\n onChange={(e) => handleChange('name', e.target.value)}\n aria-invalid={!!errors.name}\n />\n {errors.name ? <p className=\"text-xs text-status-error-text\">{errors.name}</p> : null}\n </div>\n <div className=\"space-y-2\">\n <Label>\n {tc('assethandler.assets.create.field.tag', '{{asset}} Tag')}{' '}\n <span className=\"text-status-error-text\">*</span>\n </Label>\n <Input\n placeholder={tc('assethandler.assets.create.field.tagPlaceholder', 'e.g., IT-HW-001')}\n value={formData.assetNumber}\n onChange={(e) => handleChange('assetNumber', e.target.value)}\n aria-invalid={!!errors.assetNumber}\n />\n {errors.assetNumber ? (\n <p className=\"text-xs text-status-error-text\">{errors.assetNumber}</p>\n ) : null}\n </div>\n </div>\n <div className=\"space-y-2\">\n <Label>Description</Label>\n <Textarea\n placeholder={tc(\n 'assethandler.assets.create.field.descriptionPlaceholder',\n 'Brief description of the {{assetLower}}...'\n )}\n value={formData.description}\n onChange={(e) => handleChange('description', e.target.value)}\n rows={3}\n />\n </div>\n <div className=\"grid gap-4 md:grid-cols-3\">\n <div className=\"space-y-2\">\n <Label>\n Category <span className=\"text-status-error-text\">*</span>\n </Label>\n <Select value={formData.category} onValueChange={(v) => handleChange('category', v)}>\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {categoryOptions.map((category) => (\n <SelectItem key={category} value={category} className=\"capitalize\">\n {configuredCategoryOptions?.find((option) => option.id === category)?.label ??\n formatAssetCategory(category, categoryLabels)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"space-y-2\">\n <Label>Status</Label>\n <Select value={formData.status} onValueChange={(v) => handleChange('status', v)}>\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"ACTIVE\">Active</SelectItem>\n <SelectItem value=\"INACTIVE\">Inactive</SelectItem>\n <SelectItem value=\"MAINTENANCE\">Maintenance</SelectItem>\n <SelectItem value=\"RETIRED\">Retired</SelectItem>\n </SelectContent>\n </Select>\n </div>\n <div className=\"space-y-2\">\n <Label>Condition</Label>\n <Select value={formData.condition} onValueChange={(v) => handleChange('condition', v)}>\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"EXCELLENT\">Excellent</SelectItem>\n <SelectItem value=\"GOOD\">Good</SelectItem>\n <SelectItem value=\"FAIR\">Fair</SelectItem>\n <SelectItem value=\"POOR\">Poor</SelectItem>\n <SelectItem value=\"DAMAGED\">Damaged</SelectItem>\n </SelectContent>\n </Select>\n </div>\n </div>\n <div className=\"space-y-2\">\n <Label>Serial Number</Label>\n <Input\n placeholder=\"e.g., DELL-7090-X1A2B3\"\n value={formData.serialNumber}\n onChange={(e) => handleChange('serialNumber', e.target.value)}\n />\n </div>\n </SectionCard>\n\n {/* Financial Details */}\n <SectionCard\n title=\"Financial Details\"\n description=\"Purchase and depreciation data powers book value, TCO and finance reports\"\n >\n <div className=\"grid gap-4 md:grid-cols-3\">\n <div className=\"space-y-2\">\n <Label>Purchase Value</Label>\n <div className=\"relative\">\n <span className=\"pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-sm text-text-secondary\">\n {currencySymbolGlyph}\n </span>\n <Input\n type=\"number\"\n min=\"0\"\n step=\"0.01\"\n placeholder=\"1200\"\n className=\"pl-7\"\n value={formData.purchaseValue}\n onChange={(e) => handleChange('purchaseValue', e.target.value)}\n aria-invalid={!!errors.purchaseValue}\n />\n </div>\n {errors.purchaseValue ? (\n <p className=\"text-xs text-status-error-text\">{errors.purchaseValue}</p>\n ) : null}\n </div>\n <div className=\"space-y-2\">\n <Label>Purchase Date</Label>\n <Input\n type=\"date\"\n value={formData.purchaseDate}\n onChange={(e) => handleChange('purchaseDate', e.target.value)}\n />\n </div>\n <div className=\"space-y-2\">\n <Label>Supplier</Label>\n <Input\n placeholder=\"e.g., Dell Technologies\"\n value={formData.supplier}\n onChange={(e) => handleChange('supplier', e.target.value)}\n />\n </div>\n </div>\n <div className=\"grid gap-4 md:grid-cols-3\">\n <div className=\"space-y-2\">\n <Label>Useful Life</Label>\n <div className=\"relative\">\n <Input\n type=\"number\"\n min=\"0\"\n step=\"1\"\n placeholder=\"60\"\n className=\"pr-16\"\n value={formData.usefulLifeMonths}\n onChange={(e) => handleChange('usefulLifeMonths', e.target.value)}\n aria-invalid={!!errors.usefulLifeMonths}\n />\n <span className=\"pointer-events-none absolute right-3 top-1/2 -translate-y-1/2 text-sm text-text-secondary\">\n months\n </span>\n </div>\n {errors.usefulLifeMonths ? (\n <p className=\"text-xs text-status-error-text\">{errors.usefulLifeMonths}</p>\n ) : null}\n </div>\n <div className=\"space-y-2\">\n <Label>Salvage Value</Label>\n <div className=\"relative\">\n <span className=\"pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-sm text-text-secondary\">\n {currencySymbolGlyph}\n </span>\n <Input\n type=\"number\"\n min=\"0\"\n step=\"0.01\"\n placeholder=\"100\"\n className=\"pl-7\"\n value={formData.salvageValue}\n onChange={(e) => handleChange('salvageValue', e.target.value)}\n aria-invalid={!!errors.salvageValue}\n />\n </div>\n {errors.salvageValue ? (\n <p className=\"text-xs text-status-error-text\">{errors.salvageValue}</p>\n ) : null}\n </div>\n <div className=\"space-y-2\">\n <Label>Depreciation Method</Label>\n <Select\n value={formData.depreciationMethod}\n onValueChange={(v) => handleChange('depreciationMethod', v)}\n >\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"STRAIGHT_LINE\">Straight line</SelectItem>\n <SelectItem value=\"REDUCING_BALANCE\">Reducing balance (200%)</SelectItem>\n <SelectItem value=\"DECLINING_BALANCE\">Declining balance (150%)</SelectItem>\n <SelectItem value=\"SUM_OF_YEARS_DIGITS\">Sum of years' digits</SelectItem>\n <SelectItem value=\"UNITS_OF_PRODUCTION\">Units of production</SelectItem>\n <SelectItem value=\"NONE\">None</SelectItem>\n </SelectContent>\n </Select>\n </div>\n </div>\n {/*\n Lifetime Capacity is a depreciation input and stays gated on the method that\n uses it. The METER does not: `unitsProduced` is also what a maintenance plan's\n intervalMeter counts against, so gating it meant a straight-line tractor had\n nowhere to record engine hours and its meter plans could never come due\n (BOFF-6032).\n */}\n {formData.depreciationMethod === 'UNITS_OF_PRODUCTION' ? (\n <div className=\"space-y-2\">\n <Label>Lifetime Capacity (units)</Label>\n <Input\n type=\"number\"\n min=\"0\"\n step=\"1\"\n placeholder=\"e.g., 100000 (miles, hours, cycles…)\"\n value={formData.unitsOfProductionCapacity}\n onChange={(e) => handleChange('unitsOfProductionCapacity', e.target.value)}\n />\n </div>\n ) : null}\n <div className=\"grid gap-4 md:grid-cols-2\">\n <div className=\"space-y-2\">\n <Label>Meter unit</Label>\n <Select\n value={formData.meterUnit}\n onValueChange={(value) => handleChange('meterUnit', value)}\n >\n <SelectTrigger>\n <SelectValue placeholder=\"Not metered\" />\n </SelectTrigger>\n <SelectContent>\n {METER_UNIT_OPTIONS.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"space-y-2\">\n <Label>{meterReadingLabel(formData.meterUnit)}</Label>\n <Input\n type=\"number\"\n min=\"0\"\n step=\"1\"\n placeholder=\"0\"\n value={formData.unitsProduced}\n onChange={(e) => handleChange('unitsProduced', e.target.value)}\n />\n </div>\n </div>\n <div className=\"space-y-2\">\n <Label>Warranty Expiry</Label>\n <Input\n type=\"date\"\n value={formData.warrantyExpiry}\n onChange={(e) => handleChange('warrantyExpiry', e.target.value)}\n />\n </div>\n\n {/* Live depreciation preview */}\n <ChartCard\n title=\"Depreciation preview\"\n subtitle={tc(\n 'assethandler.assets.create.depreciation.subtitle',\n \"Projected book value over the {{assetLower}}'s useful life\"\n )}\n icon={TrendingDown}\n >\n {depreciationPreview.length > 0 ? (\n <TrendChart\n data={depreciationPreview}\n xKey=\"year\"\n height={240}\n valueFormat={moneyCompact}\n xTickFormat={(v) => `${v}y`}\n series={[{ key: 'bookValue', label: 'Book value' }]}\n />\n ) : (\n <div className=\"flex flex-col items-center gap-2 py-10 text-center text-sm text-text-secondary\">\n <Info className=\"h-5 w-5 text-text-muted\" />\n Enter a purchase value and useful life to preview the depreciation schedule.\n </div>\n )}\n </ChartCard>\n </SectionCard>\n\n {/* Assignment & Location */}\n <SectionCard title=\"Assignment & Location\" description=\"Who holds it and where it lives\">\n <div className=\"grid gap-4 md:grid-cols-2\">\n <div className=\"space-y-2\">\n <Label>Assigned To</Label>\n <Input\n placeholder=\"e.g., john.smith@company.com\"\n value={formData.assignedTo}\n onChange={(e) => handleChange('assignedTo', e.target.value)}\n />\n </div>\n <div className=\"space-y-2\">\n <Label>Location</Label>\n <Input\n placeholder=\"e.g., Building A, Floor 3, Desk 15\"\n value={formData.locationName}\n onChange={(e) => handleChange('locationName', e.target.value)}\n />\n </div>\n <div className=\"space-y-2\">\n <Label>Department</Label>\n <Input\n placeholder=\"e.g., Engineering\"\n value={formData.department}\n onChange={(e) => handleChange('department', e.target.value)}\n />\n </div>\n <div className=\"space-y-2\">\n <Label>Tags</Label>\n <div className=\"flex flex-wrap items-center gap-1.5 rounded-md border border-border-strong bg-bg-surface px-2 py-1.5 focus-within:border-action-primary-bg\">\n {tags.map((tag) => (\n <Badge key={tag} variant=\"secondary\" className=\"gap-1\">\n {tag}\n <button\n type=\"button\"\n aria-label={`Remove ${tag}`}\n onClick={() => setTags((prev) => prev.filter((x) => x !== tag))}\n className=\"text-text-secondary hover:text-text-primary\"\n >\n <X className=\"h-3 w-3\" />\n </button>\n </Badge>\n ))}\n <input\n value={tagInput}\n onChange={(e) => setTagInput(e.target.value)}\n onKeyDown={onTagKeyDown}\n onBlur={commitTag}\n placeholder={tags.length === 0 ? 'Type a tag and press Enter' : ''}\n className=\"min-w-[8rem] flex-1 border-0 bg-transparent text-sm outline-none placeholder:text-text-secondary\"\n />\n </div>\n </div>\n </div>\n </SectionCard>\n\n {/* Sticky action bar */}\n <div className=\"sticky bottom-0 -mx-4 mt-6 border-t border-border-seam bg-bg-surface/95 px-4 py-3 backdrop-blur sm:-mx-6 sm:px-6\">\n <div className=\"mx-auto flex max-w-4xl flex-col gap-2 sm:flex-row sm:justify-end\">\n <Button\n variant=\"outline\"\n className=\"w-full sm:w-auto\"\n onClick={() => navigate('/assets/asset-list')}\n disabled={creating}\n >\n <X className=\"mr-2 h-4 w-4\" />\n Cancel\n </Button>\n <Button\n variant=\"outline\"\n className=\"w-full sm:w-auto\"\n onClick={() => submit(true)}\n disabled={creating}\n >\n {creating && submitMode === 'add' ? (\n <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" />\n ) : (\n <Save className=\"mr-2 h-4 w-4\" />\n )}\n Save & add another\n </Button>\n <Button className=\"w-full sm:w-auto\" onClick={() => submit(false)} disabled={creating}>\n {creating && submitMode === 'create' ? (\n <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" />\n ) : (\n <Save className=\"mr-2 h-4 w-4\" />\n )}\n {creating ? 'Creating...' : 'Create Asset'}\n </Button>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AssetsAssetDetailPage.d.ts","sourceRoot":"","sources":["../../../src/assethandler/pages/AssetsAssetDetailPage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AssetsAssetDetailPage.d.ts","sourceRoot":"","sources":["../../../src/assethandler/pages/AssetsAssetDetailPage.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAoS/B,wBAAgB,qBAAqB,sBA41BpC"}
|