From 4cb05ce79f7e1df7b7603bdeb6b710d94d782747 Mon Sep 17 00:00:00 2001 From: bediakopatrick054-afk Date: Wed, 11 Mar 2026 17:47:53 +0000 Subject: [PATCH] Update page.tsx --- src/app/(dashboard)/list/assignments/page.tsx | 326 +++++++++++++----- 1 file changed, 236 insertions(+), 90 deletions(-) diff --git a/src/app/(dashboard)/list/assignments/page.tsx b/src/app/(dashboard)/list/assignments/page.tsx index f615061a..ade8fef0 100644 --- a/src/app/(dashboard)/list/assignments/page.tsx +++ b/src/app/(dashboard)/list/assignments/page.tsx @@ -4,41 +4,43 @@ import Table from "@/components/Table"; import TableSearch from "@/components/TableSearch"; import prisma from "@/lib/prisma"; import { ITEM_PER_PAGE } from "@/lib/settings"; -import { Assignment, Class, Prisma, Subject, Teacher } from "@prisma/client"; +import { OutreachProgram, Ministry, CellGroup, Pastor, Prisma } from "@prisma/client"; import Image from "next/image"; import { auth } from "@clerk/nextjs/server"; -type AssignmentList = Assignment & { - lesson: { - subject: Subject; - class: Class; - teacher: Teacher; - }; +type OutreachProgramList = OutreachProgram & { + ministry: Ministry | null; + cellGroup: CellGroup | null; + leader: Pastor | null; }; -const AssignmentListPage = async ({ +const OutreachProgramListPage = async ({ searchParams, }: { searchParams: { [key: string]: string | undefined }; }) => { - const { userId, sessionClaims } = auth(); const role = (sessionClaims?.metadata as { role?: string })?.role; const currentUserId = userId; - const columns = [ { - header: "Subject Name", + header: "Program Name", accessor: "name", }, { - header: "Class", - accessor: "class", + header: "Ministry", + accessor: "ministry", + className: "hidden lg:table-cell", + }, + { + header: "Cell Group", + accessor: "cellGroup", + className: "hidden lg:table-cell", }, { - header: "Teacher", - accessor: "teacher", + header: "Leader", + accessor: "leader", className: "hidden md:table-cell", }, { @@ -46,7 +48,17 @@ const AssignmentListPage = async ({ accessor: "dueDate", className: "hidden md:table-cell", }, - ...(role === "admin" || role === "teacher" + { + header: "Location", + accessor: "location", + className: "hidden xl:table-cell", + }, + { + header: "Status", + accessor: "status", + className: "hidden xl:table-cell", + }, + ...(role === "admin" || role === "super_admin" || role === "pastor" || role === "evangelismLeader" ? [ { header: "Actions", @@ -56,56 +68,131 @@ const AssignmentListPage = async ({ : []), ]; - const renderRow = (item: AssignmentList) => ( - - {item.lesson.subject.name} - {item.lesson.class.name} - - {item.lesson.teacher.name + " " + item.lesson.teacher.surname} - - - {new Intl.DateTimeFormat("en-US").format(item.dueDate)} - - -
- {(role === "admin" || role === "teacher") && ( - <> - - - - )} -
- - - ); + const renderRow = (item: OutreachProgramList) => { + // Format date + const formatDate = (date: Date) => { + return new Intl.DateTimeFormat("en-US", { + month: 'short', + day: 'numeric', + year: 'numeric' + }).format(date); + }; + + // Determine if program is upcoming, ongoing, or past due + const today = new Date(); + const dueDate = new Date(item.dueDate); + const daysUntilDue = Math.ceil((dueDate.getTime() - today.getTime()) / (1000 * 3600 * 24)); + + let statusText = ""; + let statusColor = ""; + + if (daysUntilDue < 0) { + statusText = "Past Due"; + statusColor = "bg-red-100 text-red-700"; + } else if (daysUntilDue <= 7) { + statusText = "Urgent"; + statusColor = "bg-orange-100 text-orange-700"; + } else if (daysUntilDue <= 30) { + statusText = "Upcoming"; + statusColor = "bg-green-100 text-green-700"; + } else { + statusText = "Planning"; + statusColor = "bg-blue-100 text-blue-700"; + } + + return ( + + +
+

{item.title}

+

+ {formatDate(item.dueDate)} • {item.location || "TBD"} +

+
+ + + {item.ministry ? ( + + {item.ministry.name} + + ) : "—"} + + + {item.cellGroup ? ( + + {item.cellGroup.name} + + ) : "—"} + + + {item.leader ? ( +
+

{item.leader.name} {item.leader.surname}

+

Leader

+
+ ) : "—"} + + +
+

{formatDate(item.dueDate)}

+ {daysUntilDue >= 0 && daysUntilDue <= 30 && ( +

{daysUntilDue} days left

+ )} +
+ + + {item.location || "TBD"} + + + + {statusText} + + + +
+ {(role === "admin" || role === "super_admin" || role === "pastor" || role === "evangelismLeader") && ( + <> + + + + )} +
+ + + ); + }; const { page, ...queryParams } = searchParams; const p = page ? parseInt(page) : 1; // URL PARAMS CONDITION - - const query: Prisma.AssignmentWhereInput = {}; - - query.lesson = {}; + const query: Prisma.OutreachProgramWhereInput = {}; if (queryParams) { for (const [key, value] of Object.entries(queryParams)) { if (value !== undefined) { switch (key) { - case "classId": - query.lesson.classId = parseInt(value); + case "ministryId": + query.ministryId = parseInt(value); break; - case "teacherId": - query.lesson.teacherId = value; + case "cellGroupId": + query.cellGroupId = parseInt(value); + break; + case "leaderId": + query.leaderId = value; break; case "search": - query.lesson.subject = { - name: { contains: value, mode: "insensitive" }, - }; + query.OR = [ + { title: { contains: value, mode: "insensitive" } }, + { location: { contains: value, mode: "insensitive" } }, + { description: { contains: value, mode: "insensitive" } }, + { ministry: { name: { contains: value, mode: "insensitive" } } }, + { cellGroup: { name: { contains: value, mode: "insensitive" } } }, + ]; break; default: break; @@ -115,81 +202,140 @@ const AssignmentListPage = async ({ } // ROLE CONDITIONS - switch (role) { case "admin": + case "super_admin": break; - case "teacher": - query.lesson.teacherId = currentUserId!; + case "pastor": + // Pastors can see all outreach programs break; - case "student": - query.lesson.class = { - students: { - some: { - id: currentUserId!, - }, - }, + case "evangelismLeader": + // Evangelism leaders see all + break; + case "ministryLeader": + // Ministry leaders see programs from their ministry + query.ministry = { + leaderId: currentUserId! }; break; - case "parent": - query.lesson.class = { - students: { - some: { - parentId: currentUserId!, - }, - }, + case "cellLeader": + // Cell leaders see programs from their cell group + query.cellGroup = { + leaderId: currentUserId! }; break; + case "member": + // Members see programs from their cell group/ministry + query.OR = [ + { cellGroup: { members: { some: { id: currentUserId! } } } }, + { ministry: { members: { some: { id: currentUserId! } } } } + ]; + break; default: break; } const [data, count] = await prisma.$transaction([ - prisma.assignment.findMany({ + prisma.outreachProgram.findMany({ where: query, include: { - lesson: { - select: { - subject: { select: { name: true } }, - teacher: { select: { name: true, surname: true } }, - class: { select: { name: true } }, - }, - }, + ministry: { select: { name: true } }, + cellGroup: { select: { name: true } }, + leader: { select: { name: true, surname: true } }, }, take: ITEM_PER_PAGE, skip: ITEM_PER_PAGE * (p - 1), + orderBy: { + dueDate: 'asc', + }, }), - prisma.assignment.count({ where: query }), + prisma.outreachProgram.count({ where: query }), ]); + + // Calculate statistics + const upcomingCount = data.filter(item => new Date(item.dueDate) > new Date()).length; + const urgentCount = data.filter(item => { + const daysUntil = Math.ceil((new Date(item.dueDate).getTime() - new Date().getTime()) / (1000 * 3600 * 24)); + return daysUntil >= 0 && daysUntil <= 7; + }).length; + return (
{/* TOP */}
-

- All Assignments -

+
+

+ Outreach Programs +

+
+ + Total: {count} + + + Upcoming: {upcomingCount} + + {urgentCount > 0 && ( + + Urgent: {urgentCount} + + )} +
+
- - - {role === "admin" || - (role === "teacher" && ( - - ))} + {(role === "admin" || role === "super_admin" || role === "pastor" || role === "evangelismLeader") && ( + + )}
+ + {/* Quick Stats */} +
+
+

Planning

+

+ {data.filter(item => { + const daysUntil = Math.ceil((new Date(item.dueDate).getTime() - new Date().getTime()) / (1000 * 3600 * 24)); + return daysUntil > 30; + }).length} +

+
+
+

Upcoming

+

+ {data.filter(item => { + const daysUntil = Math.ceil((new Date(item.dueDate).getTime() - new Date().getTime()) / (1000 * 3600 * 24)); + return daysUntil > 7 && daysUntil <= 30; + }).length} +

+
+
+

Urgent

+

{urgentCount}

+
+
+

Past Due

+

+ {data.filter(item => new Date(item.dueDate) < new Date()).length} +

+
+
+ {/* LIST */} + {/* PAGINATION */} ); }; -export default AssignmentListPage; +export default OutreachProgramListPage;