import { useEffect, useState } from "react"; import { useSupabaseClient } from "@supabase/auth-helpers-react"; import { HeadingLink, MinimalPage, PageHeading, Spinner } from "ui"; import type { Database } from "../../../types"; import dayjs from "dayjs"; const ShiftTable = () => { const [usersOnShift, setUsersOnShift] = useState< Array<{ user: string; shift_start: string | null }> >([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(""); const [offlineUserCount, setOfflineUserCount] = useState(0); const supabaseClient = useSupabaseClient<Database>(); useEffect(() => { const fetchUsers = async () => { setLoading(true); setError(""); try { // Fetch users on shift and their emails const { data: usersOnShiftData, error: onShiftError } = await supabaseClient .from("UserLastWorkedOn") .select("shift_start, user, users_view (email)") .not("shift_start", "is", null); // Fetch count of users not on shift (offline users) const { count: offlineCount, error: offShiftError } = await supabaseClient .from("UserLastWorkedOn") .select("user", { count: "exact" }) .is("shift_start", null); if (onShiftError || offShiftError) { setError( onShiftError?.message || offShiftError?.message || "Failed to fetch user shift data" ); return; } // Sort the users on shift by their email address const sortedUsersOnShift = (usersOnShiftData ?? []) .map((user) => ({ shift_start: user.shift_start, user: Array.isArray(user.users_view) ? user.users_view[0].email : user.users_view?.email ?? user.user, })) .sort((a, b) => a.user.localeCompare(b.user)); setUsersOnShift(sortedUsersOnShift); setOfflineUserCount(offlineCount ?? 0); } catch (err) { setError("Failed to fetch user data"); console.error(err); } finally { setLoading(false); } }; fetchUsers(); }, [supabaseClient]); return ( <MinimalPage pageTitle="Shift Table | Email Interface" pageDescription="Spot Ship Email Interface | Shift Table" commandPrompt > <div className="flex w-full flex-col items-center justify-center"> <HeadingLink icon="back" text="Home" href="/secure/home" /> <PageHeading text="Spot Ship Shift Table" /> <div className="mb-4 text-sm text-gray-400"> {usersOnShift.length} user(s) currently on shift. Offline users:{" "} {offlineUserCount}. </div> {loading ? ( <Spinner /> ) : error ? ( <p className="text-red-500">Error: {error}</p> ) : usersOnShift.length ? ( <div className="overflow-hidden overflow-x-auto rounded-3xl border-transparent shadow-lg"> <table className="table-auto rounded-xl bg-gray-800"> <thead className="bg-gray-700 text-gray-400"> <tr> <th className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider"> User Email </th> <th className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider"> Shift Started </th> </tr> </thead> <tbody className="divide-y divide-gray-700"> {usersOnShift.map((user, index) => ( <tr key={index}> <td className="whitespace-nowrap px-6 py-4 text-sm"> {user.user} </td> <td className="whitespace-nowrap px-6 py-4 text-sm"> {dayjs(user.shift_start).format("DD-MM-YYYY | HH:mm")} </td> </tr> ))} </tbody> </table> </div> ) : ( <p className="text-gray-400">No users are currently on shift</p> )} </div> </MinimalPage> ); }; export default ShiftTable;