diff --git a/public/images/tech_tracker_favicon.png b/public/images/tech_tracker_favicon.png new file mode 100644 index 0000000..d2f5176 Binary files /dev/null and b/public/images/tech_tracker_favicon.png differ diff --git a/src/app/layout.tsx b/src/app/layout.tsx index b0d70c5..2ad8d53 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -8,7 +8,22 @@ import { type Metadata } from "next"; export const metadata: Metadata = { title: "Tech Tracker", description: "App used by COG IT employees to update their status throughout the day.", - icons: [{ rel: "icon", url: "/favicon.ico" }], + icons: [ + { + rel: 'icon', + url: '/favicon.ico', + }, + { + rel: 'icon', + type: 'image/png', + sizes: '32x32', + url: '/images/tech_tracker_favicon.png', + }, + { + rel: 'apple-touch-icon', + url: '/favicon.ico', + }, + ], }; const fontSans = FontSans({ diff --git a/src/components/ui/Table.tsx b/src/components/ui/Table.tsx index 603e96c..95d88f9 100644 --- a/src/components/ui/Table.tsx +++ b/src/components/ui/Table.tsx @@ -1,6 +1,6 @@ 'use client'; - import { useState, useEffect, useCallback } from 'react'; +import { useSession } from "next-auth/react"; // Define the Employee interface to match data fetched on the server interface Employee { @@ -11,11 +11,20 @@ interface Employee { } export default function Table({ employees }: { employees: Employee[] }) { + const { data: session, status } = useSession(); + const [loading, setLoading] = useState(true); const [selectedIds, setSelectedIds] = useState([]); const [selectAll, setSelectAll] = useState(false); - const [status, setStatus] = useState(''); + const [employeeStatus, setStatus] = useState(''); const [employeeData, setEmployeeData] = useState(employees); + useEffect(() => { + if (status !== "loading") { + setLoading(false); + } + }, [status]); + + useEffect(() => { // Refresh employee data if needed after state updates setEmployeeData(employees); @@ -85,20 +94,45 @@ export default function Table({ employees }: { employees: Employee[] }) { }; const handleSubmit = async () => { - if (selectedIds.length > 0 && status.trim() !== '') { + if (selectedIds.length > 0 && employeeStatus.trim() !== '') { await fetch('/api/v2/update_status', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${process.env.API_KEY}` }, - body: JSON.stringify({ employeeIds: selectedIds, newStatus: status }), + body: JSON.stringify({ employeeIds: selectedIds, newStatus: employeeStatus }), }); // Optionally refresh data on the client-side after update const updatedEmployees = await fetchEmployees(); setEmployeeData(updatedEmployees); setSelectedIds([]); setStatus(''); + } else { + if (!session) { + alert("You must be signed in to update status."); + } else { + const usersName = session?.user?.name; + const employee = employees.find(employee => employee.name === usersName); + if (employee) { + setSelectedIds([employee.id]); + if (selectedIds.length > 0 && employeeStatus.trim() !== '') { + await fetch('/api/v2/update_status', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${process.env.API_KEY}` + }, + body: JSON.stringify({ employeeIds: selectedIds, newStatus: employeeStatus }), + }); + // Optionally refresh data on the client-side after update + const updatedEmployees = await fetchEmployees(); + setEmployeeData(updatedEmployees); + setSelectedIds([]); + setStatus(''); + } + } + } } }; @@ -118,7 +152,7 @@ export default function Table({ employees }: { employees: Employee[] }) { const month = date.toLocaleString('default', { month: 'long' }); return `${time} - ${month} ${day}`; }; - + if (loading) return
Loading...
; return (
@@ -161,7 +195,7 @@ export default function Table({ employees }: { employees: Employee[] }) { type="text" placeholder="New Status" className="min-w-[120px] lg:min-w-[400px] bg-[#F9F6EE] py-2 px-3 border-none rounded-xl text-[#111111] lg:text-2xl" - value={status} + value={employeeStatus} onChange={handleStatusChange} onKeyDown={handleKeyPress} /> diff --git a/src/components/ui/Techs.tsx b/src/components/ui/Techs.tsx index 433e667..069a8a3 100644 --- a/src/components/ui/Techs.tsx +++ b/src/components/ui/Techs.tsx @@ -4,5 +4,5 @@ import Table from "~/components/ui/Table"; export default async function Techs() { const employees = await getEmployees(); - return
; + return
; }; diff --git a/src/server/functions.ts b/src/server/functions.ts index f3f3b8c..0f6d64f 100644 --- a/src/server/functions.ts +++ b/src/server/functions.ts @@ -9,12 +9,16 @@ export const getEmployees = async () => { }); }; +const convertToUTC = (date: Date) => { + return new Date(date.setHours(date.getUTCHours())+ 5); +}; + // Function to Update Employee Status using Raw SQL export const updateEmployeeStatus = async (employeeIds: string[], newStatus: string) => { try { // Convert array of ids to a format suitable for SQL query (comma-separated string) const idList = employeeIds.map(id => parseInt(id, 10)); - const updatedAt = new Date(); + const updatedAt = convertToUTC(new Date()); // Prepare the query using drizzle-orm's template-like syntax for escaping variables const query = sql`