Skip to content

Commit e2164e8

Browse files
Merge pull request #24 from akirachix/develop
Develop
2 parents 54da018 + 55dcd2f commit e2164e8

File tree

24 files changed

+1181
-901
lines changed

24 files changed

+1181
-901
lines changed

tesfa/public/tesfalogo.png

1.28 KB
Loading

tesfa/src/app/admin/dashboard/page.tsx

Lines changed: 36 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -24,22 +24,15 @@ import {
2424
ResponsiveContainer,
2525
} from "recharts";
2626
import type { User, Country, QueryLog } from "@/app/utils/type";
27-
2827
export default function DashboardPage() {
2928
const { predictions, loading: predictionsLoading } = useFetchPredictions();
3029
const { tasks, loading: tasksLoading } = useFetchTasks();
3130
const { logs: queries, loading: queriesLoading } = useQueryLog();
3231
const { organizations, loading: organizationsLoading } = useFetchOrganizations();
3332
const { countries, loading: countriesLoading } = useCountries();
34-
3533
const [dateRange, setDateRange] = useState<[Date | null, Date | null]>([null, null]);
3634
const [startDate, endDate] = dateRange;
37-
38-
const isDateInRange = (
39-
dateString: string,
40-
start: Date | null,
41-
end: Date | null
42-
): boolean => {
35+
const isDateInRange = (dateString: string, start: Date | null, end: Date | null) => {
4336
if (!start || !end) return true;
4437
const date = new Date(dateString);
4538
const startOnly = new Date(start);
@@ -48,40 +41,33 @@ export default function DashboardPage() {
4841
endOnly.setHours(23, 59, 59, 999);
4942
return date >= startOnly && date <= endOnly;
5043
};
51-
5244
const filteredQueries =
5345
queries?.filter(
5446
(query: QueryLog) =>
5547
query.created_at && isDateInRange(query.created_at, startDate, endDate)
5648
) || [];
57-
5849
const filteredOrganizations =
5950
organizations?.filter((organization: User) =>
6051
isDateInRange(organization.created_at, startDate, endDate)
6152
) || [];
62-
6353
const filteredPredictions =
6454
predictions?.filter(
6555
(prediction: any) =>
6656
prediction.created_at && isDateInRange(prediction.created_at, startDate, endDate)
6757
) || [];
68-
6958
const filteredTasks =
7059
tasks?.filter(
7160
(task: any) =>
7261
task.created_at && isDateInRange(task.created_at, startDate, endDate)
7362
) || [];
74-
7563
const activeOrganizations = filteredOrganizations.filter(
7664
(organization: User) =>
7765
organization.role === "organization" && organization.is_active === true
7866
);
79-
8067
const getMonthLabel = (dateString: string): string => {
8168
const date = new Date(dateString);
8269
return date.toLocaleString("en-US", { month: "short", year: "2-digit" });
8370
};
84-
8571
const organizationsByMonth = activeOrganizations.reduce(
8672
(accumulator: Record<string, number>, organization: User) => {
8773
const monthLabel = getMonthLabel(organization.created_at);
@@ -90,88 +76,69 @@ export default function DashboardPage() {
9076
},
9177
{}
9278
);
93-
9479
const countriesByYear =
9580
countries?.reduce((accumulator: Record<string, number>, country: Country) => {
9681
const year = new Date().getFullYear().toString();
9782
accumulator[year] = (accumulator[year] || 0) + 1;
9883
return accumulator;
9984
}, {}) || {};
100-
10185
const countriesChartData = Object.entries(countriesByYear)
10286
.map(([year, value]) => ({ year, value }))
10387
.sort((a, b) => a.year.localeCompare(b.year));
104-
105-
10688
const predictionCount = filteredPredictions.length;
10789
const taskCount = filteredTasks.length;
10890
const queryCount = filteredQueries.length;
10991
const totalCount = predictionCount + taskCount + queryCount;
110-
11192
const pieChartData =
11293
totalCount === 0
11394
? [
11495
{ name: "Predict", value: 0, color: "#0f2e2e" },
11596
{ name: "List of Tasks", value: 0, color: "#d7ad05" },
116-
{ name: "Query", value: 0, color: "#395D7A" },
97+
{ name: "Query", value: 0, color: "#395d7a" },
11798
]
11899
: [
119100
{ name: "Predict", value: predictionCount, color: "#0f2e2e" },
120101
{ name: "List of Tasks", value: taskCount, color: "#d7ad05" },
121-
{ name: "Query", value: queryCount, color: "#395D7A" },
102+
{ name: "Query", value: queryCount, color: "#395d7a" },
122103
];
123-
124104
const isLoading =
125105
organizationsLoading ||
126106
predictionsLoading ||
127107
tasksLoading ||
128108
queriesLoading ||
129109
countriesLoading;
130-
131-
const generateMonthRange = (
132-
start: Date | null,
133-
end: Date | null
134-
): string[] => {
110+
const generateMonthRange = (start: Date | null, end: Date | null): string[] => {
135111
const now = new Date();
136-
137112
const defaultStart = new Date();
138113
defaultStart.setMonth(now.getMonth() - 5);
139114
const defaultEnd = now;
140-
141115
const rangeStart = start || defaultStart;
142116
const rangeEnd = end || defaultEnd;
143-
144117
const startDateMonth = new Date(rangeStart.getFullYear(), rangeStart.getMonth(), 1);
145118
const endDateMonth = new Date(rangeEnd.getFullYear(), rangeEnd.getMonth(), 1);
146-
147119
const months: string[] = [];
148120
const current = new Date(startDateMonth);
149-
150121
while (current <= endDateMonth) {
151122
months.push(
152123
current.toLocaleString("en-US", { month: "short", year: "2-digit" })
153124
);
154125
current.setMonth(current.getMonth() + 1);
155126
}
156-
157127
return months;
158128
};
159-
160129
const allMonths = generateMonthRange(startDate, endDate);
161-
const chartData = allMonths.map((month) => {
162-
const value = organizationsByMonth[month] || 0;
163-
return { month, value };
164-
});
165-
130+
const chartData = allMonths.map((month) => ({
131+
month,
132+
value: organizationsByMonth[month] || 0,
133+
}));
166134
return (
167-
<div className="flex h-screen">
135+
<div className="flex h-screen bg-gray-50">
168136
<Sidebar />
169-
<div className="flex-1 bg-white px-5 py-2">
137+
<div className="flex-1 flex flex-col bg-white px-2 md:px-5 xl:px-8 py-2 overflow-y-auto max-h-screen">
170138
<div className="mb-4">
171139
<CalendarPicker onDateChange={setDateRange} />
172140
</div>
173-
174-
<div className="grid grid-cols-4 bg-[#011729] text-yellow-400 rounded-md overflow-hidden">
141+
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 bg-[#011729] text-yellow-400 rounded-md mb-6 shadow-md">
175142
{[
176143
{
177144
label: "High Risk Areas",
@@ -208,32 +175,29 @@ export default function DashboardPage() {
208175
].map((statistic, index) => (
209176
<div
210177
key={index}
211-
className="text-center p-6 border-r border-teal-800 last:border-r-0"
178+
className="text-center p-6 border-b border-teal-800 sm:border-b-0 sm:border-r last:border-r-0"
212179
>
213-
<p className="text-xl">{statistic.label}</p>
180+
<p className="text-lg font-semibold">{statistic.label}</p>
214181
<div className="flex justify-center items-center h-8 text-2xl">
215182
{statistic.value}
216183
</div>
217184
</div>
218185
))}
219186
</div>
220-
221-
<div className="grid grid-cols-2 gap-6 mt-6">
222-
<div className="bg-blue-50 rounded-lg p-4 shadow hover:bg-blue-100 transition-shadow">
223-
<h2 className="text-lg font-semibold mb-4">
224-
Active Organizations
225-
</h2>
187+
188+
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
189+
<div className="bg-blue-50 rounded-lg p-4 shadow hover:bg-blue-100 transition">
190+
<h2 className="text-lg font-semibold mb-4">Active Organizations</h2>
226191
<ResponsiveContainer width="100%" height={300}>
227-
<BarChart data={chartData} data-testid="bar-chart">
192+
<BarChart data={chartData} data-testid="bar-chart">
228193
<XAxis dataKey="month" interval={0} />
229194
<YAxis />
230195
<Tooltip />
231-
<Bar dataKey="value" fill="#0f2e2e" />
196+
<Bar dataKey="value" fill="#0F2E2E" />
232197
</BarChart>
233198
</ResponsiveContainer>
234199
</div>
235-
236-
<div className="bg-blue-100 rounded-lg p-4 shadow hover:bg-blue-100 transition-shadow">
200+
<div className="bg-blue-100 rounded-lg p-4 shadow hover:bg-blue-200 transition">
237201
<h2 className="text-lg font-semibold mb-4">AI Functionality</h2>
238202
<ResponsiveContainer width="100%" height={300}>
239203
<PieChart data-testid="pie-chart">
@@ -252,9 +216,9 @@ export default function DashboardPage() {
252216
</ResponsiveContainer>
253217
</div>
254218
</div>
255-
256-
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6 mt-6">
257-
<div className="bg-blue-100 rounded-lg p-4 shadow hover:bg-blue-100 transition-shadow">
219+
220+
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6 mt-6 pb-8">
221+
<div className="bg-blue-100 rounded-lg p-4 shadow hover:bg-blue-200 transition">
258222
<h2 className="text-lg font-semibold mb-4">
259223
Number of High-Risk Countries
260224
</h2>
@@ -264,32 +228,22 @@ export default function DashboardPage() {
264228
<XAxis dataKey="year" />
265229
<YAxis />
266230
<Tooltip />
267-
<Line
268-
type="monotone"
269-
dataKey="value"
270-
stroke="#0f2e2e"
271-
strokeWidth={2}
272-
/>
231+
<Line type="monotone" dataKey="value" stroke="#0F2E2E" strokeWidth={2} />
273232
</LineChart>
274233
</ResponsiveContainer>
275234
</div>
276-
277-
<div className="bg-gray-50 rounded-lg p-2 shadow hover:bg-gray-100 transition-shadow">
235+
<div className="bg-gray-50 rounded-lg p-4 shadow hover:bg-gray-100 transition">
278236
<h2 className="text-lg font-semibold mb-4">High-Risk Countries</h2>
279237
{countriesLoading ? (
280-
<p className="text-gray-500">
281-
{isLoading ? (
282-
<FaSpinner className="animate-spin text-gray-500" />
283-
) : (
284-
<p className="text-2xl font-bold"></p>
285-
)}
286-
</p>
238+
<div className="flex justify-center items-center h-40">
239+
<FaSpinner className="animate-spin text-gray-500" />
240+
</div>
287241
) : countries && countries.length > 0 ? (
288-
<div className="max-h-70 overflow-y-auto pr-2 space-y-2">
242+
<div className="max-h-72 overflow-y-auto pr-2 space-y-2">
289243
{countries.map((country: Country) => (
290244
<div
291245
key={country.country_id}
292-
className="px-3 py-2 bg-[#0f2e2e] rounded border border-gray-200 text-white"
246+
className="px-3 py-2 bg-[#0F2E2E] rounded border border-gray-200 text-white"
293247
>
294248
{country.countries_name}
295249
</div>
@@ -303,4 +257,9 @@ export default function DashboardPage() {
303257
</div>
304258
</div>
305259
);
306-
}
260+
}
261+
262+
263+
264+
265+

0 commit comments

Comments
 (0)