Files
app/app/actions/admin.ts
T

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 };
}