3.0 KiB
3.0 KiB
معماری — تسک ۱۶: داشبورد هوشمند
فایلهایی که تغییر میکنند
src/Dashboard/Controller/DashboardController.php ← اضافه کردن from/to به query + فیلدهای جدید
src/Admin/Controller/AdminApiController.php ← متد dashboardCharts() → محدود به بازه زمانی
assets/admin/pages/DashboardPage.tsx ← date range selector + نمودارها
تغییر Backend
DashboardController — اضافه کردن from/to
#[Route('/api/v1/dashboard/clinic', methods: ['GET'])]
public function clinic(Request $request): JsonResponse
{
$from = (int) $request->query->get('from', strtotime('-30 days'));
$to = (int) $request->query->get('to', time());
// query موجود را محدود به بازه میکنیم:
// WHERE created_at BETWEEN :from AND :to
// فیلدهای جدید:
$smsBalance = $this->smsWalletRepo->getBalance($entityType, $entityId);
$uniquePatients = $this->patientRecordRepo->countUnique($entityType, $entityId, $from, $to);
$revenue = $this->patientSessionRepo->sumRevenue($entityType, $entityId, $from, $to);
return $this->success([
// ... فیلدهای موجود ...
'sms_wallet_balance' => $smsBalance,
'unique_patients_count' => $uniquePatients,
'revenue_period_rials' => $revenue,
]);
}
AdminApiController — dashboardCharts با بازه زمانی
#[Route('/api/v1/admin/dashboard/charts', methods: ['GET'])]
public function dashboardCharts(Request $request): JsonResponse
{
$from = (int) $request->query->get('from', strtotime('-30 days'));
$to = (int) $request->query->get('to', time());
// appointments_by_day: GROUP BY DATE(FROM_UNIXTIME(created_at))
// revenue_by_day: از patient_sessions در بازه
// subscription_sales_by_plan: از clinic_subscriptions در بازه
}
تغییر Frontend — DashboardPage.tsx
date range selector component:
type DateRangePreset = 'week' | 'month' | '3months' | 'custom';
interface DateRange {
from: number; // Unix timestamp
to: number;
}
function DateRangeSelector({ value, onChange }: {
value: DateRange;
onChange: (r: DateRange) => void;
}) {
// preset buttons + PersianCalendar برای custom range
}
نمودارها با Recharts:
import { LineChart, Line, BarChart, Bar, XAxis, YAxis, Tooltip, ResponsiveContainer } from 'recharts';
// chart نوبتها
<ResponsiveContainer width="100%" height={250}>
<LineChart data={chartsData?.appointments_by_day}>
<XAxis dataKey="date" tickFormatter={d => formatDate(d)} />
<YAxis />
<Tooltip />
<Line dataKey="count" stroke="#3b82f6" />
</LineChart>
</ResponsiveContainer>
// chart درآمد
<BarChart data={chartsData?.revenue_by_day}>
<Bar dataKey="amount_rials" fill="#10b981" />
</BarChart>
نصب dependency:
ddev exec yarn add recharts
ddev exec yarn add @types/recharts # اگر نیاز بود