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}
+
+ )}
+
+
-
+
+ {/* 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;