diff --git a/frontend/app/(dashboard)/cmdb/page.tsx b/frontend/app/(dashboard)/cmdb/page.tsx new file mode 100644 index 00000000..8c3ef56c --- /dev/null +++ b/frontend/app/(dashboard)/cmdb/page.tsx @@ -0,0 +1,64 @@ +'use client'; + +import { useState } from 'react'; +import { Server, Monitor, Wifi, Database } from 'lucide-react'; + +interface AssetNode { id: string; name: string; type: string; dependencies: string[] } + +const NODES: AssetNode[] = [ + { id:'1', name:'Web Server', type:'server', dependencies:['3','4'] }, + { id:'2', name:'App Server', type:'server', dependencies:['3','4'] }, + { id:'3', name:'Database Server', type:'database', dependencies:[] }, + { id:'4', name:'Network Switch A', type:'network', dependencies:[] }, + { id:'5', name:'Dev Workstation', type:'computer', dependencies:['4'] }, +]; + +const TYPE_ICON: Record = { + server: , + database: , + network: , + computer: , +}; + +export default function CMDBPage() { + const [selected, setSelected] = useState(null); + const selectedNode = NODES.find(n => n.id === selected); + const dependsOn = selectedNode ? NODES.filter(n => selectedNode.dependencies.includes(n.id)) : []; + const dependents = selected ? NODES.filter(n => n.dependencies.includes(selected)) : []; + + return ( +
+

Asset Dependencies (CMDB)

Link assets and visualise dependencies

+
+
+
Assets
+ {NODES.map(n => ( + + ))} +
+
+ {selectedNode ? ( + <> +
+
{TYPE_ICON[selectedNode.type]}

{selectedNode.name}

+

{selectedNode.type}

+
+
+

Depends On

+ {dependsOn.length === 0 ?

No dependencies

: dependsOn.map(d=>
{TYPE_ICON[d.type]}{d.name}
)} +
+
+

Used By

+ {dependents.length === 0 ?

No dependents

: dependents.map(d=>
{TYPE_ICON[d.type]}{d.name}
)} +
+ + ) :
Select an asset to view its dependencies
} +
+
+
+ ); +} \ No newline at end of file diff --git a/frontend/app/(dashboard)/import/page.tsx b/frontend/app/(dashboard)/import/page.tsx new file mode 100644 index 00000000..d1e5406f --- /dev/null +++ b/frontend/app/(dashboard)/import/page.tsx @@ -0,0 +1,96 @@ +'use client'; + +import { useState, useRef } from 'react'; +import { Upload, CheckCircle, ChevronRight } from 'lucide-react'; +import { Button } from '@/components/ui/button'; + +type Step = 'upload' | 'map' | 'preview' | 'confirm'; + +const ASSET_FIELDS = ['name','assetId','category','status','department','serialNumber','purchaseDate']; +const SAMPLE_CSV_HEADERS = ['Asset Name','ID','Type','State','Team','Serial','Bought']; +const SAMPLE_ROWS = [['Laptop A','AST-100','IT','ACTIVE','Engineering','SN-1001','2023-01-01'],['Printer B','AST-101','IT','ACTIVE','Admin','SN-1002','2023-06-15']]; + +const STEPS: Step[] = ['upload','map','preview','confirm']; + +export default function CSVImportPage() { + const [step, setStep] = useState('upload'); + const [fileName, setFileName] = useState(''); + const [mapping, setMapping] = useState>({}); + const fileRef = useRef(null); + + const handleFile = (e: React.ChangeEvent) => { + const file = e.target.files?.[0]; + if (file) { setFileName(file.name); setStep('map'); } + }; + + const stepIdx = STEPS.indexOf(step); + + return ( +
+

Import Assets

CSV and Excel import wizard

+
+ {STEPS.map((s, i) => ( +
+
+ {i < stepIdx ? '✓' : i+1} + {s.charAt(0).toUpperCase() + s.slice(1)} +
+ {i < STEPS.length-1 && } +
+ ))} +
+ + {step === 'upload' && ( +
+ +

Drop your CSV or Excel file here

+

Supports .csv, .xlsx

+ + +
+ )} + + {step === 'map' && ( +
+

Map Columns — {fileName}

+
+ {SAMPLE_CSV_HEADERS.map(header => ( +
+ {header} + + +
+ ))} +
+
+
+ )} + + {step === 'preview' && ( +
+
+ Preview — {SAMPLE_ROWS.length} rows +
+
+ + {SAMPLE_CSV_HEADERS.map(h=>)} + {SAMPLE_ROWS.map((row,i)=>{row.map((cell,j)=>)})} +
{h}
{cell}
+
+ )} + + {step === 'confirm' && ( +
+ +

Import Successful

+

{SAMPLE_ROWS.length} assets imported successfully.

+ +
+ )} +
+ ); +} \ No newline at end of file