markout n shit

This commit is contained in:
Om Lanke
2025-07-05 21:08:14 +05:30
parent d0d6320362
commit 59f9c356ad
12 changed files with 951 additions and 66 deletions

View File

@@ -1,39 +1,47 @@
import { ColumnDef } from '@tanstack/react-table'; import { ColumnDef } from '@tanstack/react-table';
// Remove server-specific imports to avoid issues in client bundle import { students, internships, resumes, grades } from '@workspace/db/schema';
// import { createSelectSchema, students } from '@workspace/db';
// import * as z from 'zod/v4';
import { Badge } from '@workspace/ui/components/badge'; import { Badge } from '@workspace/ui/components/badge';
// import { Button } from '@workspace/ui/components/button'; // import { Button } from '@workspace/ui/components/button';
import { Avatar, AvatarFallback, AvatarImage } from '@workspace/ui/components/avatar'; import { Avatar, AvatarFallback, AvatarImage } from '@workspace/ui/components/avatar';
import { Eye, Mail, Phone, MapPin, Calendar, GraduationCap } from 'lucide-react'; import { Eye, Mail, Phone, MapPin, Calendar, GraduationCap } from 'lucide-react';
// Define the Student interface locally to avoid importing server-side code type SelectStudent = typeof students.$inferSelect
export interface Student { type SelectInternships = typeof internships.$inferSelect
id: number; type SelectResume = typeof resumes.$inferSelect
email: string; type SelectGrades = typeof grades.$inferSelect
rollNumber: string | null;
verified: boolean; export type Student = SelectStudent & {
firstName: string | null; internships: SelectInternships[];
middleName: string | null; resumes: SelectResume[];
lastName: string | null; grades: SelectGrades[];
mothersName?: string | null; };
gender?: string | null;
dob?: Date | null; // export interface Student {
personalGmail?: string | null; // id: number;
phoneNumber?: string | null; // email: string;
address?: string | null; // rollNumber: string | null;
profilePicture?: string | null; // verified: boolean;
degree?: string | null; // firstName: string | null;
branch?: string | null; // middleName: string | null;
year?: string | null; // lastName: string | null;
skills?: string[] | null; // mothersName?: string | null;
ssc?: number | null; // gender?: string | null;
hsc?: number | null; // dob?: Date | null;
isDiploma?: boolean | null; // personalGmail?: string | null;
linkedin?: string | null; // phoneNumber?: string | null;
github?: string | null; // address?: string | null;
createdAt?: Date; // profilePicture?: string | null;
} // degree?: string | null;
// branch?: string | null;
// year?: string | null;
// skills?: string[] | null;
// ssc?: number | null;
// hsc?: number | null;
// isDiploma?: boolean | null;
// linkedin?: string | null;
// github?: string | null;
// createdAt?: Date;
// }
export const columns: ColumnDef<Student>[] = [ export const columns: ColumnDef<Student>[] = [
{ {

View File

@@ -2,7 +2,6 @@
import { useState } from 'react'; import { useState } from 'react';
import { import {
ColumnDef,
flexRender, flexRender,
getCoreRowModel, getCoreRowModel,
getPaginationRowModel, getPaginationRowModel,
@@ -23,9 +22,10 @@ import { columns } from './columns';
interface DataTableProps { interface DataTableProps {
data: Student[]; data: Student[];
markoutAction: (id: number, state: boolean) => void;
} }
export function DataTable({ data }: DataTableProps) { export function DataTable({ data, markoutAction }: DataTableProps) {
const [selectedStudent, setSelectedStudent] = useState<Student | null>(null); const [selectedStudent, setSelectedStudent] = useState<Student | null>(null);
const [isModalOpen, setIsModalOpen] = useState(false); const [isModalOpen, setIsModalOpen] = useState(false);
@@ -122,6 +122,9 @@ export function DataTable({ data }: DataTableProps) {
student={selectedStudent} student={selectedStudent}
isOpen={isModalOpen} isOpen={isModalOpen}
onClose={handleCloseModal} onClose={handleCloseModal}
markoutAction={(state: boolean) => {
markoutAction(selectedStudent.id, state);
}}
/> />
)} )}
</> </>

View File

@@ -6,30 +6,25 @@ import { Button } from '@workspace/ui/components/button';
import { revalidatePath } from 'next/cache'; import { revalidatePath } from 'next/cache';
import { eq } from '@workspace/db/drizzle'; import { eq } from '@workspace/db/drizzle';
import { Card, CardContent, CardHeader, CardTitle } from '@workspace/ui/components/card'; import { Card, CardContent, CardHeader, CardTitle } from '@workspace/ui/components/card';
import { Badge } from '@workspace/ui/components/badge';
import { Separator } from '@workspace/ui/components/separator';
import { import {
Users, Users,
Plus, Plus,
Search, Search,
Filter, Filter,
Download, Download,
Mail,
Phone,
MapPin,
Calendar,
GraduationCap,
User, User,
Linkedin,
Github,
FileText,
Award,
BookOpen
} from 'lucide-react'; } from 'lucide-react';
async function getData(): Promise<Student[]> { async function getData(): Promise<Student[]> {
try { try {
const data = await db.select().from(students); const data = await db.query.students.findMany({
with: {
internships: true,
resumes: true,
grades: true,
},
orderBy: (students, { asc }) => [asc(students.createdAt)],
});
return data; return data;
} catch (error) { } catch (error) {
console.error('Database error:', error); console.error('Database error:', error);
@@ -49,6 +44,16 @@ async function addStudent(formData: FormData) {
revalidatePath('/students'); revalidatePath('/students');
} }
async function markoutAction(id: number, state: boolean) {
'use server';
try {
await db.update(students).set({ markedOut: state }).where(eq(students.id, id));
revalidatePath('/students');
} catch (error) {
console.error('Error marking student:', error);
}
}
async function StudentsTable() { async function StudentsTable() {
const data = await getData(); const data = await getData();
@@ -194,7 +199,7 @@ async function StudentsTable() {
</Button> </Button>
</div> </div>
) : ( ) : (
<DataTable data={data} /> <DataTable data={data} markoutAction={markoutAction}/>
)} )}
</CardContent> </CardContent>
</Card> </Card>

View File

@@ -1,11 +1,13 @@
'use client'; 'use client';
import React from 'react';
import { Student } from './columns'; import { Student } from './columns';
import { import {
Dialog, Dialog,
DialogContent, DialogContent,
DialogHeader, DialogHeader,
DialogTitle, DialogTitle,
DialogClose,
} from '@workspace/ui/components/dialog'; } from '@workspace/ui/components/dialog';
import { Badge } from '@workspace/ui/components/badge'; import { Badge } from '@workspace/ui/components/badge';
import { Avatar, AvatarFallback, AvatarImage } from '@workspace/ui/components/avatar'; import { Avatar, AvatarFallback, AvatarImage } from '@workspace/ui/components/avatar';
@@ -20,7 +22,6 @@ import {
User, User,
Linkedin, Linkedin,
Github, Github,
FileText,
Award, Award,
BookOpen, BookOpen,
ExternalLink, ExternalLink,
@@ -29,14 +30,16 @@ import {
Download, Download,
Share2 Share2
} from 'lucide-react'; } from 'lucide-react';
import { Switch } from '@workspace/ui/components/switch';
interface StudentDetailsModalProps { interface StudentDetailsModalProps {
student: Student; student: Student;
isOpen: boolean; isOpen: boolean;
onClose: () => void; onClose: () => void;
markoutAction: (state: boolean) => void;
} }
export function StudentDetailsModal({ student, isOpen, onClose }: StudentDetailsModalProps) { export function StudentDetailsModal({ student, isOpen, onClose, markoutAction }: StudentDetailsModalProps) {
const fullName = [ const fullName = [
student.firstName, student.firstName,
student.middleName, student.middleName,
@@ -57,6 +60,17 @@ export function StudentDetailsModal({ student, isOpen, onClose }: StudentDetails
return `${value}%`; return `${value}%`;
}; };
const [markedOut, setMarkedOut] = React.useState(student.markedOut ?? false);
React.useEffect(() => {
setMarkedOut(student.markedOut ?? false);
}, [student.markedOut]);
const handleMarkoutChange = (checked: boolean) => {
setMarkedOut(checked);
markoutAction(checked);
};
return ( return (
<Dialog open={isOpen} onOpenChange={onClose}> <Dialog open={isOpen} onOpenChange={onClose}>
<DialogContent className="max-w-4xl max-h-[90vh] overflow-y-auto"> <DialogContent className="max-w-4xl max-h-[90vh] overflow-y-auto">
@@ -65,14 +79,28 @@ export function StudentDetailsModal({ student, isOpen, onClose }: StudentDetails
<DialogTitle className="text-2xl font-bold text-gray-800"> <DialogTitle className="text-2xl font-bold text-gray-800">
Student Details Student Details
</DialogTitle> </DialogTitle>
<Button <div className="flex items-center gap-4">
variant="ghost" <div className="flex items-center gap-2">
size="sm" <Switch
onClick={onClose} checked={markedOut}
className="text-gray-500 hover:text-gray-700" onCheckedChange={handleMarkoutChange}
> className={
markedOut
? 'bg-red-600 border-red-600 focus-visible:ring-red-600/50'
: 'bg-white border-gray-300 focus-visible:ring-gray-300/50'
}
/>
<span className={markedOut ? 'text-red-600 font-semibold' : 'text-gray-700'}>
Marked Out
</span>
</div>
<DialogClose asChild>
<Button variant="outline" size="icon" className="text-gray-500 hover:text-gray-700">
<X className="w-5 h-5" /> <X className="w-5 h-5" />
<span className="sr-only">Close</span>
</Button> </Button>
</DialogClose>
</div>
</div> </div>
</DialogHeader> </DialogHeader>
@@ -319,10 +347,6 @@ export function StudentDetailsModal({ student, isOpen, onClose }: StudentDetails
<Button variant="outline" onClick={onClose}> <Button variant="outline" onClick={onClose}>
Close Close
</Button> </Button>
<Button className="flex items-center gap-2">
<Share2 className="w-4 h-4" />
Share Profile
</Button>
</div> </div>
</div> </div>
</DialogContent> </DialogContent>

View File

@@ -0,0 +1 @@
ALTER TABLE "students" ADD COLUMN "markedOut" boolean DEFAULT false NOT NULL;

View File

@@ -0,0 +1,776 @@
{
"id": "e4a847ee-3905-4955-b7bc-c72954d56338",
"prevId": "9394fab4-d946-45ac-ac5a-2fc22cf46a07",
"version": "7",
"dialect": "postgresql",
"tables": {
"public.admins": {
"name": "admins",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"email": {
"name": "email",
"type": "text",
"primaryKey": false,
"notNull": true
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updatedAt": {
"name": "updatedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {
"admins_email_unique": {
"name": "admins_email_unique",
"nullsNotDistinct": false,
"columns": [
"email"
]
}
},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.applications": {
"name": "applications",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"jobId": {
"name": "jobId",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"studentId": {
"name": "studentId",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"resumeId": {
"name": "resumeId",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"status": {
"name": "status",
"type": "text",
"primaryKey": false,
"notNull": true,
"default": "'pending'"
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updatedAt": {
"name": "updatedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"applications_jobId_jobs_id_fk": {
"name": "applications_jobId_jobs_id_fk",
"tableFrom": "applications",
"tableTo": "jobs",
"columnsFrom": [
"jobId"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
},
"applications_studentId_students_id_fk": {
"name": "applications_studentId_students_id_fk",
"tableFrom": "applications",
"tableTo": "students",
"columnsFrom": [
"studentId"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
},
"applications_resumeId_resumes_id_fk": {
"name": "applications_resumeId_resumes_id_fk",
"tableFrom": "applications",
"tableTo": "resumes",
"columnsFrom": [
"resumeId"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.companies": {
"name": "companies",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
"notNull": true
},
"email": {
"name": "email",
"type": "text",
"primaryKey": false,
"notNull": true
},
"link": {
"name": "link",
"type": "text",
"primaryKey": false,
"notNull": true
},
"description": {
"name": "description",
"type": "text",
"primaryKey": false,
"notNull": true
},
"imageURL": {
"name": "imageURL",
"type": "text",
"primaryKey": false,
"notNull": true
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updatedAt": {
"name": "updatedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.grades": {
"name": "grades",
"schema": "",
"columns": {
"studentId": {
"name": "studentId",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"sem": {
"name": "sem",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"sgpi": {
"name": "sgpi",
"type": "numeric(4, 2)",
"primaryKey": false,
"notNull": true
},
"isKT": {
"name": "isKT",
"type": "boolean",
"primaryKey": false,
"notNull": true
},
"deadKT": {
"name": "deadKT",
"type": "boolean",
"primaryKey": false,
"notNull": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updatedAt": {
"name": "updatedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"grades_studentId_students_id_fk": {
"name": "grades_studentId_students_id_fk",
"tableFrom": "grades",
"tableTo": "students",
"columnsFrom": [
"studentId"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {
"grades_studentId_sem_pk": {
"name": "grades_studentId_sem_pk",
"columns": [
"studentId",
"sem"
]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {
"sem_check1": {
"name": "sem_check1",
"value": "\"grades\".\"sem\" < 9"
}
},
"isRLSEnabled": false
},
"public.internships": {
"name": "internships",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"studentId": {
"name": "studentId",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"title": {
"name": "title",
"type": "text",
"primaryKey": false,
"notNull": true
},
"company": {
"name": "company",
"type": "text",
"primaryKey": false,
"notNull": true
},
"description": {
"name": "description",
"type": "text",
"primaryKey": false,
"notNull": true
},
"location": {
"name": "location",
"type": "text",
"primaryKey": false,
"notNull": true
},
"startDate": {
"name": "startDate",
"type": "timestamp",
"primaryKey": false,
"notNull": true
},
"endDate": {
"name": "endDate",
"type": "timestamp",
"primaryKey": false,
"notNull": true
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updatedAt": {
"name": "updatedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"internships_studentId_students_id_fk": {
"name": "internships_studentId_students_id_fk",
"tableFrom": "internships",
"tableTo": "students",
"columnsFrom": [
"studentId"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.jobs": {
"name": "jobs",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"companyId": {
"name": "companyId",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"title": {
"name": "title",
"type": "text",
"primaryKey": false,
"notNull": true
},
"link": {
"name": "link",
"type": "text",
"primaryKey": false,
"notNull": true
},
"description": {
"name": "description",
"type": "text",
"primaryKey": false,
"notNull": true
},
"location": {
"name": "location",
"type": "text",
"primaryKey": false,
"notNull": true
},
"imageURL": {
"name": "imageURL",
"type": "text",
"primaryKey": false,
"notNull": true
},
"salary": {
"name": "salary",
"type": "text",
"primaryKey": false,
"notNull": true
},
"applicationDeadline": {
"name": "applicationDeadline",
"type": "timestamp",
"primaryKey": false,
"notNull": true
},
"active": {
"name": "active",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
},
"minCGPA": {
"name": "minCGPA",
"type": "numeric(4, 2)",
"primaryKey": false,
"notNull": true,
"default": "'0'"
},
"minSSC": {
"name": "minSSC",
"type": "numeric(4, 2)",
"primaryKey": false,
"notNull": true,
"default": "'0'"
},
"minHSC": {
"name": "minHSC",
"type": "numeric(4, 2)",
"primaryKey": false,
"notNull": true,
"default": "'0'"
},
"allowDeadKT": {
"name": "allowDeadKT",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": true
},
"allowLiveKT": {
"name": "allowLiveKT",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": true
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updatedAt": {
"name": "updatedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"jobs_companyId_companies_id_fk": {
"name": "jobs_companyId_companies_id_fk",
"tableFrom": "jobs",
"tableTo": "companies",
"columnsFrom": [
"companyId"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.resumes": {
"name": "resumes",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"studentId": {
"name": "studentId",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"title": {
"name": "title",
"type": "text",
"primaryKey": false,
"notNull": true
},
"link": {
"name": "link",
"type": "text",
"primaryKey": false,
"notNull": true
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updatedAt": {
"name": "updatedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"resumes_studentId_students_id_fk": {
"name": "resumes_studentId_students_id_fk",
"tableFrom": "resumes",
"tableTo": "students",
"columnsFrom": [
"studentId"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.students": {
"name": "students",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"email": {
"name": "email",
"type": "text",
"primaryKey": false,
"notNull": true
},
"rollNumber": {
"name": "rollNumber",
"type": "varchar(12)",
"primaryKey": false,
"notNull": false
},
"verified": {
"name": "verified",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
},
"markedOut": {
"name": "markedOut",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
},
"firstName": {
"name": "firstName",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false
},
"middleName": {
"name": "middleName",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false
},
"lastName": {
"name": "lastName",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false
},
"mothersName": {
"name": "mothersName",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false
},
"gender": {
"name": "gender",
"type": "varchar(10)",
"primaryKey": false,
"notNull": false
},
"dob": {
"name": "dob",
"type": "timestamp",
"primaryKey": false,
"notNull": false
},
"personalGmail": {
"name": "personalGmail",
"type": "text",
"primaryKey": false,
"notNull": false
},
"phoneNumber": {
"name": "phoneNumber",
"type": "varchar(10)",
"primaryKey": false,
"notNull": false
},
"address": {
"name": "address",
"type": "text",
"primaryKey": false,
"notNull": false
},
"profilePicture": {
"name": "profilePicture",
"type": "text",
"primaryKey": false,
"notNull": false
},
"degree": {
"name": "degree",
"type": "text",
"primaryKey": false,
"notNull": false
},
"branch": {
"name": "branch",
"type": "text",
"primaryKey": false,
"notNull": false
},
"year": {
"name": "year",
"type": "text",
"primaryKey": false,
"notNull": false
},
"skills": {
"name": "skills",
"type": "text[]",
"primaryKey": false,
"notNull": false,
"default": "ARRAY[]::text[]"
},
"linkedin": {
"name": "linkedin",
"type": "text",
"primaryKey": false,
"notNull": false
},
"github": {
"name": "github",
"type": "text",
"primaryKey": false,
"notNull": false
},
"ssc": {
"name": "ssc",
"type": "numeric(4, 2)",
"primaryKey": false,
"notNull": false
},
"hsc": {
"name": "hsc",
"type": "numeric(4, 2)",
"primaryKey": false,
"notNull": false
},
"isDiploma": {
"name": "isDiploma",
"type": "boolean",
"primaryKey": false,
"notNull": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updatedAt": {
"name": "updatedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
}
},
"enums": {},
"schemas": {},
"sequences": {},
"roles": {},
"policies": {},
"views": {},
"_meta": {
"columns": {},
"schemas": {},
"tables": {}
}
}

View File

@@ -50,6 +50,13 @@
"when": 1751619273079, "when": 1751619273079,
"tag": "0006_mysterious_lionheart", "tag": "0006_mysterious_lionheart",
"breakpoints": true "breakpoints": true
},
{
"idx": 7,
"version": "7",
"when": 1751727461248,
"tag": "0007_fuzzy_zuras",
"breakpoints": true
} }
] ]
} }

View File

@@ -19,6 +19,7 @@ export const students = pgTable('students', {
email: text().notNull(), email: text().notNull(),
rollNumber: varchar({ length: 12 }), rollNumber: varchar({ length: 12 }),
verified: boolean().notNull().default(false), verified: boolean().notNull().default(false),
markedOut: boolean().notNull().default(false),
firstName: varchar({ length: 255 }), firstName: varchar({ length: 255 }),
middleName: varchar({ length: 255 }), middleName: varchar({ length: 255 }),
lastName: varchar({ length: 255 }), lastName: varchar({ length: 255 }),

View File

@@ -19,6 +19,7 @@
"@radix-ui/react-select": "^2.2.5", "@radix-ui/react-select": "^2.2.5",
"@radix-ui/react-separator": "^1.1.7", "@radix-ui/react-separator": "^1.1.7",
"@radix-ui/react-slot": "^1.2.3", "@radix-ui/react-slot": "^1.2.3",
"@radix-ui/react-switch": "^1.2.5",
"class-variance-authority": "^0.7.1", "class-variance-authority": "^0.7.1",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"date-fns": "^4.1.0", "date-fns": "^4.1.0",

View File

@@ -43,10 +43,7 @@ const DialogContent = React.forwardRef<
{...props} {...props}
> >
{children} {children}
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground"> {/* Removed default close button to avoid duplicate X buttons */}
<span className="text-2xl font-thin" aria-hidden="true">×</span>
<span className="sr-only">Close</span>
</DialogPrimitive.Close>
</DialogPrimitive.Content> </DialogPrimitive.Content>
</DialogPortal> </DialogPortal>
)) ))

View File

@@ -0,0 +1,31 @@
"use client"
import * as React from "react"
import * as SwitchPrimitive from "@radix-ui/react-switch"
import { cn } from "@workspace/ui/lib/utils"
function Switch({
className,
...props
}: React.ComponentProps<typeof SwitchPrimitive.Root>) {
return (
<SwitchPrimitive.Root
data-slot="switch"
className={cn(
"peer data-[state=checked]:bg-red-600 data-[state=unchecked]:bg-input focus-visible:border-ring focus-visible:ring-ring/50 dark:data-[state=unchecked]:bg-input/80 inline-flex h-[1.15rem] w-8 shrink-0 items-center rounded-full border border-transparent shadow-xs transition-all outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
className
)}
{...props}
>
<SwitchPrimitive.Thumb
data-slot="switch-thumb"
className={cn(
"bg-background dark:data-[state=unchecked]:bg-foreground dark:data-[state=checked]:bg-primary-foreground pointer-events-none block size-4 rounded-full ring-0 transition-transform data-[state=checked]:translate-x-[calc(100%-2px)] data-[state=unchecked]:translate-x-0"
)}
/>
</SwitchPrimitive.Root>
)
}
export { Switch }

31
pnpm-lock.yaml generated
View File

@@ -280,6 +280,9 @@ importers:
'@radix-ui/react-slot': '@radix-ui/react-slot':
specifier: ^1.2.3 specifier: ^1.2.3
version: 1.2.3(@types/react@19.1.8)(react@19.1.0) version: 1.2.3(@types/react@19.1.8)(react@19.1.0)
'@radix-ui/react-switch':
specifier: ^1.2.5
version: 1.2.5(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
class-variance-authority: class-variance-authority:
specifier: ^0.7.1 specifier: ^0.7.1
version: 0.7.1 version: 0.7.1
@@ -1292,6 +1295,19 @@ packages:
'@types/react': '@types/react':
optional: true optional: true
'@radix-ui/react-switch@1.2.5':
resolution: {integrity: sha512-5ijLkak6ZMylXsaImpZ8u4Rlf5grRmoc0p0QeX9VJtlrM4f5m3nCTX8tWga/zOA8PZYIR/t0p2Mnvd7InrJ6yQ==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
peerDependenciesMeta:
'@types/react':
optional: true
'@types/react-dom':
optional: true
'@radix-ui/react-use-callback-ref@1.1.1': '@radix-ui/react-use-callback-ref@1.1.1':
resolution: {integrity: sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==} resolution: {integrity: sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==}
peerDependencies: peerDependencies:
@@ -4468,6 +4484,21 @@ snapshots:
optionalDependencies: optionalDependencies:
'@types/react': 19.1.8 '@types/react': 19.1.8
'@radix-ui/react-switch@1.2.5(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)':
dependencies:
'@radix-ui/primitive': 1.1.2
'@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.8)(react@19.1.0)
'@radix-ui/react-context': 1.1.2(@types/react@19.1.8)(react@19.1.0)
'@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
'@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.8)(react@19.1.0)
'@radix-ui/react-use-previous': 1.1.1(@types/react@19.1.8)(react@19.1.0)
'@radix-ui/react-use-size': 1.1.1(@types/react@19.1.8)(react@19.1.0)
react: 19.1.0
react-dom: 19.1.0(react@19.1.0)
optionalDependencies:
'@types/react': 19.1.8
'@types/react-dom': 19.1.6(@types/react@19.1.8)
'@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.1.8)(react@19.1.0)': '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.1.8)(react@19.1.0)':
dependencies: dependencies:
react: 19.1.0 react: 19.1.0