My last created Shift Table 16.04.2024
Mon Apr 15 2024 22:46:59 GMT+0000 (Coordinated Universal Time)
Saved by @rafal_rydz
import React, { useEffect, useState } from "react"; import { useSupabaseClient } from "@supabase/auth-helpers-react"; import { HeadingLink, MinimalPage, PageHeading, Spinner } from "ui"; import dayjs from "dayjs"; import { useRouter } from "next/router"; // Define types for users on and off shift type UserOnShift = { shift_start: string | null; user: string; // Email from 'users_view' }; type OfflineUser = { user: string; // Email from 'users_view' }; const ShiftTable = () => { const [usersOnShift, setUsersOnShift] = useState<UserOnShift[]>([]); const [usersOffShift, setUsersOffShift] = useState<OfflineUser[]>([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(""); const [showModal, setShowModal] = useState(false); const [selectedUser, setSelectedUser] = useState<UserOnShift | null>(null); const supabaseClient = useSupabaseClient(); const router = useRouter(); const excludedUuid = "2b78abeb-133d-4248-8469-21620903cbb3"; useEffect(() => { const fetchUsers = async () => { setLoading(true); setError(""); try { const { data: usersOnShiftData, error: onShiftError } = await supabaseClient .from("UserLastWorkedOn") .select("shift_start, user, users_view (email)") .not("user", "eq", excludedUuid) .not("shift_start", "is", null); const { data: usersOffShiftData, error: offShiftError } = await supabaseClient .from("UserLastWorkedOn") .select("user, users_view (email)") .not("user", "eq", excludedUuid) .is("shift_start", null); if (onShiftError || offShiftError) { setError( onShiftError?.message || offShiftError?.message || "Failed to fetch user data." ); return; } const sortedOnShift = usersOnShiftData .map((user) => ({ shift_start: user.shift_start, user: user.users_view?.email ?? user.user, })) .sort((a, b) => a.user.localeCompare(b.user)); const sortedOffShift = usersOffShiftData .map((user) => ({ user: user.users_view?.email ?? user.user, })) .sort((a, b) => a.user.localeCompare(b.user)); setUsersOnShift(sortedOnShift); setUsersOffShift(sortedOffShift); } catch (err) { setError("Failed to fetch user data: " + err.message); } finally { setLoading(false); } }; fetchUsers(); }, [supabaseClient]); const handleUserClick = (user: UserOnShift) => { setSelectedUser(user); setShowModal(true); }; const closeModal = () => { setShowModal(false); setSelectedUser(null); }; const navigateToUserHistory = () => { if (selectedUser) { router.push(`/user-history/${selectedUser.user}`); // Adjust the route as needed closeModal(); } }; return ( <MinimalPage pageTitle="Shift Table | Email Interface" pageDescription="Spot Ship Email Interface | Shift Table" commandPrompt > <div className="w-full"> <HeadingLink icon="back" text="Home" href="/secure/home" /> </div> <PageHeading text="Spot Ship Shift Table" /> <div className="mb-4 text-sm text-gray-400"> {usersOnShift.length} user(s) currently on shift. Offline users:{" "} {usersOffShift.length}. </div> {loading ? ( <Spinner /> ) : error ? ( <p className="text-red-500">{error}</p> ) : ( <> <div className="mt-8 w-full px-4"> {renderUsersGrid( "Users Currently On Shift", usersOnShift, true, handleUserClick )} </div> <div className="mt-8 w-full px-4"> {renderUsersGrid( "Offline Users", usersOffShift, false, handleUserClick )} </div> </> )} {showModal && selectedUser && ( <div className="absolute bottom-0 left-0 right-0 top-0 flex items-center justify-center bg-black bg-opacity-50"> <div className="rounded-lg bg-white p-4 shadow-lg"> <h3 className="text-lg font-bold">User Actions</h3> <p>{`Show ${selectedUser.user}'s history?`}</p> <button className="rounded bg-blue-500 px-4 py-2 font-bold text-white hover:bg-blue-700" onClick={navigateToUserHistory} > View History </button> <button className="ml-2 rounded bg-gray-300 px-4 py-2 text-black hover:bg-gray-400" onClick={closeModal} > Cancel </button> </div> </div> )} </MinimalPage> ); function renderUsersGrid( title: string, users: any[], showShiftStart: boolean, onClick: (user: UserOnShift) => void ) { return ( <div className="overflow-hidden overflow-x-auto rounded-3xl border-transparent shadow-lg"> <h2 className="my-4 px-6 text-lg font-semibold text-white">{title}</h2> <div className="grid grid-cols-4 gap-4"> {users.map((user, index) => ( <div key={index} className="cursor-pointer rounded-xl bg-gray-800 p-4 text-center" onClick={() => onClick(user)} > <p className="text-sm text-gray-400">{user.user}</p> {showShiftStart && user.shift_start ? ( <p className="text-sm text-gray-400"> {dayjs(user.shift_start).format("DD-MM-YYYY | HH:mm")} </p> ) : null} </div> ))} </div> </div> ); } }; export default ShiftTable;
Comments