Files
NeoCom/src/app/(dashboard)/finance/general-ledger/account/[accountId]/page.tsx
2026-04-09 20:36:10 -07:00

849 lines
35 KiB
TypeScript

'use client';
import { useState, useEffect } from 'react';
import { formatCurrency } from '@/lib/utils';
import Link from 'next/link';
import { useRouter } from 'next/navigation';
import {
ArrowLeft,
Loader2,
TrendingUp,
TrendingDown,
AlertCircle,
Edit2,
Download,
Plus,
Trash2,
} from 'lucide-react';
interface Account {
id: string;
accountCode: string;
accountName: string;
accountType: string;
isActive: boolean;
level: number;
description: string;
parentAccount: string | null;
}
interface Transaction {
id: string;
journalEntryId: string;
entryNumber: string;
entryDate: string;
status: string;
description: string;
entityName: string;
sourceModule?: string;
debitAmount: number;
creditAmount: number;
}
interface SubAccount {
id: string;
accountCode: string;
accountName: string;
accountType: string;
balance: number;
}
interface MonthlyData {
month: string;
debits: number;
credits: number;
balance: number;
}
interface AccountDetailData {
account: Account;
balance: number;
totalDebits: number;
totalCredits: number;
transactions: Transaction[];
subAccounts: SubAccount[];
monthlyData: MonthlyData[];
}
export default function AccountDetailPage({
params,
}: {
params: { accountId: string };
}) {
const router = useRouter();
const [data, setData] = useState<AccountDetailData | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const [activeTab, setActiveTab] = useState<'transactions' | 'sub-accounts' | 'analysis' | 'audit'>('transactions');
const [sortOrder, setSortOrder] = useState<'asc' | 'desc'>('desc');
// Edit Account State
const [isEditing, setIsEditing] = useState(false);
const [editForm, setEditForm] = useState({ name: '', description: '', status: '' });
const [isSaving, setIsSaving] = useState(false);
// Delete Account State
const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
const [isDeleting, setIsDeleting] = useState(false);
useEffect(() => {
const fetchAccountData = async () => {
try {
setLoading(true);
setError(null);
const response = await fetch(`/api/accounts/${params.accountId}`);
if (!response.ok) {
throw new Error('Failed to fetch account data');
}
const result = await response.json();
// Transform API response to match expected shape
const transformed: AccountDetailData = {
account: {
id: result.id,
accountCode: result.accountCode,
accountName: result.accountName,
accountType: result.accountType,
isActive: result.status === 'ACTIVE',
level: result.level || 1,
description: result.description || '',
parentAccount: result.parentAccount?.accountName || null,
},
balance: result.balance ?? 0,
totalDebits: result.totalDebits ?? 0,
totalCredits: result.totalCredits ?? 0,
transactions: (result.transactions || []).map((t: any) => ({
id: t.id,
journalEntryId: t.journalEntryId || t.journalEntry?.id,
entryNumber: t.journalEntry?.entryNumber || t.entryNumber || '',
entryDate: t.journalEntry?.entryDate || t.entryDate || '',
status: t.journalEntry?.status || t.status || '',
description: t.description || t.journalEntry?.description || '',
entityName: t.entity?.name || t.entityName || '',
debitAmount: t.debitAmount ?? 0,
creditAmount: t.creditAmount ?? 0,
})),
subAccounts: (result.subAccounts || []).map((s: any) => ({
id: s.id,
accountCode: s.accountCode,
accountName: s.accountName,
accountType: s.accountType,
balance: s.balance ?? 0,
})),
monthlyData: result.monthlyData
? (typeof result.monthlyData === 'object' && !Array.isArray(result.monthlyData)
? Object.entries(result.monthlyData)
.map(([month, data]: [string, any]) => ({
month,
debits: data.debits ?? 0,
credits: data.credits ?? 0,
balance: data.balance ?? 0,
}))
.sort((a, b) => a.month.localeCompare(b.month))
: result.monthlyData)
: [],
};
setData(transformed);
} catch (err) {
setError(err instanceof Error ? err.message : 'An error occurred');
} finally {
setLoading(false);
}
};
fetchAccountData();
}, [params.accountId]);
const handleEditClick = () => {
if (data) {
setEditForm({
name: data.account.accountName,
description: data.account.description,
status: data.account.isActive ? 'ACTIVE' : 'INACTIVE',
});
setIsEditing(true);
}
};
const handleEditCancel = () => {
setIsEditing(false);
setEditForm({ name: '', description: '', status: '' });
};
const handleSave = async () => {
if (!data) return;
try {
setIsSaving(true);
const res = await fetch(`/api/accounts`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
action: 'update',
id: data.account.id,
accountName: editForm.name,
description: editForm.description,
status: editForm.status,
}),
});
if (res.ok) {
// Refetch account data
const response = await fetch(`/api/accounts/${params.accountId}`);
if (response.ok) {
const result = await response.json();
const transformed: AccountDetailData = {
account: {
id: result.id,
accountCode: result.accountCode,
accountName: result.accountName,
accountType: result.accountType,
isActive: result.status === 'ACTIVE',
level: result.level || 1,
description: result.description || '',
parentAccount: result.parentAccount?.accountName || null,
},
balance: result.balance ?? 0,
totalDebits: result.totalDebits ?? 0,
totalCredits: result.totalCredits ?? 0,
transactions: (result.transactions || []).map((t: any) => ({
id: t.id,
journalEntryId: t.journalEntryId || t.journalEntry?.id,
entryNumber: t.journalEntry?.entryNumber || t.entryNumber || '',
entryDate: t.journalEntry?.entryDate || t.entryDate || '',
status: t.journalEntry?.status || t.status || '',
description: t.description || t.journalEntry?.description || '',
entityName: t.entity?.name || t.entityName || '',
debitAmount: t.debitAmount ?? 0,
creditAmount: t.creditAmount ?? 0,
})),
subAccounts: (result.subAccounts || []).map((s: any) => ({
id: s.id,
accountCode: s.accountCode,
accountName: s.accountName,
accountType: s.accountType,
balance: s.balance ?? 0,
})),
monthlyData: result.monthlyData
? (typeof result.monthlyData === 'object' && !Array.isArray(result.monthlyData)
? Object.entries(result.monthlyData)
.map(([month, monthData]: [string, any]) => ({
month,
debits: monthData.debits ?? 0,
credits: monthData.credits ?? 0,
balance: monthData.balance ?? 0,
}))
.sort((a, b) => a.month.localeCompare(b.month))
: result.monthlyData)
: [],
};
setData(transformed);
}
setIsEditing(false);
setEditForm({ name: '', description: '', status: '' });
}
} catch (err) {
console.error('Error saving account:', err);
} finally {
setIsSaving(false);
}
};
const handleStatusToggle = async () => {
if (!data) return;
try {
setIsSaving(true);
const newStatus = data.account.isActive ? 'INACTIVE' : 'ACTIVE';
const res = await fetch(`/api/accounts`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
action: 'update',
id: data.account.id,
status: newStatus,
}),
});
if (res.ok) {
setData({
...data,
account: { ...data.account, isActive: newStatus === 'ACTIVE' },
});
}
} catch (err) {
console.error('Error toggling status:', err);
} finally {
setIsSaving(false);
}
};
const handleExport = () => {
if (!data) return;
const headers = ['Date', 'Entry #', 'Description', 'Entity', 'Source', 'Debit', 'Credit'];
const rows = data.transactions.map((tx) => [
new Date(tx.entryDate).toLocaleDateString('en-US'),
tx.entryNumber,
tx.description,
tx.entityName,
tx.sourceModule || 'Manual',
tx.debitAmount > 0 ? tx.debitAmount.toFixed(2) : '',
tx.creditAmount > 0 ? tx.creditAmount.toFixed(2) : '',
]);
const csv = [
headers.join(','),
...rows.map((row) => row.map((cell) => `"${cell}"`).join(',')),
].join('\n');
const blob = new Blob([csv], { type: 'text/csv' });
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `${data.account.accountCode}-transactions.csv`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
};
const handleDelete = async () => {
if (!data) return;
try {
setIsDeleting(true);
const res = await fetch(`/api/accounts`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
action: 'delete',
id: data.account.id,
}),
});
if (res.ok) {
router.push('/finance/general-ledger');
}
} catch (err) {
console.error('Error deleting account:', err);
} finally {
setIsDeleting(false);
setShowDeleteConfirm(false);
}
};
if (loading) {
return (
<div className="min-h-screen bg-[#111114] flex items-center justify-center">
<div className="flex flex-col items-center gap-4">
<Loader2 className="w-8 h-8 text-blue-600 animate-spin" />
<p className="text-[#8B8B9E]">Loading account details...</p>
</div>
</div>
);
}
if (error || !data) {
return (
<div className="min-h-screen bg-[#111114]">
<div className="max-w-7xl mx-auto px-6 py-8">
<Link
href="/finance/general-ledger"
className="flex items-center gap-2 text-blue-600 hover:text-blue-700 mb-6"
>
<ArrowLeft className="w-4 h-4" />
Back to General Ledger
</Link>
<div className="bg-[#1A1A1F] rounded-lg border border-red-200 p-6 flex items-start gap-4">
<AlertCircle className="w-6 h-6 text-red-600 flex-shrink-0 mt-0.5" />
<div>
<h2 className="text-lg font-semibold text-[#F0F0F3] mb-1">Error Loading Account</h2>
<p className="text-[#8B8B9E]">{error || 'Account not found'}</p>
</div>
</div>
</div>
</div>
);
}
const { account, balance, totalDebits, totalCredits, transactions, subAccounts, monthlyData } = data;
const sortedTransactions = [...transactions].sort((a, b) => {
const dateA = new Date(a.entryDate).getTime();
const dateB = new Date(b.entryDate).getTime();
return sortOrder === 'desc' ? dateB - dateA : dateA - dateB;
});
const getAccountTypeBadge = (type: string) => {
const colors: Record<string, { bg: string; text: string }> = {
ASSET: { bg: 'bg-blue-900/25', text: 'text-blue-700' },
LIABILITY: { bg: 'bg-red-900/25', text: 'text-red-700' },
EQUITY: { bg: 'bg-purple-900/25', text: 'text-purple-700' },
REVENUE: { bg: 'bg-green-900/25', text: 'text-green-700' },
EXPENSE: { bg: 'bg-orange-900/25', text: 'text-orange-700' },
};
const color = colors[type] || { bg: 'bg-[#1A1A1F]', text: 'text-[#8B8B9E]' };
return (
<span className={`inline-flex items-center px-3 py-1 rounded-full text-sm font-medium ${color.bg} ${color.text}`}>
{type}
</span>
);
};
const getMaxMonthlyValue = () => {
return Math.max(...monthlyData.map(m => Math.max(m.debits, m.credits, Math.abs(m.balance))), 1);
};
const maxValue = getMaxMonthlyValue();
return (
<div className="min-h-screen bg-[#111114]">
{/* Header */}
<div className="bg-[#1A1A1F] border-b border-[#2A2A32] sticky top-0 z-40">
<div className="max-w-7xl mx-auto px-6 py-4">
<div className="flex items-center justify-between gap-4 mb-4">
<div className="flex items-center gap-4">
<Link
href="/finance/general-ledger"
className="p-2 hover:bg-[#1A1A1F] rounded-lg transition-colors"
>
<ArrowLeft className="w-5 h-5 text-[#8B8B9E]" />
</Link>
<div>
<div className="flex items-center gap-3 mb-2">
<h1 className="text-2xl font-bold text-[#F0F0F3]">
{account.accountCode}
</h1>
{getAccountTypeBadge(account.accountType)}
</div>
<p className="text-[#8B8B9E]">{account.accountName}</p>
</div>
</div>
{!isEditing && (
<div className="flex items-center gap-2">
<button
onClick={handleEditClick}
className="flex items-center gap-2 px-3 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors text-sm font-medium"
>
<Edit2 className="w-4 h-4" />
Edit
</button>
<button
onClick={handleExport}
className="flex items-center gap-2 px-3 py-2 bg-[#2A2A32] text-[#8B8B9E] rounded-lg hover:bg-[#333340] transition-colors text-sm font-medium"
>
<Download className="w-4 h-4" />
Export
</button>
<Link
href={`/finance/general-ledger/new-entry?accountId=${params.accountId}`}
className="flex items-center gap-2 px-3 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 transition-colors text-sm font-medium"
>
<Plus className="w-4 h-4" />
New Entry
</Link>
</div>
)}
</div>
<div className="flex items-center justify-between gap-6 text-sm">
<div>
<p className="text-xs text-[#5A5A6E] uppercase tracking-wide">Status</p>
<p className="text-[#F0F0F3] font-medium mt-1">
{account.isActive ? (
<span className="text-green-600">Active</span>
) : (
<span className="text-red-600">Inactive</span>
)}
</p>
</div>
{!isEditing && (
<button
onClick={handleStatusToggle}
disabled={isSaving}
className={`px-4 py-2 rounded-lg text-sm font-medium transition-colors ${
account.isActive
? 'bg-red-900/25 text-red-700 hover:bg-red-900/40'
: 'bg-green-900/25 text-green-700 hover:bg-green-900/40'
} disabled:opacity-50`}
>
{account.isActive ? 'Deactivate' : 'Activate'}
</button>
)}
</div>
</div>
</div>
{/* Edit Mode Header */}
{isEditing && (
<div className="bg-blue-900/15 border-b border-blue-200">
<div className="max-w-7xl mx-auto px-6 py-4">
<div className="space-y-4">
<div>
<label className="block text-sm font-medium text-[#8B8B9E] mb-1">Account Name</label>
<input
type="text"
value={editForm.name}
onChange={(e) => setEditForm({ ...editForm, name: e.target.value })}
className="w-full px-3 py-2 border border-[#3A3A45] rounded-lg focus:ring-2 focus:ring-blue-600 focus:border-transparent"
/>
</div>
<div>
<label className="block text-sm font-medium text-[#8B8B9E] mb-1">Description</label>
<textarea
value={editForm.description}
onChange={(e) => setEditForm({ ...editForm, description: e.target.value })}
rows={2}
className="w-full px-3 py-2 border border-[#3A3A45] rounded-lg focus:ring-2 focus:ring-blue-600 focus:border-transparent"
/>
</div>
<div>
<label className="block text-sm font-medium text-[#8B8B9E] mb-1">Status</label>
<select
value={editForm.status}
onChange={(e) => setEditForm({ ...editForm, status: e.target.value })}
className="w-full px-3 py-2 border border-[#3A3A45] rounded-lg focus:ring-2 focus:ring-blue-600 focus:border-transparent"
>
<option value="ACTIVE">Active</option>
<option value="INACTIVE">Inactive</option>
</select>
</div>
<div className="flex items-center gap-2">
<button
onClick={handleSave}
disabled={isSaving}
className="px-4 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 transition-colors font-medium disabled:opacity-50"
>
{isSaving ? 'Saving...' : 'Save'}
</button>
<button
onClick={handleEditCancel}
disabled={isSaving}
className="px-4 py-2 bg-gray-300 text-[#8B8B9E] rounded-lg hover:bg-gray-400 transition-colors font-medium disabled:opacity-50"
>
Cancel
</button>
</div>
</div>
</div>
</div>
)}
{/* Main Content */}
<div className="max-w-7xl mx-auto px-6 py-8">
{/* Summary Cards */}
<div className="grid grid-cols-2 md:grid-cols-4 gap-4 mb-6">
<div className="bg-[#1A1A1F] rounded-lg border border-[#2A2A32] p-6">
<p className="text-xs font-semibold text-[#5A5A6E] uppercase tracking-wide">Current Balance</p>
<p className="text-2xl font-bold text-[#F0F0F3] mt-2">
{formatCurrency(balance)}
</p>
{balance >= 0 ? (
<div className="flex items-center gap-1 mt-2 text-green-600 text-sm">
<TrendingUp className="w-4 h-4" />
Positive
</div>
) : (
<div className="flex items-center gap-1 mt-2 text-red-600 text-sm">
<TrendingDown className="w-4 h-4" />
Negative
</div>
)}
</div>
<div className="bg-[#1A1A1F] rounded-lg border border-[#2A2A32] p-6">
<p className="text-xs font-semibold text-[#5A5A6E] uppercase tracking-wide">Total Debits</p>
<p className="text-2xl font-bold text-[#F0F0F3] mt-2">
{formatCurrency(totalDebits)}
</p>
<p className="text-sm text-[#8B8B9E] mt-2">All time</p>
</div>
<div className="bg-[#1A1A1F] rounded-lg border border-[#2A2A32] p-6">
<p className="text-xs font-semibold text-[#5A5A6E] uppercase tracking-wide">Total Credits</p>
<p className="text-2xl font-bold text-[#F0F0F3] mt-2">
{formatCurrency(totalCredits)}
</p>
<p className="text-sm text-[#8B8B9E] mt-2">All time</p>
</div>
<div className="bg-[#1A1A1F] rounded-lg border border-[#2A2A32] p-6">
<p className="text-xs font-semibold text-[#5A5A6E] uppercase tracking-wide">Transactions</p>
<p className="text-2xl font-bold text-[#F0F0F3] mt-2">
{transactions.length}
</p>
<p className="text-sm text-[#8B8B9E] mt-2">Journal entries</p>
</div>
</div>
{/* Tabs */}
<div className="bg-[#1A1A1F] rounded-lg border border-[#2A2A32]">
<div className="border-b border-[#2A2A32]">
<div className="flex gap-8 px-6">
{(['transactions', 'sub-accounts', 'analysis', 'audit'] as const).map((tab) => (
<button
key={tab}
onClick={() => setActiveTab(tab)}
className={`py-4 px-0 font-medium text-sm border-b-2 transition-colors ${
activeTab === tab
? 'border-blue-600 text-blue-600'
: 'border-transparent text-[#8B8B9E] hover:text-[#F0F0F3]'
}`}
>
{tab === 'transactions' && 'Transactions'}
{tab === 'sub-accounts' && 'Sub-Accounts'}
{tab === 'analysis' && 'Analysis'}
{tab === 'audit' && 'Audit Trail'}
</button>
))}
</div>
</div>
<div className="p-6">
{/* Transactions Tab */}
{activeTab === 'transactions' && (
<div>
<div className="flex items-center justify-between mb-4">
<h2 className="text-lg font-semibold text-[#F0F0F3]">Journal Entry Transactions</h2>
<button
onClick={() => setSortOrder(sortOrder === 'desc' ? 'asc' : 'desc')}
className="text-sm text-[#8B8B9E] hover:text-[#F0F0F3]"
>
Sort: {sortOrder === 'desc' ? 'Newest First' : 'Oldest First'}
</button>
</div>
<div className="overflow-x-auto">
<table className="w-full">
<thead className="bg-[#111114] border-b border-[#2A2A32]">
<tr>
<th className="px-6 py-3 text-left text-xs font-semibold text-[#8B8B9E] uppercase tracking-wide">Date</th>
<th className="px-6 py-3 text-left text-xs font-semibold text-[#8B8B9E] uppercase tracking-wide">Entry #</th>
<th className="px-6 py-3 text-left text-xs font-semibold text-[#8B8B9E] uppercase tracking-wide">Description</th>
<th className="px-6 py-3 text-left text-xs font-semibold text-[#8B8B9E] uppercase tracking-wide">Entity</th>
<th className="px-6 py-3 text-left text-xs font-semibold text-[#8B8B9E] uppercase tracking-wide">Source</th>
<th className="px-6 py-3 text-right text-xs font-semibold text-[#8B8B9E] uppercase tracking-wide">Debit</th>
<th className="px-6 py-3 text-right text-xs font-semibold text-[#8B8B9E] uppercase tracking-wide">Credit</th>
</tr>
</thead>
<tbody>
{sortedTransactions.map((tx, idx) => (
<tr key={tx.id} className={idx % 2 === 0 ? 'bg-[#1A1A1F]' : 'bg-[#111114]'}>
<td className="px-6 py-4 text-sm text-[#8B8B9E] font-medium">
{new Date(tx.entryDate).toLocaleDateString('en-US', {
year: 'numeric',
month: 'short',
day: 'numeric',
})}
</td>
<td className="px-6 py-4">
<Link
href={`/finance/general-ledger/entry/${tx.journalEntryId}`}
className="text-blue-600 hover:text-blue-700 hover:underline text-sm font-medium"
>
{tx.entryNumber}
</Link>
</td>
<td className="px-6 py-4 text-sm text-[#F0F0F3]">
{tx.description}
</td>
<td className="px-6 py-4 text-sm text-[#8B8B9E]">
{tx.entityName}
</td>
<td className="px-6 py-4 text-sm">
<span className="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-[#1A1A1F] text-[#8B8B9E]">
{tx.sourceModule || 'Manual'}
</span>
</td>
<td className="px-6 py-4 text-sm text-right font-medium">
{tx.debitAmount > 0 ? formatCurrency(tx.debitAmount) : '—'}
</td>
<td className="px-6 py-4 text-sm text-right font-medium">
{tx.creditAmount > 0 ? formatCurrency(tx.creditAmount) : '—'}
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
)}
{/* Sub-Accounts Tab */}
{activeTab === 'sub-accounts' && (
<div>
<h2 className="text-lg font-semibold text-[#F0F0F3] mb-4">Sub-Accounts</h2>
{subAccounts.length === 0 ? (
<p className="text-[#8B8B9E]">No sub-accounts</p>
) : (
<div className="overflow-x-auto">
<table className="w-full">
<thead className="bg-[#111114] border-b border-[#2A2A32]">
<tr>
<th className="px-6 py-3 text-left text-xs font-semibold text-[#8B8B9E] uppercase tracking-wide">Code</th>
<th className="px-6 py-3 text-left text-xs font-semibold text-[#8B8B9E] uppercase tracking-wide">Name</th>
<th className="px-6 py-3 text-left text-xs font-semibold text-[#8B8B9E] uppercase tracking-wide">Type</th>
<th className="px-6 py-3 text-right text-xs font-semibold text-[#8B8B9E] uppercase tracking-wide">Balance</th>
</tr>
</thead>
<tbody>
{subAccounts.map((subAcc, idx) => (
<tr key={subAcc.id} className={idx % 2 === 0 ? 'bg-[#1A1A1F]' : 'bg-[#111114]'}>
<td className="px-6 py-4">
<Link
href={`/finance/general-ledger/account/${subAcc.accountCode}`}
className="text-blue-600 hover:text-blue-700 hover:underline text-sm font-medium"
>
{subAcc.accountCode}
</Link>
</td>
<td className="px-6 py-4 text-sm text-[#F0F0F3] font-medium">
{subAcc.accountName}
</td>
<td className="px-6 py-4 text-sm">
{getAccountTypeBadge(subAcc.accountType)}
</td>
<td className="px-6 py-4 text-sm text-right font-medium">
{formatCurrency(subAcc.balance)}
</td>
</tr>
))}
</tbody>
</table>
</div>
)}
</div>
)}
{/* Analysis Tab */}
{activeTab === 'analysis' && (
<div>
<h2 className="text-lg font-semibold text-[#F0F0F3] mb-6">Monthly Trend Analysis</h2>
<div className="space-y-6">
{monthlyData.map((month) => (
<div key={month.month}>
<div className="flex items-center justify-between mb-2">
<p className="text-sm font-medium text-[#F0F0F3]">
{new Date(month.month + '-01').toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
})}
</p>
<div className="flex gap-4 text-sm">
<div>
<span className="text-[#8B8B9E]">Debits: </span>
<span className="font-semibold text-[#F0F0F3]">{formatCurrency(month.debits)}</span>
</div>
<div>
<span className="text-[#8B8B9E]">Credits: </span>
<span className="font-semibold text-[#F0F0F3]">{formatCurrency(month.credits)}</span>
</div>
<div>
<span className="text-[#8B8B9E]">Balance: </span>
<span className={`font-semibold ${month.balance >= 0 ? 'text-green-600' : 'text-red-600'}`}>
{formatCurrency(month.balance)}
</span>
</div>
</div>
</div>
<div className="flex items-end gap-2 h-16 bg-[#111114] p-3 rounded-lg">
<div className="flex-1 flex items-end gap-1">
<div
className="flex-1 bg-blue-500 rounded-sm"
style={{ height: `${(month.debits / maxValue) * 100}%` }}
title={`Debits: ${formatCurrency(month.debits)}`}
/>
<div
className="flex-1 bg-red-500 rounded-sm"
style={{ height: `${(month.credits / maxValue) * 100}%` }}
title={`Credits: ${formatCurrency(month.credits)}`}
/>
<div
className={`flex-1 ${month.balance >= 0 ? 'bg-green-500' : 'bg-orange-500'} rounded-sm`}
style={{ height: `${(Math.abs(month.balance) / maxValue) * 100}%` }}
title={`Balance: ${formatCurrency(month.balance)}`}
/>
</div>
</div>
</div>
))}
</div>
<div className="flex gap-6 mt-8 pt-6 border-t border-[#2A2A32]">
<div className="flex items-center gap-2">
<div className="w-4 h-4 bg-blue-500 rounded-sm" />
<span className="text-sm text-[#8B8B9E]">Debits</span>
</div>
<div className="flex items-center gap-2">
<div className="w-4 h-4 bg-red-500 rounded-sm" />
<span className="text-sm text-[#8B8B9E]">Credits</span>
</div>
<div className="flex items-center gap-2">
<div className="w-4 h-4 bg-green-500 rounded-sm" />
<span className="text-sm text-[#8B8B9E]">Balance (Positive)</span>
</div>
</div>
</div>
)}
{/* Audit Trail Tab */}
{activeTab === 'audit' && (
<div>
<h2 className="text-lg font-semibold text-[#F0F0F3] mb-4">Account Audit Trail</h2>
<div className="space-y-4">
<div className="bg-[#111114] p-4 rounded-lg">
<p className="text-sm text-[#8B8B9E] mb-1">
<span className="font-medium text-[#F0F0F3]">Account Created:</span> {account.accountCode}
</p>
<p className="text-xs text-[#5A5A6E]">
{account.accountName}
</p>
</div>
<p className="text-sm text-[#8B8B9E] text-center py-4">
Detailed audit trail coming soon
</p>
</div>
</div>
)}
</div>
</div>
</div>
{/* Delete Confirmation Dialog */}
{showDeleteConfirm && (
<div className="fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center">
<div className="bg-[#1A1A1F] rounded-lg shadow-lg max-w-md w-full mx-4 p-6">
<h3 className="text-lg font-semibold text-[#F0F0F3] mb-2">Delete Account</h3>
<p className="text-[#8B8B9E] mb-6">
Are you sure you want to delete this account? This action cannot be undone. All associated transaction records will remain for audit purposes.
</p>
<div className="flex items-center gap-3">
<button
onClick={handleDelete}
disabled={isDeleting}
className="flex-1 px-4 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors font-medium disabled:opacity-50"
>
{isDeleting ? 'Deleting...' : 'Delete Account'}
</button>
<button
onClick={() => setShowDeleteConfirm(false)}
disabled={isDeleting}
className="flex-1 px-4 py-2 bg-gray-300 text-[#8B8B9E] rounded-lg hover:bg-gray-400 transition-colors font-medium disabled:opacity-50"
>
Cancel
</button>
</div>
</div>
</div>
)}
{/* Danger Zone */}
<div className="max-w-7xl mx-auto px-6 py-8">
<div className="bg-red-900/15 border border-red-200 rounded-lg p-6">
<h3 className="text-lg font-semibold text-red-900 mb-2">Danger Zone</h3>
<p className="text-red-700 text-sm mb-4">
Deleting this account will remove it from the chart of accounts. Existing transactions will be preserved for audit purposes.
</p>
<button
onClick={() => setShowDeleteConfirm(true)}
className="flex items-center gap-2 px-4 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors font-medium"
>
<Trash2 className="w-4 h-4" />
Delete Account
</button>
</div>
</div>
</div>
);
}