Compare commits

..

No commits in common. "fc091eb6668d423623690aedfc272929e0e29002" and "a58fc89c464eb70fda31374332e9a3fe48f844cc" have entirely different histories.

2 changed files with 86 additions and 258 deletions

View File

@ -2,7 +2,7 @@ import React, { useState, useEffect } from 'react';
import { useParams, useNavigate, useSearchParams } from 'react-router-dom';
import { useAssetDetails, useAssetMutations } from '../hooks/useAsset';
import { FaArrowLeft, FaSave, FaEdit, FaQrcode } from 'react-icons/fa';
import type { CreateAssetData, AssetFinanceBookRow } from '../services/assetService';
import type { CreateAssetData } from '../services/assetService';
import LinkField from '../components/LinkField';
import apiService from '../services/apiService'; // ✅ your ApiService
@ -56,15 +56,6 @@ const AssetDetail: React.FC = () => {
available_for_use_date: isNewAsset ? new Date().toISOString().split('T')[0] : undefined
});
const emptyFinanceRow = {
finance_book: "",
depreciation_method: "",
total_number_of_depreciations: 0,
frequency_of_depreciation: "",
depreciation_start_date: "",
};
// Load user details on mount
useEffect(() => {
async function loadUserDetails() {
@ -79,43 +70,6 @@ const AssetDetail: React.FC = () => {
loadUserDetails();
}, []);
const addFinanceRow = () => {
// Get today's date in YYYY-MM-DD format for date input
const today = new Date().toISOString().split('T')[0];
const newRow: AssetFinanceBookRow = {
finance_book: 'Depreciation Entries',
depreciation_method: 'Straight Line',
total_number_of_depreciations: 10,
frequency_of_depreciation: 12,
depreciation_start_date: today
};
setFormData(prev => ({
...prev,
finance_books: [
...(prev.finance_books || []),
newRow
]
}));
};
const removeFinanceRow = (index: number) => {
setFormData(prev => {
const rows = [...(prev.finance_books || [])];
rows.splice(index, 1);
return { ...prev, finance_books: rows };
});
};
const updateFinanceRow = (index: number, patch: Partial<AssetFinanceBookRow>) => {
setFormData(prev => {
const rows = [...(prev.finance_books || [])];
rows[index] = { ...(rows[index] || {}), ...patch };
return { ...prev, finance_books: rows };
});
};
// Update department filters when company or userSiteName changes
useEffect(() => {
const filters: Record<string, any> = {};
@ -490,8 +444,7 @@ const AssetDetail: React.FC = () => {
</select>
</div>
<div>
{/* <div className="md:col-span-2"> */}
<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>
@ -507,22 +460,6 @@ const AssetDetail: React.FC = () => {
</p>
)}
</div>
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
Device Status <span className="text-red-500">*</span>
</label>
<select
name="custom_device_status"
value={formData.custom_device_status}
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="Up">Up</option>
<option value="Down">Down</option>
</select>
</div>
</div>
</div>
@ -690,7 +627,7 @@ const AssetDetail: React.FC = () => {
disabled={!isEditing}
/>
{/* <div>
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
Building
</label>
@ -703,9 +640,9 @@ const AssetDetail: React.FC = () => {
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>
{/* <div>
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
Area/Unit
</label>
@ -715,7 +652,7 @@ const AssetDetail: React.FC = () => {
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>
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
@ -961,191 +898,92 @@ const AssetDetail: React.FC = () => {
</div>
</div>
{/* Updated Financial Details */}
{/* Financial Details */}
<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">Financial Details</h2>
<p className="text-sm text-gray-600 dark:text-gray-400 mb-4">
The depreciation method is an accounting method used to allocate the cost of a tangible asset over its useful life.
</p>
<div className="flex items-center mb-6">
<input
id="calculate_depreciation"
type="checkbox"
checked={formData.calculate_depreciation}
onChange={(e) =>
setFormData({
...formData,
calculate_depreciation: e.target.checked,
})
}
disabled={!isEditing}
className="h-4 w-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700"
/>
<label
htmlFor="calculate_depreciation"
className="ml-2 text-sm font-medium text-gray-700 dark:text-gray-300"
>
Calculate Depreciation
</label>
</div>
{/* Asset Finance Book child table — shown only when checkbox checked */}
{formData.calculate_depreciation && (
<div className="border-t pt-4">
{/* Header with Add Row button */}
<div className="flex justify-between items-center mb-4">
<h3 className="text-md font-semibold text-gray-800 dark:text-white">
Asset Finance Books
</h3>
{isEditing && (
<button
type="button"
onClick={addFinanceRow}
className="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 flex items-center gap-2"
>
<span>+</span> Add Row
</button>
)}
</div>
{/* Show message if no rows */}
{(!formData.finance_books || formData.finance_books.length === 0) && (
<div className="text-center py-8 text-gray-500 dark:text-gray-400 bg-gray-50 dark:bg-gray-900 rounded-lg">
No finance books added yet. Click "Add Row" to add one.
</div>
)}
{/* TABLE - Full width desktop view with overflow fix */}
{formData.finance_books && formData.finance_books.length > 0 && (
<div className="overflow-visible">
<div className="overflow-x-auto">
<table className="w-full border-collapse">
<thead>
<tr className="bg-gray-100 dark:bg-gray-700 border-b border-gray-300 dark:border-gray-600">
<th className="text-left px-4 py-3 text-sm font-semibold text-gray-700 dark:text-gray-300 min-w-[200px]">
Finance Book
</th>
<th className="text-left px-4 py-3 text-sm font-semibold text-gray-700 dark:text-gray-300 min-w-[200px]">
Depreciation Method*
</th>
<th className="text-left px-4 py-3 text-sm font-semibold text-gray-700 dark:text-gray-300 min-w-[180px]">
Total Depreciations*
</th>
<th className="text-left px-4 py-3 text-sm font-semibold text-gray-700 dark:text-gray-300 min-w-[180px]">
Frequency (Months)*
</th>
<th className="text-left px-4 py-3 text-sm font-semibold text-gray-700 dark:text-gray-300 min-w-[200px]">
Depreciation Posting Date*
</th>
{isEditing && (
<th className="text-center px-4 py-3 text-sm font-semibold text-gray-700 dark:text-gray-300 min-w-[120px]">
Action
</th>
)}
</tr>
</thead>
<tbody>
{formData.finance_books.map((row: AssetFinanceBookRow, idx: number) => (
<tr
key={idx}
className="border-b border-gray-200 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-750"
>
{/* Finance Book - with overflow visible */}
<td className="px-4 py-3 relative" style={{ overflow: 'visible' }}>
<div className="relative z-20">
<LinkField
label=""
doctype="Finance Book"
value={row.finance_book || ''}
onChange={(val) => updateFinanceRow(idx, { finance_book: val })}
disabled={!isEditing}
/>
</div>
</td>
{/* Depreciation Method */}
<td className="px-4 py-3">
<select
value={row.depreciation_method || ''}
onChange={(e) => updateFinanceRow(idx, { depreciation_method: e.target.value })}
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 Method</option>
<option value="Straight Line">Straight Line</option>
<option value="Double Declining Balance">Double Declining Balance</option>
<option value="Written Down Value">Written Down Value</option>
<option value="Manual">Manual</option>
</select>
</td>
{/* Total Depreciations */}
<td className="px-4 py-3">
<input
type="number"
value={row.total_number_of_depreciations ?? ''}
onChange={(e) =>
updateFinanceRow(idx, {
total_number_of_depreciations: Number(e.target.value),
})
}
disabled={!isEditing}
placeholder="0"
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"
/>
</td>
{/* Frequency */}
<td className="px-4 py-3">
<input
type="number"
value={row.frequency_of_depreciation ?? ''}
onChange={(e) =>
updateFinanceRow(idx, {
frequency_of_depreciation: Number(e.target.value),
})
}
disabled={!isEditing}
placeholder="0"
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"
/>
</td>
{/* Start Date */}
<td className="px-4 py-3">
<input
type="date"
value={row.depreciation_start_date || ''}
onChange={(e) =>
updateFinanceRow(idx, { depreciation_start_date: e.target.value })
}
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"
/>
</td>
{/* REMOVE BUTTON */}
{isEditing && (
<td className="px-4 py-3 text-center">
<button
type="button"
onClick={() => removeFinanceRow(idx)}
className="px-3 py-2 bg-red-600 text-white rounded-md hover:bg-red-700 transition-colors"
>
Remove
</button>
</td>
)}
</tr>
))}
</tbody>
</table>
</div>
</div>
)}
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
Depreciation Method
</label>
<select
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="">Straight Line</option>
</select>
</div>
)}
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
Depreciation Rate (%)
</label>
<input
type="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">
Current Value
</label>
<input
type="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 className="md:col-span-3">
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
Annual Rate
</label>
<input
type="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 className="md:col-span-3">
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
Current Value
</label>
<input
type="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 className="flex items-center mt-4">
<input
id="calculate_depreciation"
type="checkbox"
checked={formData.calculate_depreciation}
onChange={(e) =>
setFormData({
...formData,
calculate_depreciation: e.target.checked,
})
}
disabled={!isEditing}
className="h-4 w-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700"
/>
<label
htmlFor="calculate_depreciation"
className="ml-2 text-sm font-medium text-gray-700 dark:text-gray-300"
>
Calculate Depreciation
</label>
</div>
</div>
</div>
{/* End-of-Life Details */}

View File

@ -67,15 +67,6 @@ export interface AssetStats {
total_amount: number;
}
// Add child row type
export interface AssetFinanceBookRow {
finance_book?: string;
depreciation_method?: string;
total_number_of_depreciations?: number;
frequency_of_depreciation?: string;
depreciation_start_date?: string; // YYYY-MM-DD
}
export interface CreateAssetData {
asset_name: string;
company: string;
@ -96,7 +87,6 @@ export interface CreateAssetData {
custom_site_contractor?: string;
custom_total_amount?: number;
calculate_depreciation?: boolean;
finance_books?: AssetFinanceBookRow[];
[key: string]: any;
}