Files
manager_employees_gui/src/pages/HomePage.tsx
T

97 lines
3.1 KiB
TypeScript

import { useEffect, useState } from "react";
import { getCompanies } from "@api/companiesApi";
import { getWeekSchedule } from "@api/scheduleApi";
import { getUsers } from "@api/usersApi";
import { PageHeader } from "@components/PageHeader";
import type { BackendPreference } from "@/types/backend";
import type { Company } from "@/types/companies";
import type { Schedule } from "@/types/schedule";
import type { Employee } from "@/types/users";
import styles from "./HomePage.module.scss";
type HomePageProps = {
backendPreference: BackendPreference;
onNavigate: (path: string) => void;
};
export function HomePage({ backendPreference, onNavigate }: HomePageProps) {
const [companies, setCompanies] = useState<Company[]>([]);
const [schedules, setSchedules] = useState<Schedule[]>([]);
const [users, setUsers] = useState<Employee[]>([]);
const [error, setError] = useState("");
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
let isMounted = true;
async function loadDashboard() {
setError("");
setIsLoading(true);
try {
const [companiesResponse, usersResponse, scheduleResponse] = await Promise.all([
getCompanies(backendPreference),
getUsers(backendPreference),
getWeekSchedule(backendPreference),
]);
if (isMounted) {
setCompanies(companiesResponse);
setUsers(usersResponse);
setSchedules(scheduleResponse.schedules);
}
} catch (loadError) {
if (isMounted) {
setError(
loadError instanceof Error ? loadError.message : "Unable to load dashboard data",
);
}
} finally {
if (isMounted) {
setIsLoading(false);
}
}
}
void loadDashboard();
return () => {
isMounted = false;
};
}, [backendPreference]);
const workingToday = new Set(
schedules
.filter(
(schedule): schedule is Schedule & { user_id: number } =>
typeof schedule.user_id === "number" && Boolean(schedule.enter_time && !schedule.out_time),
)
.map((schedule) => schedule.user_id),
).size;
return (
<>
<PageHeader
title="Employee Manager"
description="Track employee attendance, company teams, and weekly schedules from one dashboard."
/>
{error ? <p className={styles.error}>{error}</p> : null}
{isLoading ? <p className={styles.muted}>Loading dashboard...</p> : null}
<section className={styles.statsGrid} aria-label="Dashboard overview">
<button className={styles.card} onClick={() => onNavigate("/users")} type="button">
<span>Total users</span>
<strong>{users.length}</strong>
</button>
<button className={styles.card} onClick={() => onNavigate("/schedule")} type="button">
<span>Working today</span>
<strong>{workingToday}</strong>
</button>
<button className={styles.card} onClick={() => onNavigate("/companies")} type="button">
<span>Companies</span>
<strong>{companies.length}</strong>
</button>
</section>
</>
);
}