From 59f9c356ad5b00d4465641d412ae49423f4b1de3 Mon Sep 17 00:00:00 2001 From: Om Lanke Date: Sat, 5 Jul 2025 21:08:14 +0530 Subject: [PATCH] markout n shit --- apps/admin/app/(main)/students/columns.tsx | 68 +- apps/admin/app/(main)/students/data-table.tsx | 7 +- apps/admin/app/(main)/students/page.tsx | 33 +- .../(main)/students/student-details-modal.tsx | 54 +- packages/db/migrations/0007_fuzzy_zuras.sql | 1 + .../db/migrations/meta/0007_snapshot.json | 776 ++++++++++++++++++ packages/db/migrations/meta/_journal.json | 7 + packages/db/schema.ts | 1 + packages/ui/package.json | 1 + packages/ui/src/components/dialog.tsx | 7 +- packages/ui/src/components/switch.tsx | 31 + pnpm-lock.yaml | 31 + 12 files changed, 951 insertions(+), 66 deletions(-) create mode 100644 packages/db/migrations/0007_fuzzy_zuras.sql create mode 100644 packages/db/migrations/meta/0007_snapshot.json create mode 100644 packages/ui/src/components/switch.tsx diff --git a/apps/admin/app/(main)/students/columns.tsx b/apps/admin/app/(main)/students/columns.tsx index 908ae0e..4082817 100644 --- a/apps/admin/app/(main)/students/columns.tsx +++ b/apps/admin/app/(main)/students/columns.tsx @@ -1,39 +1,47 @@ import { ColumnDef } from '@tanstack/react-table'; -// Remove server-specific imports to avoid issues in client bundle -// import { createSelectSchema, students } from '@workspace/db'; -// import * as z from 'zod/v4'; +import { students, internships, resumes, grades } from '@workspace/db/schema'; import { Badge } from '@workspace/ui/components/badge'; // import { Button } from '@workspace/ui/components/button'; import { Avatar, AvatarFallback, AvatarImage } from '@workspace/ui/components/avatar'; import { Eye, Mail, Phone, MapPin, Calendar, GraduationCap } from 'lucide-react'; -// Define the Student interface locally to avoid importing server-side code -export interface Student { - id: number; - email: string; - rollNumber: string | null; - verified: boolean; - firstName: string | null; - middleName: string | null; - lastName: string | null; - mothersName?: string | null; - gender?: string | null; - dob?: Date | null; - personalGmail?: string | null; - phoneNumber?: string | null; - address?: string | null; - 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; -} +type SelectStudent = typeof students.$inferSelect +type SelectInternships = typeof internships.$inferSelect +type SelectResume = typeof resumes.$inferSelect +type SelectGrades = typeof grades.$inferSelect + +export type Student = SelectStudent & { + internships: SelectInternships[]; + resumes: SelectResume[]; + grades: SelectGrades[]; +}; + +// export interface Student { +// id: number; +// email: string; +// rollNumber: string | null; +// verified: boolean; +// firstName: string | null; +// middleName: string | null; +// lastName: string | null; +// mothersName?: string | null; +// gender?: string | null; +// dob?: Date | null; +// personalGmail?: string | null; +// phoneNumber?: string | null; +// address?: string | null; +// 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[] = [ { diff --git a/apps/admin/app/(main)/students/data-table.tsx b/apps/admin/app/(main)/students/data-table.tsx index 46e8b66..66470ea 100644 --- a/apps/admin/app/(main)/students/data-table.tsx +++ b/apps/admin/app/(main)/students/data-table.tsx @@ -2,7 +2,6 @@ import { useState } from 'react'; import { - ColumnDef, flexRender, getCoreRowModel, getPaginationRowModel, @@ -23,9 +22,10 @@ import { columns } from './columns'; interface DataTableProps { data: Student[]; + markoutAction: (id: number, state: boolean) => void; } -export function DataTable({ data }: DataTableProps) { +export function DataTable({ data, markoutAction }: DataTableProps) { const [selectedStudent, setSelectedStudent] = useState(null); const [isModalOpen, setIsModalOpen] = useState(false); @@ -122,6 +122,9 @@ export function DataTable({ data }: DataTableProps) { student={selectedStudent} isOpen={isModalOpen} onClose={handleCloseModal} + markoutAction={(state: boolean) => { + markoutAction(selectedStudent.id, state); + }} /> )} diff --git a/apps/admin/app/(main)/students/page.tsx b/apps/admin/app/(main)/students/page.tsx index ec78791..9226fac 100644 --- a/apps/admin/app/(main)/students/page.tsx +++ b/apps/admin/app/(main)/students/page.tsx @@ -6,30 +6,25 @@ import { Button } from '@workspace/ui/components/button'; import { revalidatePath } from 'next/cache'; import { eq } from '@workspace/db/drizzle'; 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 { Users, Plus, Search, Filter, Download, - Mail, - Phone, - MapPin, - Calendar, - GraduationCap, User, - Linkedin, - Github, - FileText, - Award, - BookOpen } from 'lucide-react'; async function getData(): Promise { 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; } catch (error) { console.error('Database error:', error); @@ -49,6 +44,16 @@ async function addStudent(formData: FormData) { 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() { const data = await getData(); @@ -194,7 +199,7 @@ async function StudentsTable() { ) : ( - + )} diff --git a/apps/admin/app/(main)/students/student-details-modal.tsx b/apps/admin/app/(main)/students/student-details-modal.tsx index f90b128..34224fb 100644 --- a/apps/admin/app/(main)/students/student-details-modal.tsx +++ b/apps/admin/app/(main)/students/student-details-modal.tsx @@ -1,11 +1,13 @@ 'use client'; +import React from 'react'; import { Student } from './columns'; import { Dialog, DialogContent, DialogHeader, DialogTitle, + DialogClose, } from '@workspace/ui/components/dialog'; import { Badge } from '@workspace/ui/components/badge'; import { Avatar, AvatarFallback, AvatarImage } from '@workspace/ui/components/avatar'; @@ -20,7 +22,6 @@ import { User, Linkedin, Github, - FileText, Award, BookOpen, ExternalLink, @@ -29,14 +30,16 @@ import { Download, Share2 } from 'lucide-react'; +import { Switch } from '@workspace/ui/components/switch'; interface StudentDetailsModalProps { student: Student; isOpen: boolean; onClose: () => void; + markoutAction: (state: boolean) => void; } -export function StudentDetailsModal({ student, isOpen, onClose }: StudentDetailsModalProps) { +export function StudentDetailsModal({ student, isOpen, onClose, markoutAction }: StudentDetailsModalProps) { const fullName = [ student.firstName, student.middleName, @@ -57,6 +60,17 @@ export function StudentDetailsModal({ student, isOpen, onClose }: StudentDetails 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 ( @@ -65,14 +79,28 @@ export function StudentDetailsModal({ student, isOpen, onClose }: StudentDetails Student Details - +
+
+ + + Marked Out + +
+ + + +
@@ -319,13 +347,9 @@ export function StudentDetailsModal({ student, isOpen, onClose }: StudentDetails -
); -} \ No newline at end of file +} \ No newline at end of file diff --git a/packages/db/migrations/0007_fuzzy_zuras.sql b/packages/db/migrations/0007_fuzzy_zuras.sql new file mode 100644 index 0000000..608e406 --- /dev/null +++ b/packages/db/migrations/0007_fuzzy_zuras.sql @@ -0,0 +1 @@ +ALTER TABLE "students" ADD COLUMN "markedOut" boolean DEFAULT false NOT NULL; \ No newline at end of file diff --git a/packages/db/migrations/meta/0007_snapshot.json b/packages/db/migrations/meta/0007_snapshot.json new file mode 100644 index 0000000..fa0657c --- /dev/null +++ b/packages/db/migrations/meta/0007_snapshot.json @@ -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": {} + } +} \ No newline at end of file diff --git a/packages/db/migrations/meta/_journal.json b/packages/db/migrations/meta/_journal.json index c42f81e..a2e7095 100644 --- a/packages/db/migrations/meta/_journal.json +++ b/packages/db/migrations/meta/_journal.json @@ -50,6 +50,13 @@ "when": 1751619273079, "tag": "0006_mysterious_lionheart", "breakpoints": true + }, + { + "idx": 7, + "version": "7", + "when": 1751727461248, + "tag": "0007_fuzzy_zuras", + "breakpoints": true } ] } \ No newline at end of file diff --git a/packages/db/schema.ts b/packages/db/schema.ts index 914b00b..bee1f61 100644 --- a/packages/db/schema.ts +++ b/packages/db/schema.ts @@ -19,6 +19,7 @@ export const students = pgTable('students', { email: text().notNull(), rollNumber: varchar({ length: 12 }), verified: boolean().notNull().default(false), + markedOut: boolean().notNull().default(false), firstName: varchar({ length: 255 }), middleName: varchar({ length: 255 }), lastName: varchar({ length: 255 }), diff --git a/packages/ui/package.json b/packages/ui/package.json index fd2241f..42cc696 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -19,6 +19,7 @@ "@radix-ui/react-select": "^2.2.5", "@radix-ui/react-separator": "^1.1.7", "@radix-ui/react-slot": "^1.2.3", + "@radix-ui/react-switch": "^1.2.5", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "date-fns": "^4.1.0", diff --git a/packages/ui/src/components/dialog.tsx b/packages/ui/src/components/dialog.tsx index 3778102..ef0a04c 100644 --- a/packages/ui/src/components/dialog.tsx +++ b/packages/ui/src/components/dialog.tsx @@ -43,10 +43,7 @@ const DialogContent = React.forwardRef< {...props} > {children} - - - Close - + {/* Removed default close button to avoid duplicate X buttons */} )) @@ -118,4 +115,4 @@ export { DialogFooter, DialogTitle, DialogDescription, -} \ No newline at end of file +} \ No newline at end of file diff --git a/packages/ui/src/components/switch.tsx b/packages/ui/src/components/switch.tsx new file mode 100644 index 0000000..7b87e74 --- /dev/null +++ b/packages/ui/src/components/switch.tsx @@ -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) { + return ( + + + + ) +} + +export { Switch } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 939b71b..64af9aa 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -280,6 +280,9 @@ importers: '@radix-ui/react-slot': specifier: ^1.2.3 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: specifier: ^0.7.1 version: 0.7.1 @@ -1292,6 +1295,19 @@ packages: '@types/react': 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': resolution: {integrity: sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==} peerDependencies: @@ -4468,6 +4484,21 @@ snapshots: optionalDependencies: '@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)': dependencies: react: 19.1.0