Compare commits
6 Commits
ee33235a99
...
23b58de1f9
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
23b58de1f9 | ||
|
|
e62a7be9fa | ||
|
|
a2d3f48fca | ||
|
|
5d92f1bac9 | ||
|
|
af5c2d6019 | ||
| de987a9fc5 |
@ -236,6 +236,32 @@ const AssetDetail: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
|
<form onSubmit={handleSubmit}>
|
||||||
|
{/* 4-Column Grid Layout */}
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
|
||||||
|
|
||||||
|
{/* COLUMN 1: Asset Information */}
|
||||||
|
<div className="bg-white dark:bg-gray-800 rounded-lg shadow-md p-6">
|
||||||
|
<h2 className="text-base font-semibold text-gray-800 dark:text-white mb-4 pb-2 border-b border-gray-200 dark:border-gray-700">
|
||||||
|
Asset Information
|
||||||
|
</h2>
|
||||||
|
<div className="space-y-4">
|
||||||
|
<div>
|
||||||
|
<label className="block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||||
|
Asset Name <span className="text-red-500">*</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="asset_name"
|
||||||
|
value={formData.asset_name}
|
||||||
|
onChange={handleChange}
|
||||||
|
placeholder="e.g. Laptop Model X"
|
||||||
|
required
|
||||||
|
disabled={!isEditing}
|
||||||
|
className="w-full px-3 py-2 text-sm border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:bg-gray-100 dark:disabled:bg-gray-700 bg-white dark:bg-gray-700 text-gray-900 dark:text-white"
|
||||||
|
/>
|
||||||
|
=======
|
||||||
<form onSubmit={handleSubmit} className="space-y-6">
|
<form onSubmit={handleSubmit} className="space-y-6">
|
||||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
||||||
{/* Left Column - Asset Information & Technical Specs & Location */}
|
{/* Left Column - Asset Information & Technical Specs & Location */}
|
||||||
@ -316,6 +342,283 @@ const AssetDetail: React.FC = () => {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||||
|
Class <span className="text-red-500">*</span>
|
||||||
|
</label>
|
||||||
|
<select
|
||||||
|
name="custom_class"
|
||||||
|
value={formData.custom_class}
|
||||||
|
onChange={handleChange}
|
||||||
|
disabled={!isEditing}
|
||||||
|
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:bg-gray-100 dark:disabled:bg-gray-700 bg-white dark:bg-gray-700 text-gray-900 dark:text-white"
|
||||||
|
>
|
||||||
|
<option value="">Select class</option>
|
||||||
|
<option value="Class A">Class A</option>
|
||||||
|
<option value="Class B">Class B</option>
|
||||||
|
<option value="Class C">Class C</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="md:col-span-2">
|
||||||
|
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||||
|
Asset ID <span className="text-red-500">*</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={isNewAsset || isDuplicating ? 'Auto-generated' : asset?.name}
|
||||||
|
disabled
|
||||||
|
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-gray-100 dark:bg-gray-700 text-gray-900 dark:text-white"
|
||||||
|
/>
|
||||||
|
{isDuplicating && (
|
||||||
|
<p className="mt-1 text-xs text-blue-600 dark:text-blue-400">
|
||||||
|
💡 Duplicating from: {duplicateFromAsset}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
>>>>>>> 225d63e (Added Linkfield.tsx)
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
|
<div>
|
||||||
|
<label className="block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||||
|
Category <span className="text-red-500">*</span>
|
||||||
|
</label>
|
||||||
|
<select
|
||||||
|
name="custom_asset_type"
|
||||||
|
value={formData.custom_asset_type}
|
||||||
|
onChange={handleChange}
|
||||||
|
required
|
||||||
|
disabled={!isEditing}
|
||||||
|
className="w-full px-3 py-2 text-sm border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:bg-gray-100 dark:disabled:bg-gray-700 bg-white dark:bg-gray-700 text-gray-900 dark:text-white"
|
||||||
|
>
|
||||||
|
<option value="">Select category</option>
|
||||||
|
<option value="Medical Equipment">Medical Equipment</option>
|
||||||
|
<option value="Office Equipment">Office Equipment</option>
|
||||||
|
<option value="IT Equipment">IT Equipment</option>
|
||||||
|
<option value="Furniture">Furniture</option>
|
||||||
|
</select>
|
||||||
|
=======
|
||||||
|
{/* Technical Specs */}
|
||||||
|
<div className="bg-white dark:bg-gray-800 rounded-lg shadow p-6">
|
||||||
|
<h2 className="text-lg font-semibold text-gray-800 dark:text-white mb-4">Technical Specs</h2>
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||||
|
Serial No.
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="custom_serial_number"
|
||||||
|
value={formData.custom_serial_number}
|
||||||
|
onChange={handleChange}
|
||||||
|
placeholder="e.g. SN-12345"
|
||||||
|
disabled={!isEditing}
|
||||||
|
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:bg-gray-100 dark:disabled:bg-gray-700 bg-white dark:bg-gray-700 text-gray-900 dark:text-white"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||||
|
System ID
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="e.g. SYS-755"
|
||||||
|
disabled={!isEditing}
|
||||||
|
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:bg-gray-100 dark:disabled:bg-gray-700 bg-white dark:bg-gray-700 text-gray-900 dark:text-white"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||||
|
Serial No.2
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="e.g. SR-V021-A"
|
||||||
|
disabled={!isEditing}
|
||||||
|
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:bg-gray-100 dark:disabled:bg-gray-700 bg-white dark:bg-gray-700 text-gray-900 dark:text-white"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* <div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||||
|
Manufacturer
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="custom_manufacturer"
|
||||||
|
value={formData.custom_manufacturer}
|
||||||
|
onChange={handleChange}
|
||||||
|
placeholder="Manufacturer name"
|
||||||
|
disabled={!isEditing}
|
||||||
|
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:bg-gray-100 dark:disabled:bg-gray-700 bg-white dark:bg-gray-700 text-gray-900 dark:text-white"
|
||||||
|
/>
|
||||||
|
</div> */}
|
||||||
|
|
||||||
|
<LinkField
|
||||||
|
label="Manufacturer"
|
||||||
|
doctype="Manufacturer"
|
||||||
|
value={formData.manufacturer || ''}
|
||||||
|
onChange={(val) => setFormData({ ...formData, manufacturer: val })}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||||
|
Model
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="custom_model"
|
||||||
|
value={formData.custom_model}
|
||||||
|
onChange={handleChange}
|
||||||
|
placeholder="Model number"
|
||||||
|
disabled={!isEditing}
|
||||||
|
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:bg-gray-100 dark:disabled:bg-gray-700 bg-white dark:bg-gray-700 text-gray-900 dark:text-white"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||||
|
Model Number
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="Model number"
|
||||||
|
disabled={!isEditing}
|
||||||
|
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:bg-gray-100 dark:disabled:bg-gray-700 bg-white dark:bg-gray-700 text-gray-900 dark:text-white"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
>>>>>>> 225d63e (Added Linkfield.tsx)
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
|
<div>
|
||||||
|
<label className="block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||||
|
Modality
|
||||||
|
</label>
|
||||||
|
<select
|
||||||
|
name="custom_modality"
|
||||||
|
value={formData.custom_modality}
|
||||||
|
onChange={handleChange}
|
||||||
|
disabled={!isEditing}
|
||||||
|
className="w-full px-3 py-2 text-sm border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:bg-gray-100 dark:disabled:bg-gray-700 bg-white dark:bg-gray-700 text-gray-900 dark:text-white"
|
||||||
|
>
|
||||||
|
<option value="">Select modality</option>
|
||||||
|
<option value="X-Ray">X-Ray</option>
|
||||||
|
<option value="CT">CT Scan</option>
|
||||||
|
<option value="MRI">MRI</option>
|
||||||
|
<option value="Ultrasound">Ultrasound</option>
|
||||||
|
<option value="Other">Other</option>
|
||||||
|
</select>
|
||||||
|
=======
|
||||||
|
{/* Location */}
|
||||||
|
<div className="bg-white dark:bg-gray-800 rounded-lg shadow p-6">
|
||||||
|
<h2 className="text-lg font-semibold text-gray-800 dark:text-white mb-4">Location</h2>
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||||
|
{/* <div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||||
|
Company
|
||||||
|
</label>
|
||||||
|
<select
|
||||||
|
name="company"
|
||||||
|
value={formData.company}
|
||||||
|
onChange={handleChange}
|
||||||
|
disabled={!isEditing}
|
||||||
|
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:bg-gray-100 dark:disabled:bg-gray-700 bg-white dark:bg-gray-700 text-gray-900 dark:text-white"
|
||||||
|
>
|
||||||
|
<option value="">Select company</option>
|
||||||
|
<option value="ABC Hospital">ABC Hospital</option>
|
||||||
|
<option value="XYZ Clinic">XYZ Clinic</option>
|
||||||
|
</select>
|
||||||
|
</div> */}
|
||||||
|
|
||||||
|
<LinkField
|
||||||
|
label="Hospital"
|
||||||
|
doctype="Company"
|
||||||
|
value={formData.company || ''}
|
||||||
|
onChange={(val) => setFormData({ ...formData, company: val })}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* <div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||||
|
Department
|
||||||
|
</label>
|
||||||
|
<select
|
||||||
|
name="department"
|
||||||
|
value={formData.department}
|
||||||
|
onChange={handleChange}
|
||||||
|
disabled={!isEditing}
|
||||||
|
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:bg-gray-100 dark:disabled:bg-gray-700 bg-white dark:bg-gray-700 text-gray-900 dark:text-white"
|
||||||
|
>
|
||||||
|
<option value="">Select department</option>
|
||||||
|
<option value="Radiology">Radiology</option>
|
||||||
|
<option value="Cardiology">Cardiology</option>
|
||||||
|
<option value="IT">IT</option>
|
||||||
|
</select>
|
||||||
|
</div> */}
|
||||||
|
|
||||||
|
<LinkField
|
||||||
|
label="Department"
|
||||||
|
doctype="Department"
|
||||||
|
value={formData.department || ''}
|
||||||
|
onChange={(val) => setFormData({ ...formData, department: val })}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||||
|
Building
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="location"
|
||||||
|
value={formData.location}
|
||||||
|
onChange={handleChange}
|
||||||
|
placeholder="Building name"
|
||||||
|
disabled={!isEditing}
|
||||||
|
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:bg-gray-100 dark:disabled:bg-gray-700 bg-white dark:bg-gray-700 text-gray-900 dark:text-white"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||||
|
Area/Unit
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="Area or unit"
|
||||||
|
disabled={!isEditing}
|
||||||
|
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:bg-gray-100 dark:disabled:bg-gray-700 bg-white dark:bg-gray-700 text-gray-900 dark:text-white"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||||
|
Room Number
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="e.g. Room 001-002"
|
||||||
|
disabled={!isEditing}
|
||||||
|
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:bg-gray-100 dark:disabled:bg-gray-700 bg-white dark:bg-gray-700 text-gray-900 dark:text-white"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||||
|
Assigned To
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="Person or department"
|
||||||
|
disabled={!isEditing}
|
||||||
|
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:bg-gray-100 dark:disabled:bg-gray-700 bg-white dark:bg-gray-700 text-gray-900 dark:text-white"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
>>>>>>> 225d63e (Added Linkfield.tsx)
|
||||||
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1">
|
<label className="block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||||
Class
|
Class
|
||||||
@ -398,27 +701,20 @@ const AssetDetail: React.FC = () => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* <div>
|
<div>
|
||||||
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
<label className="block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||||
Manufacturer
|
Manufacturer
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
name="custom_manufacturer"
|
name="custom_manufacturer"
|
||||||
value={formData.custom_manufacturer}
|
value={formData.custom_manufacturer}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
placeholder="Manufacturer name"
|
placeholder="Manufacturer name"
|
||||||
disabled={!isEditing}
|
disabled={!isEditing}
|
||||||
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:bg-gray-100 dark:disabled:bg-gray-700 bg-white dark:bg-gray-700 text-gray-900 dark:text-white"
|
className="w-full px-3 py-2 text-sm border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:bg-gray-100 dark:disabled:bg-gray-700 bg-white dark:bg-gray-700 text-gray-900 dark:text-white"
|
||||||
/>
|
|
||||||
</div> */}
|
|
||||||
|
|
||||||
<LinkField
|
|
||||||
label="Manufacturer"
|
|
||||||
doctype="Manufacturer"
|
|
||||||
value={formData.manufacturer || ''}
|
|
||||||
onChange={(val) => setFormData({ ...formData, manufacturer: val })}
|
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1">
|
<label className="block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||||
@ -449,58 +745,46 @@ const AssetDetail: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Location */}
|
{/* COLUMN 3: Location */}
|
||||||
<div className="bg-white dark:bg-gray-800 rounded-lg shadow p-6">
|
<div className="bg-white dark:bg-gray-800 rounded-lg shadow-md p-6">
|
||||||
<h2 className="text-lg font-semibold text-gray-800 dark:text-white mb-4">Location</h2>
|
<h2 className="text-base font-semibold text-gray-800 dark:text-white mb-4 pb-2 border-b border-gray-200 dark:border-gray-700">
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
Location
|
||||||
{/* <div>
|
</h2>
|
||||||
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
<div className="space-y-4">
|
||||||
Company
|
<div>
|
||||||
</label>
|
<label className="block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||||
<select
|
Site
|
||||||
name="company"
|
</label>
|
||||||
value={formData.company}
|
<select
|
||||||
onChange={handleChange}
|
name="company"
|
||||||
disabled={!isEditing}
|
value={formData.company}
|
||||||
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:bg-gray-100 dark:disabled:bg-gray-700 bg-white dark:bg-gray-700 text-gray-900 dark:text-white"
|
onChange={handleChange}
|
||||||
>
|
disabled={!isEditing}
|
||||||
<option value="">Select company</option>
|
className="w-full px-3 py-2 text-sm border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:bg-gray-100 dark:disabled:bg-gray-700 bg-white dark:bg-gray-700 text-gray-900 dark:text-white"
|
||||||
<option value="ABC Hospital">ABC Hospital</option>
|
>
|
||||||
<option value="XYZ Clinic">XYZ Clinic</option>
|
<option value="">Select site</option>
|
||||||
</select>
|
<option value="ABC Hospital">ABC Hospital</option>
|
||||||
</div> */}
|
<option value="XYZ Clinic">XYZ Clinic</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
<LinkField
|
<div>
|
||||||
label="Hospital"
|
<label className="block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||||
doctype="Company"
|
Department
|
||||||
value={formData.company || ''}
|
</label>
|
||||||
onChange={(val) => setFormData({ ...formData, company: val })}
|
<select
|
||||||
/>
|
name="department"
|
||||||
|
value={formData.department}
|
||||||
{/* <div>
|
onChange={handleChange}
|
||||||
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
disabled={!isEditing}
|
||||||
Department
|
className="w-full px-3 py-2 text-sm border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:bg-gray-100 dark:disabled:bg-gray-700 bg-white dark:bg-gray-700 text-gray-900 dark:text-white"
|
||||||
</label>
|
>
|
||||||
<select
|
<option value="">Select department</option>
|
||||||
name="department"
|
<option value="Radiology">Radiology</option>
|
||||||
value={formData.department}
|
<option value="Cardiology">Cardiology</option>
|
||||||
onChange={handleChange}
|
<option value="IT">IT</option>
|
||||||
disabled={!isEditing}
|
</select>
|
||||||
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:bg-gray-100 dark:disabled:bg-gray-700 bg-white dark:bg-gray-700 text-gray-900 dark:text-white"
|
</div>
|
||||||
>
|
|
||||||
<option value="">Select department</option>
|
|
||||||
<option value="Radiology">Radiology</option>
|
|
||||||
<option value="Cardiology">Cardiology</option>
|
|
||||||
<option value="IT">IT</option>
|
|
||||||
</select>
|
|
||||||
</div> */}
|
|
||||||
|
|
||||||
<LinkField
|
|
||||||
label="Department"
|
|
||||||
doctype="Department"
|
|
||||||
value={formData.department || ''}
|
|
||||||
onChange={(val) => setFormData({ ...formData, department: val })}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1">
|
<label className="block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||||
|
|||||||
@ -681,7 +681,7 @@ const CompletionRateCard: React.FC<{
|
|||||||
: '0.00';
|
: '0.00';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-white dark:bg-gray-800 rounded-lg shadow hover:shadow-md transition-all p-5 border border-gray-200 dark:border-gray-700">
|
<div className="bg-white dark:bg-gray-800 rounded-lg shadow hover:shadow-md transition-all px-5 border border-gray-200 dark:border-gray-700">
|
||||||
<div className="mb-3">
|
<div className="mb-3">
|
||||||
<div className="text-2xl font-semibold text-gray-900 dark:text-white mb-2">{completionRate}%</div>
|
<div className="text-2xl font-semibold text-gray-900 dark:text-white mb-2">{completionRate}%</div>
|
||||||
<div className="text-sm font-medium text-indigo-600 dark:text-indigo-400 mb-1">Completion Rate</div>
|
<div className="text-sm font-medium text-indigo-600 dark:text-indigo-400 mb-1">Completion Rate</div>
|
||||||
@ -692,7 +692,7 @@ const CompletionRateCard: React.FC<{
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Mini Stats */}
|
{/* Mini Stats */}
|
||||||
<div className="grid grid-cols-3 gap-3 mt-4 pt-4 border-t border-gray-200 dark:border-gray-700">
|
<div className="grid grid-cols-3 gap-3 mt-2 pt-2 mb-2 pb-2 border-t border-gray-200 dark:border-gray-700">
|
||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
<div className="text-lg font-semibold text-indigo-600 dark:text-indigo-400">{totalWorkOrders}</div>
|
<div className="text-lg font-semibold text-indigo-600 dark:text-indigo-400">{totalWorkOrders}</div>
|
||||||
<div className="text-[9px] font-medium text-gray-500 dark:text-gray-400 uppercase">Total</div>
|
<div className="text-[9px] font-medium text-gray-500 dark:text-gray-400 uppercase">Total</div>
|
||||||
@ -995,14 +995,17 @@ const BarChart: React.FC<{ data: any }> = ({ data }) => {
|
|||||||
const allValues = datasets.flatMap((ds: any) => ds.values || []);
|
const allValues = datasets.flatMap((ds: any) => ds.values || []);
|
||||||
const max = Math.max(...allValues, 1);
|
const max = Math.max(...allValues, 1);
|
||||||
const chartHeight = 250;
|
const chartHeight = 250;
|
||||||
const width = 800;
|
// Increase width based on number of labels to prevent overlap
|
||||||
|
const minBarSpacing = 60; // Minimum spacing between bars
|
||||||
|
const calculatedWidth = Math.max(800, labels.length * minBarSpacing + 100);
|
||||||
|
const width = calculatedWidth;
|
||||||
|
|
||||||
// Generate smooth line data (Average line overlay)
|
// Generate smooth line data (Average line overlay)
|
||||||
const lineData = datasets[0]?.values || [];
|
const lineData = datasets[0]?.values || [];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative w-full">
|
<div className="relative w-full overflow-x-auto">
|
||||||
<svg width="100%" height="280" viewBox={`0 0 ${width} ${chartHeight + 30}`} className="w-full">
|
<svg width="100%" height="320" viewBox={`0 0 ${width} ${chartHeight + 70}`} className="w-full" preserveAspectRatio="xMidYMid meet">
|
||||||
<defs>
|
<defs>
|
||||||
<linearGradient id="barGradient" x1="0%" y1="0%" x2="0%" y2="100%">
|
<linearGradient id="barGradient" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||||
<stop offset="0%" style={{ stopColor: '#8B5CF6', stopOpacity: 0.8 }} />
|
<stop offset="0%" style={{ stopColor: '#8B5CF6', stopOpacity: 0.8 }} />
|
||||||
@ -1095,16 +1098,20 @@ const BarChart: React.FC<{ data: any }> = ({ data }) => {
|
|||||||
|
|
||||||
{/* X-axis labels */}
|
{/* X-axis labels */}
|
||||||
{labels.map((label: string, i: number) => {
|
{labels.map((label: string, i: number) => {
|
||||||
const x = 80 + (i * ((width - 100) / labels.length)) + 20;
|
const barSpacing = (width - 100) / labels.length;
|
||||||
|
const x = 80 + (i * barSpacing) + (barSpacing / 2);
|
||||||
|
const truncatedLabel = label && label.length > 15 ? label.substring(0, 13) + '...' : label || 'null';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<text
|
<text
|
||||||
key={i}
|
key={i}
|
||||||
x={x}
|
x={x}
|
||||||
y={chartHeight + 20}
|
y={chartHeight + 50}
|
||||||
|
transform={`rotate(-45, ${x}, ${chartHeight + 50})`}
|
||||||
textAnchor="middle"
|
textAnchor="middle"
|
||||||
className="text-xs fill-gray-600 dark:fill-gray-400"
|
className="text-xs fill-gray-600 dark:fill-gray-400"
|
||||||
>
|
>
|
||||||
{label}
|
{truncatedLabel}
|
||||||
</text>
|
</text>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|||||||
@ -6,6 +6,9 @@ export default defineConfig({
|
|||||||
plugins: [react()],
|
plugins: [react()],
|
||||||
server: {
|
server: {
|
||||||
port: 3000,
|
port: 3000,
|
||||||
|
allowedHosts: [
|
||||||
|
'monotriglyphic-uniformless-rema.ngrok-free.dev'
|
||||||
|
],
|
||||||
proxy: {
|
proxy: {
|
||||||
// Proxy API requests to Frappe backend
|
// Proxy API requests to Frappe backend
|
||||||
'/api': {
|
'/api': {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user