adding gui for the application

This commit is contained in:
2026-09-18 11:11:59 -04:00
parent ff7aa065e3
commit 256e87c8c8
47 changed files with 4398 additions and 12055 deletions
+92
View File
@@ -0,0 +1,92 @@
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;
};
export function HomePage({ backendPreference }: 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.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">
<article className={styles.card}>
<span>Total users</span>
<strong>{users.length}</strong>
</article>
<article className={styles.card}>
<span>Working today</span>
<strong>{workingToday}</strong>
</article>
<article className={styles.card}>
<span>Companies</span>
<strong>{companies.length}</strong>
</article>
</section>
</>
);
}