History Table is now functioning completely
This commit is contained in:
		
							
								
								
									
										15
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								package.json
									
									
									
									
									
								
							@@ -23,6 +23,7 @@
 | 
			
		||||
    "@radix-ui/react-popover": "^1.1.1",
 | 
			
		||||
    "@radix-ui/react-progress": "^1.1.0",
 | 
			
		||||
    "@radix-ui/react-radio-group": "^1.2.0",
 | 
			
		||||
    "@radix-ui/react-scroll-area": "^1.1.0",
 | 
			
		||||
    "@radix-ui/react-select": "^2.1.1",
 | 
			
		||||
    "@radix-ui/react-slot": "^1.1.0",
 | 
			
		||||
    "@radix-ui/react-switch": "^1.1.0",
 | 
			
		||||
@@ -37,13 +38,13 @@
 | 
			
		||||
    "drizzle-orm": "^0.30.10",
 | 
			
		||||
    "geist": "^1.3.1",
 | 
			
		||||
    "lucide-react": "^0.411.0",
 | 
			
		||||
    "mysql2": "^3.10.3",
 | 
			
		||||
    "mysql2": "^3.11.0",
 | 
			
		||||
    "next": "^14.2.5",
 | 
			
		||||
    "next-auth": "5.0.0-beta.19",
 | 
			
		||||
    "next-themes": "^0.3.0",
 | 
			
		||||
    "pm2": "^5.4.2",
 | 
			
		||||
    "react": "^18.3.1",
 | 
			
		||||
    "react-day-picker": "^9.0.3",
 | 
			
		||||
    "react-day-picker": "^9.0.5",
 | 
			
		||||
    "react-dom": "^18.3.1",
 | 
			
		||||
    "react-hook-form": "^7.52.1",
 | 
			
		||||
    "server-only": "^0.0.1",
 | 
			
		||||
@@ -56,19 +57,19 @@
 | 
			
		||||
  },
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "@types/eslint": "^8.56.11",
 | 
			
		||||
    "@types/node": "^20.14.12",
 | 
			
		||||
    "@types/node": "^20.14.13",
 | 
			
		||||
    "@types/react": "^18.3.3",
 | 
			
		||||
    "@types/react-dom": "^18.3.0",
 | 
			
		||||
    "@typescript-eslint/eslint-plugin": "^7.17.0",
 | 
			
		||||
    "@typescript-eslint/parser": "^7.17.0",
 | 
			
		||||
    "@typescript-eslint/eslint-plugin": "^7.18.0",
 | 
			
		||||
    "@typescript-eslint/parser": "^7.18.0",
 | 
			
		||||
    "drizzle-kit": "^0.21.4",
 | 
			
		||||
    "eslint": "^8.57.0",
 | 
			
		||||
    "eslint-config-next": "^14.2.5",
 | 
			
		||||
    "eslint-plugin-drizzle": "^0.2.3",
 | 
			
		||||
    "postcss": "^8.4.39",
 | 
			
		||||
    "postcss": "^8.4.40",
 | 
			
		||||
    "prettier": "^3.3.3",
 | 
			
		||||
    "prettier-plugin-tailwindcss": "^0.6.5",
 | 
			
		||||
    "tailwindcss": "^3.4.6",
 | 
			
		||||
    "tailwindcss": "^3.4.7",
 | 
			
		||||
    "typescript": "^5.5.4"
 | 
			
		||||
  },
 | 
			
		||||
  "ct3aMetadata": {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										383
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										383
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,12 +1,13 @@
 | 
			
		||||
"use server";
 | 
			
		||||
import { NextResponse } from 'next/server';
 | 
			
		||||
import { getHistory } from '~/server/functions';
 | 
			
		||||
import { get_history } from '~/server/functions';
 | 
			
		||||
import { auth } from '~/auth';
 | 
			
		||||
 | 
			
		||||
export const GET = async (request: Request) => {
 | 
			
		||||
  try {
 | 
			
		||||
    const url = new URL(request.url);
 | 
			
		||||
    const apiKey = url.searchParams.get('apikey');
 | 
			
		||||
    const userId = Number(url.searchParams.get('user_id')) || -1;
 | 
			
		||||
    const page = Number(url.searchParams.get('page')) || 1;
 | 
			
		||||
    const perPage = Number(url.searchParams.get('per_page')) || 50;
 | 
			
		||||
    if (apiKey !== process.env.API_KEY) {
 | 
			
		||||
@@ -17,7 +18,7 @@ export const GET = async (request: Request) => {
 | 
			
		||||
          { status: 401 }
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
    const historyData = await getHistory(page, perPage);
 | 
			
		||||
    const historyData = await get_history(userId, page, perPage);
 | 
			
		||||
    return NextResponse.json(historyData, { status: 200 });
 | 
			
		||||
  } catch (error) {
 | 
			
		||||
    console.error('Error fetching history data:', error);
 | 
			
		||||
 
 | 
			
		||||
@@ -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 }
 | 
			
		||||
@@ -68,32 +68,46 @@ type PaginatedHistory = {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const getHistory =
 | 
			
		||||
  async (page: number, perPage: number): Promise<PaginatedHistory> => {
 | 
			
		||||
export const get_history = async (user_id: number, page: number, perPage: number): Promise<PaginatedHistory> => {
 | 
			
		||||
  const offset = (page - 1) * perPage;
 | 
			
		||||
  const historyQuery = sql`
 | 
			
		||||
  let historyQuery = sql`
 | 
			
		||||
    SELECT u.name, h.status, h.updatedAt
 | 
			
		||||
    FROM history h
 | 
			
		||||
    JOIN users u ON h.user_id = u.id
 | 
			
		||||
    WHERE h.user_id = ${user_id}
 | 
			
		||||
    ORDER BY h.id DESC
 | 
			
		||||
    LIMIT ${perPage} OFFSET ${offset}
 | 
			
		||||
  `;
 | 
			
		||||
  const countQuery = sql`
 | 
			
		||||
  let countQuery = sql`
 | 
			
		||||
    SELECT COUNT(*) AS total_count
 | 
			
		||||
    FROM history
 | 
			
		||||
    WHERE user_id = ${user_id}
 | 
			
		||||
  `;
 | 
			
		||||
  const [historyResults, countResults] = await Promise.all([
 | 
			
		||||
  if (user_id === -1) {
 | 
			
		||||
    historyQuery = sql`
 | 
			
		||||
      SELECT u.name, h.status, h.updatedAt
 | 
			
		||||
      FROM history h
 | 
			
		||||
      JOIN users u ON h.user_id = u.id
 | 
			
		||||
      ORDER BY h.id DESC
 | 
			
		||||
      LIMIT ${perPage} OFFSET ${offset}
 | 
			
		||||
    `;
 | 
			
		||||
    countQuery = sql`
 | 
			
		||||
      SELECT COUNT(*) AS total_count
 | 
			
		||||
      FROM history
 | 
			
		||||
    `;
 | 
			
		||||
  } 
 | 
			
		||||
  const [historyresults, countresults] = await Promise.all([
 | 
			
		||||
    db.execute(historyQuery), 
 | 
			
		||||
    db.execute(countQuery),
 | 
			
		||||
  ]);
 | 
			
		||||
  // Safely cast results
 | 
			
		||||
  const historyRows = historyResults[0] as unknown as
 | 
			
		||||
  const historyrows = historyresults[0] as unknown as
 | 
			
		||||
    { name: string, status: string, updatedAt: Date }[];
 | 
			
		||||
  const countRow = countResults[0] as unknown as { total_count: number }[];
 | 
			
		||||
  const totalCount = countRow[0]?.total_count ?? 0;
 | 
			
		||||
  const countrow = countresults[0] as unknown as { total_count: number }[];
 | 
			
		||||
  const totalCount = countrow[0]?.total_count ?? 0;
 | 
			
		||||
  const totalPages = Math.ceil(totalCount / perPage);
 | 
			
		||||
  // Format and map results
 | 
			
		||||
  const formattedResults: HistoryEntry[] = historyRows.map(row => ({
 | 
			
		||||
  const formattedResults: HistoryEntry[] = historyrows.map(row => ({
 | 
			
		||||
    name: row.name,
 | 
			
		||||
    status: row.status,
 | 
			
		||||
    updatedAt: new Date(row.updatedAt),
 | 
			
		||||
@@ -109,3 +123,44 @@ export const getHistory =
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//export const getHistory =
 | 
			
		||||
  //async (page: number, perPage: number): Promise<PaginatedHistory> => {
 | 
			
		||||
  //const offset = (page - 1) * perPage;
 | 
			
		||||
  //const historyQuery = sql`
 | 
			
		||||
    //SELECT u.name, h.status, h.updatedAt
 | 
			
		||||
    //FROM history h
 | 
			
		||||
    //JOIN users u ON h.user_id = u.id
 | 
			
		||||
    //ORDER BY h.id DESC
 | 
			
		||||
    //LIMIT ${perPage} OFFSET ${offset}
 | 
			
		||||
  //`;
 | 
			
		||||
  //const countQuery = sql`
 | 
			
		||||
    //SELECT COUNT(*) AS total_count
 | 
			
		||||
    //FROM history
 | 
			
		||||
  //`;
 | 
			
		||||
  //const [historyResults, countResults] = await Promise.all([
 | 
			
		||||
    //db.execute(historyQuery), 
 | 
			
		||||
    //db.execute(countQuery),
 | 
			
		||||
  //]);
 | 
			
		||||
  //// Safely cast results
 | 
			
		||||
  //const historyRows = historyResults[0] as unknown as
 | 
			
		||||
    //{ name: string, status: string, updatedAt: Date }[];
 | 
			
		||||
  //const countRow = countResults[0] as unknown as { total_count: number }[];
 | 
			
		||||
  //const totalCount = countRow[0]?.total_count ?? 0;
 | 
			
		||||
  //const totalPages = Math.ceil(totalCount / perPage);
 | 
			
		||||
  //// Format and map results
 | 
			
		||||
  //const formattedResults: HistoryEntry[] = historyRows.map(row => ({
 | 
			
		||||
    //name: row.name,
 | 
			
		||||
    //status: row.status,
 | 
			
		||||
    //updatedAt: new Date(row.updatedAt),
 | 
			
		||||
  //}));
 | 
			
		||||
  //return {
 | 
			
		||||
    //data: formattedResults,
 | 
			
		||||
    //meta: {
 | 
			
		||||
      //current_page: page,
 | 
			
		||||
      //per_page: perPage,
 | 
			
		||||
      //total_pages: totalPages,
 | 
			
		||||
      //total_count: totalCount,
 | 
			
		||||
    //}
 | 
			
		||||
  //};
 | 
			
		||||
//};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user