added admin dashboard
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
import type { Actions, PageServerLoad } from './$types';
|
||||
import { fail } from '@sveltejs/kit';
|
||||
import { writeFileSync, mkdirSync, existsSync, unlinkSync } from 'node:fs';
|
||||
import { join } from 'node:path';
|
||||
import { randomUUID } from 'node:crypto';
|
||||
import {
|
||||
addTestimonial,
|
||||
deleteTestimonial,
|
||||
getContent,
|
||||
updateTestimonial
|
||||
} from '$lib/server/content';
|
||||
|
||||
const UPLOAD_DIR = join(process.cwd(), 'static', 'img', 'uploads');
|
||||
const MAX_BYTES = 4 * 1024 * 1024;
|
||||
const ALLOWED = new Set(['image/png', 'image/jpeg', 'image/webp']);
|
||||
|
||||
export const load: PageServerLoad = () => {
|
||||
return { testimonials: getContent().testimonials };
|
||||
};
|
||||
|
||||
function extFromType(type: string): string {
|
||||
if (type === 'image/png') return 'png';
|
||||
if (type === 'image/webp') return 'webp';
|
||||
return 'jpg';
|
||||
}
|
||||
|
||||
async function saveAvatar(file: File): Promise<string> {
|
||||
if (!existsSync(UPLOAD_DIR)) mkdirSync(UPLOAD_DIR, { recursive: true });
|
||||
const buf = Buffer.from(await file.arrayBuffer());
|
||||
const ext = extFromType(file.type);
|
||||
const filename = `avatar-${randomUUID().slice(0, 8)}.${ext}`;
|
||||
writeFileSync(join(UPLOAD_DIR, filename), buf);
|
||||
return `/img/uploads/${filename}`;
|
||||
}
|
||||
|
||||
function removePrevAvatar(src: string | undefined): void {
|
||||
if (!src?.startsWith('/img/uploads/')) return;
|
||||
const full = join(process.cwd(), 'static', src);
|
||||
try {
|
||||
if (existsSync(full)) unlinkSync(full);
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
export const actions: Actions = {
|
||||
add: async ({ request }) => {
|
||||
const form = await request.formData();
|
||||
const text = String(form.get('text') ?? '').trim();
|
||||
const name = String(form.get('name') ?? '').trim();
|
||||
const role = String(form.get('role') ?? '').trim();
|
||||
const avatarAlt = String(form.get('avatarAlt') ?? '').trim() || name;
|
||||
const file = form.get('avatar');
|
||||
|
||||
if (!text || !name) return fail(400, { error: 'Testimonianza e nome sono obbligatori.' });
|
||||
|
||||
let avatarSrc = '/img/logo.png';
|
||||
if (file instanceof File && file.size) {
|
||||
if (file.size > MAX_BYTES) return fail(400, { error: 'Avatar troppo grande (max 4 MB).' });
|
||||
if (file.type && !ALLOWED.has(file.type)) return fail(400, { error: `Formato non supportato: ${file.type}.` });
|
||||
avatarSrc = await saveAvatar(file);
|
||||
}
|
||||
|
||||
const entry = addTestimonial({ text, name, role, avatarSrc, avatarAlt });
|
||||
return { success: true, added: entry.id };
|
||||
},
|
||||
|
||||
update: async ({ request }) => {
|
||||
const form = await request.formData();
|
||||
const id = String(form.get('id') ?? '');
|
||||
const text = String(form.get('text') ?? '').trim();
|
||||
const name = String(form.get('name') ?? '').trim();
|
||||
const role = String(form.get('role') ?? '').trim();
|
||||
const avatarAlt = String(form.get('avatarAlt') ?? '').trim() || name;
|
||||
const file = form.get('avatar');
|
||||
|
||||
if (!id) return fail(400, { error: 'ID mancante.' });
|
||||
if (!text || !name) return fail(400, { error: 'Testimonianza e nome sono obbligatori.' });
|
||||
|
||||
const current = getContent().testimonials.find((t) => t.id === id);
|
||||
let avatarSrc = current?.avatarSrc ?? '/img/logo.png';
|
||||
if (file instanceof File && file.size) {
|
||||
if (file.size > MAX_BYTES) return fail(400, { error: 'Avatar troppo grande (max 4 MB).' });
|
||||
if (file.type && !ALLOWED.has(file.type)) return fail(400, { error: `Formato non supportato: ${file.type}.` });
|
||||
removePrevAvatar(current?.avatarSrc);
|
||||
avatarSrc = await saveAvatar(file);
|
||||
}
|
||||
|
||||
const updated = updateTestimonial(id, { text, name, role, avatarSrc, avatarAlt });
|
||||
if (!updated) return fail(404, { error: 'Testimonianza non trovata.' });
|
||||
return { success: true, updated: id };
|
||||
},
|
||||
|
||||
delete: async ({ request }) => {
|
||||
const form = await request.formData();
|
||||
const id = String(form.get('id') ?? '');
|
||||
if (!id) return fail(400, { error: 'ID mancante.' });
|
||||
const current = getContent().testimonials.find((t) => t.id === id);
|
||||
removePrevAvatar(current?.avatarSrc);
|
||||
deleteTestimonial(id);
|
||||
return { success: true, deleted: id };
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user