This commit is contained in:
2026-03-08 14:27:16 +03:00
parent 66c151653e
commit 11b58b68c3
22 changed files with 4652 additions and 204 deletions

View File

@@ -443,26 +443,137 @@ export default function ExpensesPage() {
</div>
{/* Action Messages */}
{actionData?.success && actionData.message && (
{actionData?.success && 'message' in actionData && actionData.message && (
<div className="bg-green-50 border border-green-200 text-green-800 px-4 py-3 rounded-lg">
{actionData.message}
</div>
)}
{actionData?.error && (
{actionData && !actionData.success && 'error' in actionData && actionData.error && (
<div className="bg-red-50 border border-red-200 text-red-800 px-4 py-3 rounded-lg">
{actionData.error}
</div>
)}
{/* Expenses Table */}
<DataTable
data={expenses}
columns={columns}
currentPage={currentPage}
totalPages={totalPages}
onPageChange={handlePageChange}
/>
<div className="bg-white rounded-lg shadow-sm border">
{expenses.length === 0 ? (
<div className="text-center py-12">
<div className="text-gray-400 text-lg mb-2">💰</div>
<h3 className="text-lg font-medium text-gray-900 mb-2">
لا توجد مصروفات
</h3>
<p className="text-gray-500">
لم يتم العثور على أي مصروفات.
</p>
</div>
) : (
<>
{/* Desktop Table View */}
<div className="hidden md:block">
<DataTable
data={expenses as any}
columns={columns}
emptyMessage="لم يتم العثور على أي مصروفات"
/>
</div>
{/* Mobile Card View */}
<div className="md:hidden divide-y divide-gray-200">
{expenses.map((expense: any) => {
const categoryLabel = EXPENSE_CATEGORIES.find(c => c.value === expense.category)?.label;
return (
<div key={expense.id} className="p-4 hover:bg-gray-50">
<div className="space-y-3">
<div className="flex justify-between items-start">
<div className="flex-1">
<div className="font-medium text-gray-900">{expense.description}</div>
<div className="text-sm text-gray-500 mt-1">{categoryLabel || expense.category}</div>
</div>
<div className="text-lg font-semibold text-gray-900">
{formatCurrency(expense.amount)}
</div>
</div>
<div className="grid grid-cols-2 gap-2 text-sm">
<div>
<span className="text-gray-600">تاريخ المصروف: </span>
<span className="text-gray-900">{formatDate(expense.expenseDate)}</span>
</div>
<div>
<span className="text-gray-600">تاريخ الإضافة: </span>
<span className="text-gray-900">{formatDate(expense.createdDate)}</span>
</div>
</div>
<div className="pt-2">
<Button
variant="outline"
size="sm"
onClick={() => handleEditExpense(expense)}
disabled={isLoading}
className="w-full"
>
تعديل
</Button>
</div>
</div>
</div>
);
})}
</div>
</>
)}
{/* Pagination */}
{totalPages > 1 && (
<div className="px-4 py-3 border-t border-gray-200 bg-gray-50">
<div className="flex items-center justify-between">
<div className="flex items-center space-x-2 space-x-reverse">
<button
onClick={() => handlePageChange(currentPage - 1)}
disabled={currentPage === 1 || isLoading}
className="px-3 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 rounded-md hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed"
>
السابق
</button>
<div className="flex items-center space-x-1 space-x-reverse">
{Array.from({ length: Math.min(5, totalPages) }, (_, i) => {
const page = i + 1;
return (
<button
key={page}
onClick={() => handlePageChange(page)}
disabled={isLoading}
className={`px-3 py-2 text-sm font-medium rounded-md ${
currentPage === page
? 'bg-blue-600 text-white'
: 'text-gray-500 bg-white border border-gray-300 hover:bg-gray-50'
} disabled:opacity-50 disabled:cursor-not-allowed`}
>
{page}
</button>
);
})}
</div>
<button
onClick={() => handlePageChange(currentPage + 1)}
disabled={currentPage === totalPages || isLoading}
className="px-3 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 rounded-md hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed"
>
التالي
</button>
</div>
<p className="text-sm text-gray-500">
صفحة {currentPage} من {totalPages}
</p>
</div>
</div>
)}
</div>
{/* Create Expense Modal */}
<Modal
@@ -472,7 +583,7 @@ export default function ExpensesPage() {
>
<ExpenseForm
onCancel={() => setShowCreateModal(false)}
errors={actionData?.action === "create" ? actionData.errors : undefined}
errors={actionData && 'errors' in actionData ? actionData.errors : undefined}
isLoading={isLoading}
/>
</Modal>
@@ -487,7 +598,7 @@ export default function ExpensesPage() {
<ExpenseForm
expense={selectedExpense}
onCancel={() => setShowEditModal(false)}
errors={actionData?.action === "update" ? actionData.errors : undefined}
errors={actionData && 'errors' in actionData ? actionData.errors : undefined}
isLoading={isLoading}
/>
)}