import type { LoaderFunctionArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { useLoaderData, useSearchParams } from "@remix-run/react"; import { requireAuth } from "~/lib/auth-middleware.server"; import { getFinancialSummary, getMonthlyFinancialData, getIncomeByMaintenanceType, getExpenseBreakdown, getTopCustomersByRevenue, getFinancialTrends } from "~/lib/financial-reporting.server"; import { DashboardLayout } from "~/components/layout/DashboardLayout"; import { Button } from "~/components/ui/Button"; import { Input } from "~/components/ui/Input"; import { useSettings } from "~/contexts/SettingsContext"; export async function loader({ request }: LoaderFunctionArgs) { const user = await requireAuth(request, 2); // Admin level required const url = new URL(request.url); const dateFrom = url.searchParams.get("dateFrom") ? new Date(url.searchParams.get("dateFrom")!) : undefined; const dateTo = url.searchParams.get("dateTo") ? new Date(url.searchParams.get("dateTo")!) : undefined; // Get all financial data const [ financialSummary, monthlyData, incomeByType, expenseBreakdown, topCustomers, trends ] = await Promise.all([ getFinancialSummary(dateFrom, dateTo), getMonthlyFinancialData(), getIncomeByMaintenanceType(dateFrom, dateTo), getExpenseBreakdown(dateFrom, dateTo), getTopCustomersByRevenue(10, dateFrom, dateTo), dateFrom && dateTo ? getFinancialTrends(dateFrom, dateTo) : null, ]); return json({ user, financialSummary, monthlyData, incomeByType, expenseBreakdown, topCustomers, trends, dateFrom: dateFrom?.toISOString().split('T')[0] || "", dateTo: dateTo?.toISOString().split('T')[0] || "", }); } export default function FinancialReportsPage() { const { formatCurrency } = useSettings(); const { user, financialSummary, monthlyData, incomeByType, expenseBreakdown, topCustomers, trends, dateFrom, dateTo } = useLoaderData(); const [searchParams, setSearchParams] = useSearchParams(); const handleDateFilter = (type: string, value: string) => { const newParams = new URLSearchParams(searchParams); if (value) { newParams.set(type, value); } else { newParams.delete(type); } setSearchParams(newParams); }; const clearFilters = () => { setSearchParams({}); }; return (

التقارير المالية

تحليل شامل للوضع المالي للمؤسسة

{/* Date Filters */}
handleDateFilter("dateFrom", e.target.value)} />
handleDateFilter("dateTo", e.target.value)} />
{/* Financial Summary Cards */}

إجمالي الإيرادات

{formatCurrency(financialSummary.totalIncome)}

{financialSummary.incomeCount} عملية

إجمالي المصروفات

{formatCurrency(financialSummary.totalExpenses)}

{financialSummary.expenseCount} مصروف

صافي الربح

= 0 ? 'text-green-600' : 'text-red-600'}`}> {formatCurrency(financialSummary.netProfit)}

هامش الربح: {financialSummary.profitMargin.toFixed(1)}%

= 0 ? 'bg-green-100' : 'bg-red-100' }`}> = 0 ? 'text-green-600' : 'text-red-600'}`} fill="none" stroke="currentColor" viewBox="0 0 24 24">

متوسط الإيراد الشهري

{formatCurrency(monthlyData.reduce((sum, month) => sum + month.income, 0) / Math.max(monthlyData.length, 1))}

آخر 12 شهر

{/* Trends (if date range is selected) */} {trends && (

مقارنة الفترات

نمو الإيرادات

= 0 ? 'text-green-600' : 'text-red-600'}`}> {trends.trends.incomeGrowth >= 0 ? '+' : ''}{trends.trends.incomeGrowth.toFixed(1)}%

نمو المصروفات

{trends.trends.expenseGrowth >= 0 ? '+' : ''}{trends.trends.expenseGrowth.toFixed(1)}%

نمو الأرباح

= 0 ? 'text-green-600' : 'text-red-600'}`}> {trends.trends.profitGrowth >= 0 ? '+' : ''}{trends.trends.profitGrowth.toFixed(1)}%

)} {/* Charts and Breakdowns */}
{/* Income by Maintenance Type */}

الإيرادات حسب نوع الصيانة

{incomeByType.map((item, index) => (
{item.category} {item.percentage.toFixed(1)}%
{formatCurrency(item.amount)} {item.count} عملية
))}
{/* Expense Breakdown */}

تفصيل المصروفات

{expenseBreakdown.map((item, index) => (
{item.category} {item.percentage.toFixed(1)}%
{formatCurrency(item.amount)} {item.count} مصروف
))}
{/* Top Customers and Monthly Data */}
{/* Top Customers */}

أفضل العملاء

{topCustomers.map((customer, index) => (
{index + 1}

{customer.customerName}

{customer.visitCount} زيارة

{formatCurrency(customer.totalRevenue)}

))}
{/* Monthly Performance */}

الأداء الشهري

{monthlyData.slice(-6).reverse().map((month, index) => (
{month.month} {month.year} = 0 ? 'text-green-600' : 'text-red-600'}`}> {formatCurrency(month.profit)}
الإيرادات: {formatCurrency(month.income)}
المصروفات: {formatCurrency(month.expenses)}
))}
); }