table looks ok

PHOTO EMBED

Wed Apr 10 2024 23:03:10 GMT+0000 (Coordinated Universal Time)

Saved by @rafal_rydz

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;
content_copyCOPY