ugh
This commit is contained in:
		
							
								
								
									
										18
									
								
								src/app/api/get_employees.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/app/api/get_employees.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					"use server";
 | 
				
			||||||
 | 
					import type { NextApiRequest, NextApiResponse } from 'next';
 | 
				
			||||||
 | 
					import { getEmployees } from '~/server/functions';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default async function handler(req: NextApiRequest, res: NextApiResponse) {
 | 
				
			||||||
 | 
					  if (req.method === 'GET') {
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					      const employees = await getEmployees();
 | 
				
			||||||
 | 
					      res.status(200).json(employees);
 | 
				
			||||||
 | 
					    } catch (error) {
 | 
				
			||||||
 | 
					      console.error('Error fetching employees:', error);
 | 
				
			||||||
 | 
					      res.status(500).json({ message: 'Internal server error' });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    res.setHeader('Allow', ['GET']);
 | 
				
			||||||
 | 
					    res.status(405).json({ message: `Method ${req.method} Not Allowed` });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										29
									
								
								src/app/api/update_status.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/app/api/update_status.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
				
			|||||||
 | 
					"use server";
 | 
				
			||||||
 | 
					import type { NextApiRequest, NextApiResponse } from 'next';
 | 
				
			||||||
 | 
					import { updateEmployeeStatus } from '~/server/functions';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type UpdateStatusBody = {
 | 
				
			||||||
 | 
					  employeeIds: number[];
 | 
				
			||||||
 | 
					  newStatus: string;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default async function handler(req: NextApiRequest, res: NextApiResponse) {
 | 
				
			||||||
 | 
					  if (req.method === 'POST') {
 | 
				
			||||||
 | 
					    const { employeeIds, newStatus } = req.body as UpdateStatusBody;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!Array.isArray(employeeIds) || typeof newStatus !== 'string') {
 | 
				
			||||||
 | 
					      return res.status(400).json({ message: 'Invalid input' });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					      await updateEmployeeStatus(employeeIds, newStatus);
 | 
				
			||||||
 | 
					      return res.status(200).json({ message: 'Status updated successfully' });
 | 
				
			||||||
 | 
					    } catch (error) {
 | 
				
			||||||
 | 
					      console.error('Error updating status:', error);
 | 
				
			||||||
 | 
					      return res.status(500).json({ message: 'Internal server error' });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    res.setHeader('Allow', ['POST']);
 | 
				
			||||||
 | 
					    return res.status(405).json({ message: `Method ${req.method} Not Allowed` });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										121
									
								
								src/components/ui/Table.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								src/components/ui/Table.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,121 @@
 | 
				
			|||||||
 | 
					'use client';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { useState, useEffect } from 'react';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Define the Employee interface to match data fetched on the server
 | 
				
			||||||
 | 
					interface Employee {
 | 
				
			||||||
 | 
					  id: number;
 | 
				
			||||||
 | 
					  name: string;
 | 
				
			||||||
 | 
					  status: string;
 | 
				
			||||||
 | 
					  updatedAt: Date;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default function Table({ employees }: { employees: Employee[] }) {
 | 
				
			||||||
 | 
					  const [selectedIds, setSelectedIds] = useState<number[]>([]);
 | 
				
			||||||
 | 
					  const [status, setStatus] = useState('');
 | 
				
			||||||
 | 
					  const [employeeData, setEmployeeData] = useState(employees);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  useEffect(() => {
 | 
				
			||||||
 | 
					    // Refresh employee data if needed after state updates
 | 
				
			||||||
 | 
					    setEmployeeData(employees);
 | 
				
			||||||
 | 
					  }, [employees]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const handleCheckboxChange = (id: number) => {
 | 
				
			||||||
 | 
					    setSelectedIds((prevSelected) =>
 | 
				
			||||||
 | 
					      prevSelected.includes(id)
 | 
				
			||||||
 | 
					        ? prevSelected.filter((prevId) => prevId !== id)
 | 
				
			||||||
 | 
					        : [...prevSelected, id]
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const handleStatusChange = (e: React.ChangeEvent<HTMLInputElement>) => {
 | 
				
			||||||
 | 
					    setStatus(e.target.value);
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const handleSubmit = async () => {
 | 
				
			||||||
 | 
					    if (selectedIds.length > 0 && status.trim() !== '') {
 | 
				
			||||||
 | 
					      await fetch('/api/update_status', {
 | 
				
			||||||
 | 
					        method: 'POST',
 | 
				
			||||||
 | 
					        headers: {
 | 
				
			||||||
 | 
					          'Content-Type': 'application/json',
 | 
				
			||||||
 | 
					          'Authorization': `Bearer ${process.env.API_KEY}`
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        body: JSON.stringify({ employeeIds: selectedIds, newStatus: status }),
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					      // Optionally refresh data on the client-side after update
 | 
				
			||||||
 | 
					      const updatedEmployees = await fetchEmployees();
 | 
				
			||||||
 | 
					      setEmployeeData(updatedEmployees);
 | 
				
			||||||
 | 
					      setSelectedIds([]);
 | 
				
			||||||
 | 
					      setStatus('');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const fetchEmployees = async (): Promise<Employee[]> => {
 | 
				
			||||||
 | 
					    const res = await fetch('/api/get_employees', {
 | 
				
			||||||
 | 
					      method: 'GET',
 | 
				
			||||||
 | 
					      headers: {
 | 
				
			||||||
 | 
					        'Authorization': `Bearer ${process.env.API_KEY}`
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    return res.json() as Promise<Employee[]>;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const formatTime = (timestamp: Date) => {
 | 
				
			||||||
 | 
					    const date = new Date(timestamp);
 | 
				
			||||||
 | 
					    const time = date.toLocaleTimeString('en-US', {
 | 
				
			||||||
 | 
					      hour: 'numeric',
 | 
				
			||||||
 | 
					      minute: 'numeric',
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    const day = date.getDate();
 | 
				
			||||||
 | 
					    const month = date.toLocaleString('default', { month: 'long' });
 | 
				
			||||||
 | 
					    return `${time} - ${month} ${day}`;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <div>
 | 
				
			||||||
 | 
					      <table className="w-5/6 m-auto text-center border-collapse text-[42px]">
 | 
				
			||||||
 | 
					        <thead className="bg-gradient-to-br from-[#212121] to-[#333333]">
 | 
				
			||||||
 | 
					          <tr>
 | 
				
			||||||
 | 
					            <th className="p-5 border border-[#3e4446] text-[48px]" />
 | 
				
			||||||
 | 
					            <th className="p-2 border border-[#3e4446] text-[48px]">Name</th>
 | 
				
			||||||
 | 
					            <th className="p-2 border border-[#3e4446] text-[48px]">Status</th>
 | 
				
			||||||
 | 
					            <th className="p-2 border border-[#3e4446] text-[48px]">Updated At</th>
 | 
				
			||||||
 | 
					          </tr>
 | 
				
			||||||
 | 
					        </thead>
 | 
				
			||||||
 | 
					        <tbody>
 | 
				
			||||||
 | 
					          {employeeData.map((employee) => (
 | 
				
			||||||
 | 
					            <tr className="even:bg-gradient-to-bl from-[#222222] to-[#232323]" key={employee.id}>
 | 
				
			||||||
 | 
					              <td className="p-1 border border-[#3e4446]">
 | 
				
			||||||
 | 
					                <input
 | 
				
			||||||
 | 
					                  type="checkbox"
 | 
				
			||||||
 | 
					                  className="m-0 cursor-pointer transform scale-150"
 | 
				
			||||||
 | 
					                  checked={selectedIds.includes(employee.id)}
 | 
				
			||||||
 | 
					                  onChange={() => handleCheckboxChange(employee.id)}
 | 
				
			||||||
 | 
					                />
 | 
				
			||||||
 | 
					              </td>
 | 
				
			||||||
 | 
					              <td className="p-1 border border-[#3e4446]">{employee.name}</td>
 | 
				
			||||||
 | 
					              <td className="p-1 border border-[#3e4446]">{employee.status}</td>
 | 
				
			||||||
 | 
					              <td className="p-1 border border-[#3e4446]">{formatTime(employee.updatedAt)}</td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					          ))}
 | 
				
			||||||
 | 
					        </tbody>
 | 
				
			||||||
 | 
					      </table>
 | 
				
			||||||
 | 
					      <div className="m-auto flex flex-row items-center justify-center">
 | 
				
			||||||
 | 
					        <input
 | 
				
			||||||
 | 
					          type="text"
 | 
				
			||||||
 | 
					          placeholder="New Status"
 | 
				
			||||||
 | 
					          className="w-1/5 p-2 border-none rounded-md"
 | 
				
			||||||
 | 
					          value={status}
 | 
				
			||||||
 | 
					          onChange={handleStatusChange}
 | 
				
			||||||
 | 
					        />
 | 
				
			||||||
 | 
					        <button
 | 
				
			||||||
 | 
					          type="submit"
 | 
				
			||||||
 | 
					          className="m-2 px-2 py-5 border-none rounded-md text-center bg-gradient-to-br from-[#484848] to-[#333333]"
 | 
				
			||||||
 | 
					          onClick={handleSubmit}
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					          Update
 | 
				
			||||||
 | 
					        </button>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,67 +1,70 @@
 | 
				
			|||||||
//import { auth } from "~/auth";
 | 
					//import { auth } from "~/auth";
 | 
				
			||||||
import { getEmployees } from "~/server/functions";
 | 
					import { getEmployees } from "~/server/functions";
 | 
				
			||||||
 | 
					import Table from "~/components/ui/Table";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const dynamic = "force-dynamic";
 | 
					//export const dynamic = "force-dynamic";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default async function Techs_Table() {
 | 
					export default async function Techs_Table() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const employees = await getEmployees();
 | 
					  const employees = await getEmployees();
 | 
				
			||||||
 | 
					  return <Table employees={employees} />;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  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",
 | 
				
			||||||
      {hour: "numeric", minute: "numeric",});
 | 
					      //{hour: "numeric", minute: "numeric",});
 | 
				
			||||||
    const day = date.getDate();
 | 
					    //const day = date.getDate();
 | 
				
			||||||
    const month = date.toLocaleString("default", { month: "long" });
 | 
					    //const month = date.toLocaleString("default", { month: "long" });
 | 
				
			||||||
    return `${time} - ${month} ${day}`;
 | 
					    //return `${time} - ${month} ${day}`;
 | 
				
			||||||
  }
 | 
					  //}
 | 
				
			||||||
  //const session = await auth();
 | 
					  //const session = await auth();
 | 
				
			||||||
  //const users_name = session?.user?.name;
 | 
					  //const users_name = session?.user?.name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  //return (
 | 
				
			||||||
    <div>
 | 
					    //<div>
 | 
				
			||||||
      <table className="w-5/6 m-auto text-center border-collapse text-[42px]">
 | 
					      //<table className="w-5/6 m-auto text-center border-collapse text-[42px]">
 | 
				
			||||||
        <thead className="bg-gradient-to-br from-[#212121] to-[#333333]">
 | 
					        //<thead className="bg-gradient-to-br from-[#121212] to-[#333333]">
 | 
				
			||||||
          <tr>
 | 
					          //<tr>
 | 
				
			||||||
            <th className="p-5 border border-[#3e4446] text-[48px]"/>
 | 
					            //<th className="p-5 border border-[#3e4446] text-[48px]"/>
 | 
				
			||||||
            <th className="p-2 border border-[#3e4446] text-[48px]">
 | 
					            //<th className="p-2 border border-[#3e4446] text-[48px]">
 | 
				
			||||||
              Name
 | 
					              //Name
 | 
				
			||||||
            </th>
 | 
					            //</th>
 | 
				
			||||||
            <th className="p-2 border border-[#3e4446] text-[48px]">
 | 
					            //<th className="p-2 border border-[#3e4446] text-[48px]">
 | 
				
			||||||
              Status
 | 
					              //Status
 | 
				
			||||||
            </th>
 | 
					            //</th>
 | 
				
			||||||
            <th className="p-2 border border-[#3e4446] text-[48px]">
 | 
					            //<th className="p-2 border border-[#3e4446] text-[48px]">
 | 
				
			||||||
              Updated At
 | 
					              //Updated At
 | 
				
			||||||
            </th>
 | 
					            //</th>
 | 
				
			||||||
          </tr>
 | 
					          //</tr>
 | 
				
			||||||
        </thead>
 | 
					        //</thead>
 | 
				
			||||||
        <tbody>
 | 
					        //<tbody>
 | 
				
			||||||
            {employees.map((employee) => (
 | 
					            //{employees.map((employee) => (
 | 
				
			||||||
              <tr className="even:bg-gradient-to-bl from-[#222222] to-[#232323]" key={employee.id}>
 | 
					              //<tr className="even:bg-gradient-to-bl from-[#222222] to-[#323232]" key={employee.id}>
 | 
				
			||||||
                <td className="p-1 border border-[#3e4446]">
 | 
					                //<td className="p-1 border border-[#3e4446]">
 | 
				
			||||||
                  <input type="checkbox"
 | 
					                  //<input type="checkbox"
 | 
				
			||||||
                    className="m-0 cursor-pointer transform scale-150"
 | 
					                    //className="m-0 cursor-pointer transform scale-150"
 | 
				
			||||||
                    //checked={}
 | 
					                    ////checked={}
 | 
				
			||||||
                  />
 | 
					                  ///>
 | 
				
			||||||
                </td>
 | 
					                //</td>
 | 
				
			||||||
                <td className="p-1 border border-[#3e4446]">{employee.name}</td>
 | 
					                //<td className="p-1 border border-[#3e4446]">{employee.name}</td>
 | 
				
			||||||
                <td className="p-1 border border-[#3e4446]">{employee.status}</td>
 | 
					                //<td className="p-1 border border-[#3e4446]">{employee.status}</td>
 | 
				
			||||||
                <td className="p-1 border border-[#3e4446]">{formatTime(employee.updatedAt)}</td>
 | 
					                //<td className="p-1 border border-[#3e4446]">{formatTime(employee.updatedAt)}</td>
 | 
				
			||||||
              </tr>
 | 
					              //</tr>
 | 
				
			||||||
            ))}
 | 
					            //))}
 | 
				
			||||||
        </tbody>
 | 
					        //</tbody>
 | 
				
			||||||
      </table>
 | 
					      //</table>
 | 
				
			||||||
      <div className="m-auto flex flex-row items-center justify-center">
 | 
					      //<div className="m-auto flex flex-row items-center justify-center">
 | 
				
			||||||
        <input type="text" placeholder="New Status"
 | 
					        //<input type="text" placeholder="New Status"
 | 
				
			||||||
          className="w-1/5 p-2 border-none rounded-md"
 | 
					          //className="w-1/5 p-2 border-none rounded-xl"
 | 
				
			||||||
          //value={}
 | 
					          ////value={}
 | 
				
			||||||
        />
 | 
					        ///>
 | 
				
			||||||
        <button type="submit"
 | 
					        //<button type="submit"
 | 
				
			||||||
          className="m-2 px-2 py-5 border-none rounded-md text-center bg-gradient-to-br from-[#484848] to-[#333333]"
 | 
					          //className="m-2 p-3 border-none rounded-2xl text-center bg-gradient-to-br from-[#484848] to-[#333333]"
 | 
				
			||||||
        >
 | 
					        //>
 | 
				
			||||||
          Update
 | 
					          //Update
 | 
				
			||||||
        </button>
 | 
					        //</button>
 | 
				
			||||||
      </div>
 | 
					      //</div>
 | 
				
			||||||
    </div>
 | 
					    //</div>
 | 
				
			||||||
  );
 | 
					  //);
 | 
				
			||||||
};
 | 
					//};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,11 +1,33 @@
 | 
				
			|||||||
import "server-only";
 | 
					import "server-only";
 | 
				
			||||||
import { db } from "~/server/db";
 | 
					import { db } from "~/server/db";
 | 
				
			||||||
//import * as schema from "~/server/db/schema";
 | 
					import { sql } from "drizzle-orm";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Function to Get Employees
 | 
				
			||||||
export const getEmployees = async () => {
 | 
					export const getEmployees = async () => {
 | 
				
			||||||
  return await db.query.users.findMany({
 | 
					  return await db.query.users.findMany({
 | 
				
			||||||
    orderBy: (model, { desc }) => desc(model.id),
 | 
					    orderBy: (model, { asc }) => asc(model.id),
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Function to Update Employee Status using Raw SQL
 | 
				
			||||||
 | 
					export const updateEmployeeStatus = async (employeeIds: number[], newStatus: string) => {
 | 
				
			||||||
 | 
					  try {
 | 
				
			||||||
 | 
					    // Convert array of ids to a format suitable for SQL query (comma-separated string)
 | 
				
			||||||
 | 
					    const idString = employeeIds.join(",");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Prepare the raw SQL query with embedded variables
 | 
				
			||||||
 | 
					    const query = `
 | 
				
			||||||
 | 
					      UPDATE users
 | 
				
			||||||
 | 
					      SET status = '${newStatus}', updatedAt = '${new Date().toISOString()}'
 | 
				
			||||||
 | 
					      WHERE id IN (${idString})
 | 
				
			||||||
 | 
					    `;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Execute the raw SQL query using the execute method
 | 
				
			||||||
 | 
					    await db.execute(sql`${query}`);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return { success: true };
 | 
				
			||||||
 | 
					  } catch (error) {
 | 
				
			||||||
 | 
					    console.error("Error updating employee status:", error);
 | 
				
			||||||
 | 
					    throw new Error("Failed to update status");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user