History Table is now functioning completely
This commit is contained in:
parent
b14383f8fd
commit
44497ebe7b
15
package.json
15
package.json
@ -23,6 +23,7 @@
|
|||||||
"@radix-ui/react-popover": "^1.1.1",
|
"@radix-ui/react-popover": "^1.1.1",
|
||||||
"@radix-ui/react-progress": "^1.1.0",
|
"@radix-ui/react-progress": "^1.1.0",
|
||||||
"@radix-ui/react-radio-group": "^1.2.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-select": "^2.1.1",
|
||||||
"@radix-ui/react-slot": "^1.1.0",
|
"@radix-ui/react-slot": "^1.1.0",
|
||||||
"@radix-ui/react-switch": "^1.1.0",
|
"@radix-ui/react-switch": "^1.1.0",
|
||||||
@ -37,13 +38,13 @@
|
|||||||
"drizzle-orm": "^0.30.10",
|
"drizzle-orm": "^0.30.10",
|
||||||
"geist": "^1.3.1",
|
"geist": "^1.3.1",
|
||||||
"lucide-react": "^0.411.0",
|
"lucide-react": "^0.411.0",
|
||||||
"mysql2": "^3.10.3",
|
"mysql2": "^3.11.0",
|
||||||
"next": "^14.2.5",
|
"next": "^14.2.5",
|
||||||
"next-auth": "5.0.0-beta.19",
|
"next-auth": "5.0.0-beta.19",
|
||||||
"next-themes": "^0.3.0",
|
"next-themes": "^0.3.0",
|
||||||
"pm2": "^5.4.2",
|
"pm2": "^5.4.2",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-day-picker": "^9.0.3",
|
"react-day-picker": "^9.0.5",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
"react-hook-form": "^7.52.1",
|
"react-hook-form": "^7.52.1",
|
||||||
"server-only": "^0.0.1",
|
"server-only": "^0.0.1",
|
||||||
@ -56,19 +57,19 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/eslint": "^8.56.11",
|
"@types/eslint": "^8.56.11",
|
||||||
"@types/node": "^20.14.12",
|
"@types/node": "^20.14.13",
|
||||||
"@types/react": "^18.3.3",
|
"@types/react": "^18.3.3",
|
||||||
"@types/react-dom": "^18.3.0",
|
"@types/react-dom": "^18.3.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^7.17.0",
|
"@typescript-eslint/eslint-plugin": "^7.18.0",
|
||||||
"@typescript-eslint/parser": "^7.17.0",
|
"@typescript-eslint/parser": "^7.18.0",
|
||||||
"drizzle-kit": "^0.21.4",
|
"drizzle-kit": "^0.21.4",
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^8.57.0",
|
||||||
"eslint-config-next": "^14.2.5",
|
"eslint-config-next": "^14.2.5",
|
||||||
"eslint-plugin-drizzle": "^0.2.3",
|
"eslint-plugin-drizzle": "^0.2.3",
|
||||||
"postcss": "^8.4.39",
|
"postcss": "^8.4.40",
|
||||||
"prettier": "^3.3.3",
|
"prettier": "^3.3.3",
|
||||||
"prettier-plugin-tailwindcss": "^0.6.5",
|
"prettier-plugin-tailwindcss": "^0.6.5",
|
||||||
"tailwindcss": "^3.4.6",
|
"tailwindcss": "^3.4.7",
|
||||||
"typescript": "^5.5.4"
|
"typescript": "^5.5.4"
|
||||||
},
|
},
|
||||||
"ct3aMetadata": {
|
"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";
|
"use server";
|
||||||
import { NextResponse } from 'next/server';
|
import { NextResponse } from 'next/server';
|
||||||
import { getHistory } from '~/server/functions';
|
import { get_history } from '~/server/functions';
|
||||||
import { auth } from '~/auth';
|
import { auth } from '~/auth';
|
||||||
|
|
||||||
export const GET = async (request: Request) => {
|
export const GET = async (request: Request) => {
|
||||||
try {
|
try {
|
||||||
const url = new URL(request.url);
|
const url = new URL(request.url);
|
||||||
const apiKey = url.searchParams.get('apikey');
|
const apiKey = url.searchParams.get('apikey');
|
||||||
|
const userId = Number(url.searchParams.get('user_id')) || -1;
|
||||||
const page = Number(url.searchParams.get('page')) || 1;
|
const page = Number(url.searchParams.get('page')) || 1;
|
||||||
const perPage = Number(url.searchParams.get('per_page')) || 50;
|
const perPage = Number(url.searchParams.get('per_page')) || 50;
|
||||||
if (apiKey !== process.env.API_KEY) {
|
if (apiKey !== process.env.API_KEY) {
|
||||||
@ -17,7 +18,7 @@ export const GET = async (request: Request) => {
|
|||||||
{ status: 401 }
|
{ status: 401 }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const historyData = await getHistory(page, perPage);
|
const historyData = await get_history(userId, page, perPage);
|
||||||
return NextResponse.json(historyData, { status: 200 });
|
return NextResponse.json(historyData, { status: 200 });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching history data:', error);
|
console.error('Error fetching history data:', error);
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
|
import { ScrollArea } from "~/components/ui/shadcn/scroll-area";
|
||||||
import {
|
import {
|
||||||
Drawer,
|
|
||||||
DrawerTrigger,
|
|
||||||
DrawerClose,
|
DrawerClose,
|
||||||
DrawerContent,
|
DrawerContent,
|
||||||
DrawerFooter,
|
DrawerFooter,
|
||||||
@ -30,7 +29,7 @@ type HistoryEntry = {
|
|||||||
name: string;
|
name: string;
|
||||||
status: string;
|
status: string;
|
||||||
updatedAt: Date;
|
updatedAt: Date;
|
||||||
}
|
};
|
||||||
type PaginatedHistory = {
|
type PaginatedHistory = {
|
||||||
data: HistoryEntry[];
|
data: HistoryEntry[];
|
||||||
meta: {
|
meta: {
|
||||||
@ -39,112 +38,116 @@ type PaginatedHistory = {
|
|||||||
total_pages: number;
|
total_pages: number;
|
||||||
total_count: 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 [history, setHistory] = useState<HistoryEntry[]>([]);
|
||||||
const [page, setPage] = useState<number>(1);
|
const [page, setPage] = useState<number>(1);
|
||||||
const [totalPages, setTotalPages] = 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(() => {
|
useEffect(() => {
|
||||||
const fetchHistory = async (currentPage: number) => {
|
fetchHistory(page, user_id).catch((error) => {
|
||||||
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) => {
|
|
||||||
console.error('Error fetching history:', error);
|
console.error('Error fetching history:', error);
|
||||||
});
|
});
|
||||||
}, [page]);
|
}, [page, user_id]);
|
||||||
|
|
||||||
const handlePageChange = (newPage: number) => {
|
const handlePageChange = (newPage: number) => {
|
||||||
setPage(newPage);
|
setPage(newPage);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Drawer>
|
<DrawerContent>
|
||||||
<DrawerTrigger>
|
<DrawerHeader>
|
||||||
Status
|
<DrawerTitle>
|
||||||
</DrawerTrigger>
|
<div className="flex flex-row items-center text-center sm:justify-center sm:ml-0 py-4">
|
||||||
<DrawerContent>
|
<Image src="/images/tech_tracker_logo.png" alt="Tech Tracker Logo" width={60} height={60} className="max-w-[40px] md:max-w-[120px]" />
|
||||||
<DrawerHeader>
|
<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">
|
||||||
<DrawerTitle>
|
History
|
||||||
<div className="flex flex-row items-center text-center
|
</h1>
|
||||||
sm:justify-center sm:ml-0 py-4">
|
</div>
|
||||||
<Image src="/images/tech_tracker_logo.png"
|
</DrawerTitle>
|
||||||
alt="Tech Tracker Logo" width={60} height={60}
|
</DrawerHeader>
|
||||||
className="max-w-[40px] md:max-w-[120px]"
|
<ScrollArea className="w-full sm:w-5/6 lg:w-5/12 m-auto h-80">
|
||||||
/>
|
<Table className="w-full m-auto">
|
||||||
<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 ">
|
|
||||||
<TableHeader>
|
<TableHeader>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableHead>Name</TableHead>
|
<TableHead className="font-semibold lg:max-w-[100px]">Name</TableHead>
|
||||||
<TableHead>Status</TableHead>
|
<TableHead className="font-semibold lg:max-w-[100px]">Status</TableHead>
|
||||||
<TableHead>Updated At</TableHead>
|
<TableHead className="font-semibold lg:max-w-[100px] justify-end items-end text-right">Updated At</TableHead>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{history.map((entry, index) => (
|
{history.map((entry, index) => (
|
||||||
<TableRow key={index}>
|
<TableRow key={index}>
|
||||||
<TableCell className="font-medium">{entry.name}</TableCell>
|
<TableCell className="font-medium lg:max-w-[100px]">{entry.name}</TableCell>
|
||||||
<TableCell>{entry.status}</TableCell>
|
<TableCell className="font-medium lg:max-w-[100px]">{entry.status}</TableCell>
|
||||||
<TableCell>{new Date(entry.updatedAt).toLocaleString()}</TableCell>
|
<TableCell className="font-medium lg:max-w-[100px] justify-end items-end text-right">{new Date(entry.updatedAt).toLocaleString()}</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
))}
|
))}
|
||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
<DrawerFooter>
|
</ScrollArea>
|
||||||
<Pagination>
|
<DrawerFooter>
|
||||||
<PaginationContent>
|
<Pagination>
|
||||||
{page > 1 && (
|
<PaginationContent>
|
||||||
<PaginationItem>
|
{page > 1 && (
|
||||||
<PaginationPrevious
|
<PaginationItem>
|
||||||
href="#"
|
<PaginationPrevious
|
||||||
onClick={(e) => {
|
href="#"
|
||||||
e.preventDefault();
|
onClick={(e) => {
|
||||||
handlePageChange(page - 1);
|
e.preventDefault();
|
||||||
}}
|
handlePageChange(page - 1);
|
||||||
/>
|
}}
|
||||||
</PaginationItem>
|
/>
|
||||||
)}
|
</PaginationItem>
|
||||||
<h3 className="text-center font-semibold">Page {page}</h3>
|
)}
|
||||||
{page < totalPages && (
|
<h3 className="text-center flex flex-row">
|
||||||
<PaginationItem>
|
Page
|
||||||
<PaginationNext
|
<h3 className="font-bold mx-1">
|
||||||
href="#"
|
{page}
|
||||||
onClick={(e) => {
|
</h3>
|
||||||
e.preventDefault();
|
of
|
||||||
handlePageChange(page + 1);
|
<h3 className="font-semibold ml-1">
|
||||||
}}
|
{totalPages}
|
||||||
/>
|
</h3>
|
||||||
</PaginationItem>
|
</h3>
|
||||||
)}
|
{page < totalPages && (
|
||||||
</PaginationContent>
|
<PaginationItem>
|
||||||
</Pagination>
|
<PaginationNext
|
||||||
<DrawerClose>
|
href="#"
|
||||||
</DrawerClose>
|
onClick={(e) => {
|
||||||
</DrawerFooter>
|
e.preventDefault();
|
||||||
</DrawerContent>
|
handlePageChange(page + 1);
|
||||||
</Drawer>
|
}}
|
||||||
|
/>
|
||||||
|
</PaginationItem>
|
||||||
|
)}
|
||||||
|
</PaginationContent>
|
||||||
|
</Pagination>
|
||||||
|
<DrawerClose>
|
||||||
|
</DrawerClose>
|
||||||
|
</DrawerFooter>
|
||||||
|
</DrawerContent>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
export default History_Drawer;
|
||||||
// If you want to show all page numbers:
|
// If you want to show all page numbers:
|
||||||
//{Array.from({ length: totalPages }).map((_, idx) => (
|
//{Array.from({ length: totalPages }).map((_, idx) => (
|
||||||
//<PaginationItem key={idx}>
|
//<PaginationItem key={idx}>
|
||||||
@ -158,4 +161,3 @@ export default function History_Drawer() {
|
|||||||
//</PaginationLink>
|
//</PaginationLink>
|
||||||
//</PaginationItem>
|
//</PaginationItem>
|
||||||
//))}
|
//))}
|
||||||
|
|
||||||
|
@ -3,6 +3,8 @@ import { useState, useEffect, useCallback } from 'react';
|
|||||||
import { useSession } from "next-auth/react";
|
import { useSession } from "next-auth/react";
|
||||||
import Loading from "~/components/ui/Loading";
|
import Loading from "~/components/ui/Loading";
|
||||||
import { useTVMode } from "~/components/context/TVModeContext";
|
import { useTVMode } from "~/components/context/TVModeContext";
|
||||||
|
import { Drawer, DrawerTrigger } from "~/components/ui/shadcn/drawer";
|
||||||
|
|
||||||
import History_Drawer from "~/components/ui/History_Drawer";
|
import History_Drawer from "~/components/ui/History_Drawer";
|
||||||
|
|
||||||
type Employee = {
|
type Employee = {
|
||||||
@ -20,6 +22,7 @@ export default function Tech_Table({ employees }: { employees: Employee[] }) {
|
|||||||
const [selectAll, setSelectAll] = useState(false);
|
const [selectAll, setSelectAll] = useState(false);
|
||||||
const [employeeStatus, setStatus] = useState('');
|
const [employeeStatus, setStatus] = useState('');
|
||||||
const [employeeData, setEmployeeData] = useState(employees);
|
const [employeeData, setEmployeeData] = useState(employees);
|
||||||
|
const [selectedUserId, setSelectedUserId] = useState(-1);
|
||||||
|
|
||||||
const fetch_employees = useCallback(async (): Promise<Employee[]> => {
|
const fetch_employees = useCallback(async (): Promise<Employee[]> => {
|
||||||
const res = await fetch('/api/get_technicians', {
|
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 formatTime = (timestamp: Date) => {
|
||||||
const date = new Date(timestamp);
|
const date = new Date(timestamp);
|
||||||
const time = date.toLocaleTimeString('en-US', {
|
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">Name</th>
|
||||||
<th className="border border-[#3e4446] py-3">
|
<th className="border border-[#3e4446] py-3">
|
||||||
<History_Drawer />
|
<Drawer>
|
||||||
|
<DrawerTrigger>
|
||||||
|
Status
|
||||||
|
</DrawerTrigger>
|
||||||
|
<History_Drawer user_id={-1}/>
|
||||||
|
</Drawer>
|
||||||
</th>
|
</th>
|
||||||
<th className="border border-[#3e4446] py-3">Updated At</th>
|
<th className="border border-[#3e4446] py-3">Updated At</th>
|
||||||
</tr>
|
</tr>
|
||||||
@ -193,9 +205,16 @@ export default function Tech_Table({ employees }: { employees: Employee[] }) {
|
|||||||
{employee.name}
|
{employee.name}
|
||||||
</td>
|
</td>
|
||||||
<td className="s-column max-w-[700px] px-1 md:py-3 border border-[#3e4446]">
|
<td className="s-column max-w-[700px] px-1 md:py-3 border border-[#3e4446]">
|
||||||
<button>
|
<Drawer>
|
||||||
{employee.status}
|
<DrawerTrigger>
|
||||||
</button>
|
<button onClick={() => handleStatusClick(employee.id)}>
|
||||||
|
{employee.status}
|
||||||
|
</button>
|
||||||
|
</DrawerTrigger>
|
||||||
|
{selectedUserId !== -1 && (
|
||||||
|
<History_Drawer key={selectedUserId} user_id={selectedUserId} />
|
||||||
|
)}
|
||||||
|
</Drawer>
|
||||||
</td>
|
</td>
|
||||||
<td className="ua-column px-1 md:py-3 border border-[#3e4446]">
|
<td className="ua-column px-1 md:py-3 border border-[#3e4446]">
|
||||||
{formatTime(employee.updatedAt)}
|
{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 =
|
export const get_history = async (user_id: number, page: number, perPage: number): Promise<PaginatedHistory> => {
|
||||||
async (page: number, perPage: number): Promise<PaginatedHistory> => {
|
|
||||||
const offset = (page - 1) * perPage;
|
const offset = (page - 1) * perPage;
|
||||||
const historyQuery = sql`
|
let historyQuery = sql`
|
||||||
SELECT u.name, h.status, h.updatedAt
|
SELECT u.name, h.status, h.updatedAt
|
||||||
FROM history h
|
FROM history h
|
||||||
JOIN users u ON h.user_id = u.id
|
JOIN users u ON h.user_id = u.id
|
||||||
|
WHERE h.user_id = ${user_id}
|
||||||
ORDER BY h.id DESC
|
ORDER BY h.id DESC
|
||||||
LIMIT ${perPage} OFFSET ${offset}
|
LIMIT ${perPage} OFFSET ${offset}
|
||||||
`;
|
`;
|
||||||
const countQuery = sql`
|
let countQuery = sql`
|
||||||
SELECT COUNT(*) AS total_count
|
SELECT COUNT(*) AS total_count
|
||||||
FROM history
|
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(historyQuery),
|
||||||
db.execute(countQuery),
|
db.execute(countQuery),
|
||||||
]);
|
]);
|
||||||
// Safely cast results
|
// Safely cast results
|
||||||
const historyRows = historyResults[0] as unknown as
|
const historyrows = historyresults[0] as unknown as
|
||||||
{ name: string, status: string, updatedAt: Date }[];
|
{ name: string, status: string, updatedAt: Date }[];
|
||||||
const countRow = countResults[0] as unknown as { total_count: number }[];
|
const countrow = countresults[0] as unknown as { total_count: number }[];
|
||||||
const totalCount = countRow[0]?.total_count ?? 0;
|
const totalCount = countrow[0]?.total_count ?? 0;
|
||||||
const totalPages = Math.ceil(totalCount / perPage);
|
const totalPages = Math.ceil(totalCount / perPage);
|
||||||
// Format and map results
|
// Format and map results
|
||||||
const formattedResults: HistoryEntry[] = historyRows.map(row => ({
|
const formattedResults: HistoryEntry[] = historyrows.map(row => ({
|
||||||
name: row.name,
|
name: row.name,
|
||||||
status: row.status,
|
status: row.status,
|
||||||
updatedAt: new Date(row.updatedAt),
|
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,
|
||||||
|
//}
|
||||||
|
//};
|
||||||
|
//};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user