History Table is now functioning completely
This commit is contained in:
@ -1,8 +1,7 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import Image from "next/image";
|
||||
import { ScrollArea } from "~/components/ui/shadcn/scroll-area";
|
||||
import {
|
||||
Drawer,
|
||||
DrawerTrigger,
|
||||
DrawerClose,
|
||||
DrawerContent,
|
||||
DrawerFooter,
|
||||
@ -30,7 +29,7 @@ type HistoryEntry = {
|
||||
name: string;
|
||||
status: string;
|
||||
updatedAt: Date;
|
||||
}
|
||||
};
|
||||
type PaginatedHistory = {
|
||||
data: HistoryEntry[];
|
||||
meta: {
|
||||
@ -39,112 +38,116 @@ type PaginatedHistory = {
|
||||
total_pages: number;
|
||||
total_count: number;
|
||||
}
|
||||
}
|
||||
};
|
||||
type History_Drawer_Props = {
|
||||
user_id: number;
|
||||
};
|
||||
|
||||
export default function History_Drawer() {
|
||||
const History_Drawer: React.FC<History_Drawer_Props> = ({ user_id }) => {
|
||||
const [history, setHistory] = useState<HistoryEntry[]>([]);
|
||||
const [page, setPage] = useState<number>(1);
|
||||
const [totalPages, setTotalPages] = useState<number>(1);
|
||||
const perPage = 5;
|
||||
const perPage = 50;
|
||||
|
||||
const fetchHistory = async (currentPage: number, user_id: number) => {
|
||||
try {
|
||||
const response = await fetch(`/api/get_paginated_history?user_id=${user_id}&page=${currentPage}&per_page=${perPage}`);
|
||||
if (!response.ok) throw new Error('Failed to fetch history');
|
||||
const data: PaginatedHistory = await response.json() as PaginatedHistory;
|
||||
setHistory(data.data);
|
||||
setTotalPages(data.meta.total_pages);
|
||||
} catch (error) {
|
||||
console.error('Error fetching history:', error);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const fetchHistory = async (currentPage: number) => {
|
||||
try {
|
||||
const response = await fetch(`/api/get_paginated_history?page=${currentPage}&per_page=${perPage}`);
|
||||
if (!response.ok)
|
||||
throw new Error('Failed to fetch history');
|
||||
const data: PaginatedHistory = await response.json() as PaginatedHistory;
|
||||
setHistory(data.data);
|
||||
setTotalPages(data.meta.total_pages);
|
||||
} catch (error) {
|
||||
console.error('Error fetching history:', error);
|
||||
}
|
||||
};
|
||||
fetchHistory(page)
|
||||
.catch((error) => {
|
||||
fetchHistory(page, user_id).catch((error) => {
|
||||
console.error('Error fetching history:', error);
|
||||
});
|
||||
}, [page]);
|
||||
}, [page, user_id]);
|
||||
|
||||
const handlePageChange = (newPage: number) => {
|
||||
setPage(newPage);
|
||||
};
|
||||
|
||||
return (
|
||||
<Drawer>
|
||||
<DrawerTrigger>
|
||||
Status
|
||||
</DrawerTrigger>
|
||||
<DrawerContent>
|
||||
<DrawerHeader>
|
||||
<DrawerTitle>
|
||||
<div className="flex flex-row items-center text-center
|
||||
sm:justify-center sm:ml-0 py-4">
|
||||
<Image src="/images/tech_tracker_logo.png"
|
||||
alt="Tech Tracker Logo" width={60} height={60}
|
||||
className="max-w-[40px] md:max-w-[120px]"
|
||||
/>
|
||||
<h1 className="title-text text-sm md:text-2xl lg:text-6xl
|
||||
bg-gradient-to-r from-[#bec8e6] via-[#F0EEE4] to-[#FFF8E7]
|
||||
font-bold pl-2 md:pl-4 text-transparent bg-clip-text">
|
||||
History
|
||||
</h1>
|
||||
</div>
|
||||
</DrawerTitle>
|
||||
</DrawerHeader>
|
||||
<Table className="w-5/6 lg:w-1/2 m-auto ">
|
||||
<DrawerContent>
|
||||
<DrawerHeader>
|
||||
<DrawerTitle>
|
||||
<div className="flex flex-row items-center text-center sm:justify-center sm:ml-0 py-4">
|
||||
<Image src="/images/tech_tracker_logo.png" alt="Tech Tracker Logo" width={60} height={60} className="max-w-[40px] md:max-w-[120px]" />
|
||||
<h1 className="title-text text-sm md:text-2xl lg:text-6xl bg-gradient-to-r from-[#bec8e6] via-[#F0EEE4] to-[#FFF8E7] font-bold pl-2 md:pl-4 text-transparent bg-clip-text">
|
||||
History
|
||||
</h1>
|
||||
</div>
|
||||
</DrawerTitle>
|
||||
</DrawerHeader>
|
||||
<ScrollArea className="w-full sm:w-5/6 lg:w-5/12 m-auto h-80">
|
||||
<Table className="w-full m-auto">
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>Name</TableHead>
|
||||
<TableHead>Status</TableHead>
|
||||
<TableHead>Updated At</TableHead>
|
||||
<TableHead className="font-semibold lg:max-w-[100px]">Name</TableHead>
|
||||
<TableHead className="font-semibold lg:max-w-[100px]">Status</TableHead>
|
||||
<TableHead className="font-semibold lg:max-w-[100px] justify-end items-end text-right">Updated At</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{history.map((entry, index) => (
|
||||
<TableRow key={index}>
|
||||
<TableCell className="font-medium">{entry.name}</TableCell>
|
||||
<TableCell>{entry.status}</TableCell>
|
||||
<TableCell>{new Date(entry.updatedAt).toLocaleString()}</TableCell>
|
||||
<TableCell className="font-medium lg:max-w-[100px]">{entry.name}</TableCell>
|
||||
<TableCell className="font-medium lg:max-w-[100px]">{entry.status}</TableCell>
|
||||
<TableCell className="font-medium lg:max-w-[100px] justify-end items-end text-right">{new Date(entry.updatedAt).toLocaleString()}</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
<DrawerFooter>
|
||||
<Pagination>
|
||||
<PaginationContent>
|
||||
{page > 1 && (
|
||||
<PaginationItem>
|
||||
<PaginationPrevious
|
||||
href="#"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
handlePageChange(page - 1);
|
||||
}}
|
||||
/>
|
||||
</PaginationItem>
|
||||
)}
|
||||
<h3 className="text-center font-semibold">Page {page}</h3>
|
||||
{page < totalPages && (
|
||||
<PaginationItem>
|
||||
<PaginationNext
|
||||
href="#"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
handlePageChange(page + 1);
|
||||
}}
|
||||
/>
|
||||
</PaginationItem>
|
||||
)}
|
||||
</PaginationContent>
|
||||
</Pagination>
|
||||
<DrawerClose>
|
||||
</DrawerClose>
|
||||
</DrawerFooter>
|
||||
</DrawerContent>
|
||||
</Drawer>
|
||||
</ScrollArea>
|
||||
<DrawerFooter>
|
||||
<Pagination>
|
||||
<PaginationContent>
|
||||
{page > 1 && (
|
||||
<PaginationItem>
|
||||
<PaginationPrevious
|
||||
href="#"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
handlePageChange(page - 1);
|
||||
}}
|
||||
/>
|
||||
</PaginationItem>
|
||||
)}
|
||||
<h3 className="text-center flex flex-row">
|
||||
Page
|
||||
<h3 className="font-bold mx-1">
|
||||
{page}
|
||||
</h3>
|
||||
of
|
||||
<h3 className="font-semibold ml-1">
|
||||
{totalPages}
|
||||
</h3>
|
||||
</h3>
|
||||
{page < totalPages && (
|
||||
<PaginationItem>
|
||||
<PaginationNext
|
||||
href="#"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
handlePageChange(page + 1);
|
||||
}}
|
||||
/>
|
||||
</PaginationItem>
|
||||
)}
|
||||
</PaginationContent>
|
||||
</Pagination>
|
||||
<DrawerClose>
|
||||
</DrawerClose>
|
||||
</DrawerFooter>
|
||||
</DrawerContent>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default History_Drawer;
|
||||
// If you want to show all page numbers:
|
||||
//{Array.from({ length: totalPages }).map((_, idx) => (
|
||||
//<PaginationItem key={idx}>
|
||||
@ -158,4 +161,3 @@ export default function History_Drawer() {
|
||||
//</PaginationLink>
|
||||
//</PaginationItem>
|
||||
//))}
|
||||
|
||||
|
@ -3,6 +3,8 @@ import { useState, useEffect, useCallback } from 'react';
|
||||
import { useSession } from "next-auth/react";
|
||||
import Loading from "~/components/ui/Loading";
|
||||
import { useTVMode } from "~/components/context/TVModeContext";
|
||||
import { Drawer, DrawerTrigger } from "~/components/ui/shadcn/drawer";
|
||||
|
||||
import History_Drawer from "~/components/ui/History_Drawer";
|
||||
|
||||
type Employee = {
|
||||
@ -20,6 +22,7 @@ export default function Tech_Table({ employees }: { employees: Employee[] }) {
|
||||
const [selectAll, setSelectAll] = useState(false);
|
||||
const [employeeStatus, setStatus] = useState('');
|
||||
const [employeeData, setEmployeeData] = useState(employees);
|
||||
const [selectedUserId, setSelectedUserId] = useState(-1);
|
||||
|
||||
const fetch_employees = useCallback(async (): Promise<Employee[]> => {
|
||||
const res = await fetch('/api/get_technicians', {
|
||||
@ -95,6 +98,10 @@ export default function Tech_Table({ employees }: { employees: Employee[] }) {
|
||||
}
|
||||
};
|
||||
|
||||
const handleStatusClick = (id: number) => {
|
||||
setSelectedUserId(id);
|
||||
};
|
||||
|
||||
const formatTime = (timestamp: Date) => {
|
||||
const date = new Date(timestamp);
|
||||
const time = date.toLocaleTimeString('en-US', {
|
||||
@ -167,7 +174,12 @@ export default function Tech_Table({ employees }: { employees: Employee[] }) {
|
||||
)}
|
||||
<th className="border border-[#3e4446] py-3">Name</th>
|
||||
<th className="border border-[#3e4446] py-3">
|
||||
<History_Drawer />
|
||||
<Drawer>
|
||||
<DrawerTrigger>
|
||||
Status
|
||||
</DrawerTrigger>
|
||||
<History_Drawer user_id={-1}/>
|
||||
</Drawer>
|
||||
</th>
|
||||
<th className="border border-[#3e4446] py-3">Updated At</th>
|
||||
</tr>
|
||||
@ -193,9 +205,16 @@ export default function Tech_Table({ employees }: { employees: Employee[] }) {
|
||||
{employee.name}
|
||||
</td>
|
||||
<td className="s-column max-w-[700px] px-1 md:py-3 border border-[#3e4446]">
|
||||
<button>
|
||||
{employee.status}
|
||||
</button>
|
||||
<Drawer>
|
||||
<DrawerTrigger>
|
||||
<button onClick={() => handleStatusClick(employee.id)}>
|
||||
{employee.status}
|
||||
</button>
|
||||
</DrawerTrigger>
|
||||
{selectedUserId !== -1 && (
|
||||
<History_Drawer key={selectedUserId} user_id={selectedUserId} />
|
||||
)}
|
||||
</Drawer>
|
||||
</td>
|
||||
<td className="ua-column px-1 md:py-3 border border-[#3e4446]">
|
||||
{formatTime(employee.updatedAt)}
|
||||
|
48
src/components/ui/shadcn/scroll-area.tsx
Normal file
48
src/components/ui/shadcn/scroll-area.tsx
Normal file
@ -0,0 +1,48 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area"
|
||||
|
||||
import { cn } from "~/lib/utils"
|
||||
|
||||
const ScrollArea = React.forwardRef<
|
||||
React.ElementRef<typeof ScrollAreaPrimitive.Root>,
|
||||
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root>
|
||||
>(({ className, children, ...props }, ref) => (
|
||||
<ScrollAreaPrimitive.Root
|
||||
ref={ref}
|
||||
className={cn("relative overflow-hidden", className)}
|
||||
{...props}
|
||||
>
|
||||
<ScrollAreaPrimitive.Viewport className="h-full w-full rounded-[inherit]">
|
||||
{children}
|
||||
</ScrollAreaPrimitive.Viewport>
|
||||
<ScrollBar />
|
||||
<ScrollAreaPrimitive.Corner />
|
||||
</ScrollAreaPrimitive.Root>
|
||||
))
|
||||
ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName
|
||||
|
||||
const ScrollBar = React.forwardRef<
|
||||
React.ElementRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>,
|
||||
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>
|
||||
>(({ className, orientation = "vertical", ...props }, ref) => (
|
||||
<ScrollAreaPrimitive.ScrollAreaScrollbar
|
||||
ref={ref}
|
||||
orientation={orientation}
|
||||
className={cn(
|
||||
"flex touch-none select-none transition-colors",
|
||||
orientation === "vertical" &&
|
||||
"h-full w-2.5 border-l border-l-transparent p-[1px]",
|
||||
orientation === "horizontal" &&
|
||||
"h-2.5 flex-col border-t border-t-transparent p-[1px]",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<ScrollAreaPrimitive.ScrollAreaThumb className="relative flex-1 rounded-full bg-border" />
|
||||
</ScrollAreaPrimitive.ScrollAreaScrollbar>
|
||||
))
|
||||
ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName
|
||||
|
||||
export { ScrollArea, ScrollBar }
|
Reference in New Issue
Block a user