169 lines
5.4 KiB
TypeScript
169 lines
5.4 KiB
TypeScript
// app/actions/admin.ts
|
|
|
|
"use server";
|
|
|
|
import prisma from "../../lib/prisma";
|
|
import { unstable_noStore as noStore } from "next/cache";
|
|
|
|
// ==========================================
|
|
// 1. FETCH DATA
|
|
// ==========================================
|
|
|
|
export async function getAdminData() {
|
|
noStore(); // CRITICAL: Tells Next.js to NEVER cache this response
|
|
|
|
return await prisma.period.findMany({
|
|
include: {
|
|
youths: {
|
|
include: {
|
|
attendance: true
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
export async function getDailyLogsDb() {
|
|
noStore();
|
|
return await prisma.dailyLog.findMany();
|
|
}
|
|
|
|
// ==========================================
|
|
// 2. PERIOD ACTIONS
|
|
// ==========================================
|
|
|
|
export async function createPeriodDb(name: string, startDate: string, endDate: string) {
|
|
const newPeriod = await prisma.period.create({
|
|
data: { name, startDate, endDate }
|
|
});
|
|
return newPeriod;
|
|
}
|
|
|
|
export async function deletePeriodDb(periodId: string) {
|
|
const youths = await prisma.youth.findMany({ where: { periodId } });
|
|
const youthIds = youths.map(y => y.id);
|
|
|
|
if (youthIds.length > 0) {
|
|
await prisma.attendance.deleteMany({
|
|
where: { youthId: { in: youthIds } }
|
|
});
|
|
}
|
|
|
|
await prisma.youth.deleteMany({
|
|
where: { periodId }
|
|
});
|
|
|
|
await prisma.period.delete({
|
|
where: { id: periodId }
|
|
});
|
|
|
|
return { success: true };
|
|
}
|
|
|
|
// ==========================================
|
|
// 3. YOUTH ACTIONS
|
|
// ==========================================
|
|
|
|
export async function bulkAddYouthDb(periodId: string, youthData: { name: string, team: string }[]) {
|
|
await prisma.youth.createMany({
|
|
data: youthData.map(y => ({
|
|
name: y.name,
|
|
team: y.team,
|
|
periodId: periodId
|
|
}))
|
|
});
|
|
return { success: true };
|
|
}
|
|
|
|
export async function removeYouthDb(youthId: string) {
|
|
await prisma.attendance.deleteMany({
|
|
where: { youthId }
|
|
});
|
|
|
|
await prisma.youth.delete({
|
|
where: { id: youthId }
|
|
});
|
|
|
|
return { success: true };
|
|
}
|
|
|
|
// ==========================================
|
|
// 4. ATTENDANCE & LOG ACTIONS
|
|
// ==========================================
|
|
|
|
export async function setAttendanceDb(date: string, youthId: string, shiftId: string, hoursWorked: number, weightedHours: number, status: string, note: string) {
|
|
await prisma.attendance.upsert({
|
|
where: { date_youthId_shiftId: { date, youthId, shiftId } },
|
|
update: { hoursWorked, weightedHours, status, note },
|
|
create: { date, youthId, shiftId, hoursWorked, weightedHours, status, note }
|
|
});
|
|
return { success: true };
|
|
}
|
|
|
|
export async function removeAttendanceDb(date: string, youthId: string, shiftId: string) {
|
|
await prisma.attendance.delete({
|
|
where: { date_youthId_shiftId: { date, youthId, shiftId } }
|
|
}).catch(() => { /* Ignore if it doesn't exist */ });
|
|
return { success: true };
|
|
}
|
|
|
|
export async function bulkSetAttendanceDb(records: { date: string; youthId: string; shiftId: string; hoursWorked: number; weightedHours: number; status: string; note: string }[]) {
|
|
await prisma.$transaction(
|
|
records.map(record =>
|
|
prisma.attendance.upsert({
|
|
where: { date_youthId_shiftId: { date: record.date, youthId: record.youthId, shiftId: record.shiftId } },
|
|
update: { hoursWorked: record.hoursWorked, weightedHours: record.weightedHours, status: record.status, note: record.note },
|
|
create: { date: record.date, youthId: record.youthId, shiftId: record.shiftId, hoursWorked: record.hoursWorked, weightedHours: record.weightedHours, status: record.status, note: record.note }
|
|
})
|
|
)
|
|
);
|
|
return { success: true };
|
|
}
|
|
|
|
export async function setDailyLogDb(date: string, content: string) {
|
|
await prisma.dailyLog.upsert({
|
|
where: { date },
|
|
update: { content },
|
|
create: { date, content }
|
|
});
|
|
return { success: true };
|
|
}
|
|
|
|
// ==========================================
|
|
// 5. AUTHENTICATION ACTIONS
|
|
// ==========================================
|
|
|
|
export async function getLoginUsers() {
|
|
noStore();
|
|
return await prisma.user.findMany({
|
|
select: { id: true, name: true, role: true }
|
|
});
|
|
}
|
|
|
|
export async function verifyLogin(username: string, pin: string) {
|
|
noStore();
|
|
const users = await prisma.user.findMany();
|
|
const user = users.find(u => u.name.toLowerCase() === username.toLowerCase().trim());
|
|
|
|
if (user && user.pin === pin) {
|
|
return { success: true, user: { id: user.id, name: user.name, role: user.role } };
|
|
}
|
|
return { success: false, user: null };
|
|
}
|
|
|
|
// ==========================================
|
|
// 6. OFFLINE SYNC ACTIONS
|
|
// ==========================================
|
|
|
|
export async function syncOfflineQueueDb(queue: any[]) {
|
|
for (const action of queue) {
|
|
if (action.type === 'SET_ATTENDANCE') {
|
|
await setAttendanceDb(action.payload.date, action.payload.youthId, action.payload.shiftId, action.payload.hoursWorked, action.payload.weightedHours, action.payload.status, action.payload.note);
|
|
} else if (action.type === 'REMOVE_ATTENDANCE') {
|
|
await removeAttendanceDb(action.payload.date, action.payload.youthId, action.payload.shiftId);
|
|
} else if (action.type === 'SET_DAILY_LOG') {
|
|
await setDailyLogDb(action.payload.date, action.payload.content);
|
|
}
|
|
}
|
|
return { success: true };
|
|
} |