shift table the best state
Mon Apr 29 2024 11:16:34 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";
import { useGetFilename } from "@/hooks";
import { getFilename } from "@/functions";
import Link from "next/link";
type User = {
shift_start: string | null;
break_start: string | null;
user: any;
image: string;
fullName: string;
group: string | null;
users_view?: {
email?: string;
raw_user_meta_data?: {
avatar_url?: string;
full_name?: string;
};
};
email: string;
};
const ShiftTable = () => {
const [usersOnShift, setUsersOnShift] = useState<User[]>([]);
const [usersOffShift, setUsersOffShift] = useState<User[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState("");
const { data: fileNameId } = useGetFilename(
"88ccb685-8532-454b-a1c4-f69425af7e93"
);
console.log(fileNameId);
const supabaseClient = useSupabaseClient();
const router = useRouter();
const excludedUuid = "2b78abeb-133d-4248-8469-21620903cbb3";
useEffect(() => {
const fetchUsers = async () => {
setLoading(true);
setError("");
try {
const { data: usersData, error: fetchError } = await supabaseClient
.from("UserLastWorkedOn")
.select(
"shift_start, break_start, user, users_view ( raw_user_meta_data), email, group"
)
.not("user", "eq", excludedUuid);
if (fetchError) {
setError(fetchError.message || "Failed to fetch user data.");
return;
}
console.log(usersData);
const mappedUsers = await Promise.all(
usersData.map(async (user) => {
const meta_data = user.users_view as any;
const metaData = meta_data?.raw_user_meta_data;
console.log(user.users_view);
const image = metaData.avatar_url;
const fullName = metaData.full_name || "No Name Provided";
const filename = await getFilename(supabaseClient, user.email);
return {
shift_start: user.shift_start
? dayjs(user.shift_start).format("DD-MM-YYYY | HH:mm")
: null,
break_start: user.break_start
? dayjs(user.break_start).format("DD-MM-YYYY | HH:mm")
: null,
user: user.user,
image: image,
fullName: fullName,
group: user.group || "No Group",
email: filename ?? "",
};
})
);
setUsersOnShift(
mappedUsers.filter((user) => user.shift_start !== null)
);
setUsersOffShift(
mappedUsers.filter((user) => user.shift_start === null)
);
} catch (err) {
setError("Failed to fetch user data: " + err.message);
} finally {
setLoading(false);
}
};
fetchUsers();
}, [supabaseClient]);
return (
<MinimalPage
pageTitle="Shift Table | Email Interface"
pageDescription="Spot Ship Email Interface | Shift Table"
>
<div className="w-full">
<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:{" "}
{usersOffShift.length}.
</div>
{loading ? (
<Spinner />
) : error ? (
<p className="text-red-500">{error}</p>
) : (
<>
{renderUsersGrid(
"Data Analysts",
usersOnShift.filter((user) => user.group === "Data Analyst"),
true,
false
)}
{renderUsersGrid(
"Senior Data Analysts",
usersOnShift.filter(
(user) => user.group === "Senior Data Analyst"
),
true,
false
)}
{renderUsersGrid(
"Data Team Managers",
usersOnShift.filter((user) => user.group === "Data Team Manager"),
true,
false
)}
{renderUsersGrid(
"Europe Team",
usersOnShift.filter((user) => user.group === "Europe Team"),
true,
false
)}
{renderUsersGrid("Offline Users", usersOffShift, false, true)}
</>
)}
</div>
</MinimalPage>
);
function renderUsersGrid(
title: string,
users: User[],
showShiftStart: boolean,
dim: boolean
) {
return (
<div
className={`overflow-hidden overflow-x-auto rounded-lg shadow ${
dim ? "opacity-50" : ""
}`}
>
<h2 className="text-center text-lg font-semibold">{title}</h2>
<div className="grid grid-cols-4 gap-4 p-4">
{users.map((user, index) => (
<div
key={index}
className={`relative flex flex-col items-center justify-center rounded-lg bg-gray-800 p-4 ${
dim ? "bg-opacity-50" : ""
}`}
>
<div className="relative h-12 w-12">
<img
src={user.image || "avatar_url.jpg"} // Fallback to default avatar if none
alt={user.fullName}
className="h-full w-full rounded-full object-cover"
/>
{/* Status Indicators placed on the image */}
{user.shift_start && !user.break_start && (
<span className="absolute bottom-0 right-0 block h-5 w-5 rounded-full border-2 border-black bg-green-400" />
)}
{user.break_start && (
<span className="absolute bottom-0 right-0 block h-5 w-5 rounded-full border-2 border-black bg-yellow-400" />
)}
{!user.shift_start && (
<span className="absolute bottom-0 right-0 block h-5 w-5 rounded-full border-2 border-black bg-gray-400" />
)}
</div>
<Link
href={`/secure/review/email?filename=${user.email}`}
passHref
rel="noopener noreferrer"
target="_blank"
>
<button className="mt-2 rounded bg-blue-500 px-2 py-1 text-xs font-bold text-white hover:bg-blue-700">
{user.email !== "" ? "Working on Email" : "No Email Assigned"}
</button>
</Link>
<p className="mt-2 text-sm text-white">{user.fullName}</p>
{showShiftStart && user.shift_start && (
<p className="text-xs text-gray-400">{user.shift_start}</p>
)}
</div>
))}
</div>
</div>
);
}
};
export default ShiftTable;



Comments