63 lines
2.3 KiB
TypeScript
63 lines
2.3 KiB
TypeScript
import type { PageServerLoad, Actions } from './$types';
|
|
import { db } from '$lib/server/db';
|
|
import { donations, pets } from '$lib/server/schema';
|
|
import { error, fail, redirect } from '@sveltejs/kit';
|
|
import { logAudit } from '$lib/server/audit';
|
|
import { hasPermission } from '$lib/roles';
|
|
import type { Role } from '$lib/roles';
|
|
|
|
export const load: PageServerLoad = async ({ locals }) => {
|
|
if (!hasPermission(locals.user!.role as Role, 'donations')) error(403, 'Access denied');
|
|
const petList = await db.select({ id: pets.id, name: pets.name }).from(pets).orderBy(pets.name);
|
|
return { pets: petList };
|
|
};
|
|
|
|
export const actions: Actions = {
|
|
default: async ({ request, locals }) => {
|
|
if (!hasPermission(locals.user!.role as Role, 'donations')) error(403, 'Access denied');
|
|
const fd = await request.formData();
|
|
|
|
const source = fd.get('source')?.toString() ?? '';
|
|
const amountStr = fd.get('amount')?.toString().trim() ?? '';
|
|
const donorName = fd.get('donorName')?.toString().trim() || null;
|
|
const donorEmail = fd.get('donorEmail')?.toString().trim() || null;
|
|
const petId = fd.get('petId')?.toString() ? parseInt(fd.get('petId') as string, 10) : null;
|
|
const isRecurring = fd.get('isRecurring') === 'on';
|
|
const notes = fd.get('notes')?.toString().trim() || null;
|
|
const purpose = fd.get('purpose')?.toString().trim() || null;
|
|
|
|
const validSources = ['stripe', 'paypal', 'venmo', 'givebutter', 'cash', 'check', 'zelle', 'google_pay', 'square', 'other'];
|
|
if (!validSources.includes(source)) {
|
|
return fail(400, { error: 'Please select a valid source', values: Object.fromEntries(fd) });
|
|
}
|
|
|
|
const parsedAmount = parseFloat(amountStr);
|
|
if (!amountStr || isNaN(parsedAmount) || parsedAmount <= 0) {
|
|
return fail(400, { error: 'Amount must be a positive number', values: Object.fromEntries(fd) });
|
|
}
|
|
|
|
const amountCents = Math.round(parsedAmount * 100);
|
|
|
|
const [result] = await db.insert(donations).values({
|
|
source: source as typeof donations.source.enumValues[number],
|
|
amount: amountCents,
|
|
donorName,
|
|
donorEmail,
|
|
petId,
|
|
isRecurring,
|
|
notes,
|
|
purpose
|
|
});
|
|
|
|
await logAudit({
|
|
userId: locals.user!.id,
|
|
action: 'create_donation',
|
|
entity: 'donation',
|
|
entityId: result.insertId,
|
|
diff: { source, amount: parsedAmount, donorName }
|
|
});
|
|
|
|
redirect(303, '/admin/donations');
|
|
}
|
|
};
|