This commit is contained in:
Bastien COIGNOUX
2025-07-14 18:03:29 +02:00
parent 9fad10e7b7
commit 1439d33584
3 changed files with 152 additions and 6 deletions

Binary file not shown.

View File

@ -0,0 +1,72 @@
import { json } from '@sveltejs/kit';
import db from '$lib/server/db';
export async function POST({ request }) {
const body = await request.json();
try {
if (Array.isArray(body)) {
if (body.length > 1) {
// Cas dun import CSV → remplacement total
const insert = db.prepare(`
INSERT INTO resource_planning (ressource, profil, date, disponibilite)
VALUES (@ressource, @profil, @date, @disponibilite)
`);
const clear = db.prepare(`DELETE FROM resource_planning`);
const transaction = db.transaction((data: any[]) => {
clear.run();
for (const entry of data) {
insert.run(entry);
}
});
transaction(body);
} else if (body.length === 1) {
// Cas d'une modif manuelle → update ou insert
const { ressource, profil, date, disponibilite } = body[0];
const existing = db.prepare(`
SELECT id FROM resource_planning
WHERE ressource = ? AND profil = ? AND date = ?
`).get(ressource, profil, date);
if (existing) {
db.prepare(`
UPDATE resource_planning
SET disponibilite = ?
WHERE id = ?
`).run(disponibilite, existing.id);
} else {
db.prepare(`
INSERT INTO resource_planning (ressource, profil, date, disponibilite)
VALUES (?, ?, ?, ?)
`).run(ressource, profil, date, disponibilite);
}
}
}
return json({ success: true });
} catch (e) {
console.error('Erreur POST /api/planning', e);
return json({ success: false, error: e.message }, { status: 500 });
}
}
export async function GET() {
const rows = db.prepare(`SELECT * FROM resource_planning`).all();
const grouped = new Map();
for (const row of rows) {
const key = `${row.ressource}|${row.profil}`;
if (!grouped.has(key)) {
grouped.set(key, {
ressource: row.ressource,
profil: row.profil,
disponibilites: {}
});
}
grouped.get(key).disponibilites[row.date] = row.disponibilite;
}
return json(Array.from(grouped.values()));
}

View File

@ -1,5 +1,6 @@
<script lang="ts">
import Papa from 'papaparse';
import { onMount } from 'svelte';
import { writable, get } from 'svelte/store';
const planning = writable<any[]>([]);
@ -7,6 +8,9 @@
let file: File | null = null;
const saveMessage = writable('');
let timeout: ReturnType<typeof setTimeout>;
const joursFeries = [
'2025-01-01', '2025-04-21', '2025-05-01', '2025-05-08', '2025-05-29',
'2025-07-14', '2025-08-15', '2025-11-01', '2025-11-11', '2025-12-25'
@ -30,31 +34,76 @@
});
}
function handleFileUpload() {
function showSaveMessage(message: string = '✅ Sauvegarde enregistrée') {
saveMessage.set(message);
clearTimeout(timeout);
timeout = setTimeout(() => saveMessage.set(''), 2000);
}
onMount(async () => {
const res = await fetch('/api/planning');
if (res.ok) {
const data = await res.json();
if (data.length) {
const allDates = new Set<string>();
data.forEach(row => {
Object.keys(row.disponibilites).forEach(d => allDates.add(d));
});
const sortedDates = Array.from(allDates).sort();
dates.set(sortedDates);
planning.set(data);
}
}
});
async function handleFileUpload() {
if (!file) return;
Papa.parse(file, {
header: true,
skipEmptyLines: true,
complete: (result) => {
complete: async (result) => {
const rows = result.data as any[];
const colonnesDates = Object.keys(rows[0]).filter(k => /^\d/.test(k));
dates.set(colonnesDates);
planning.set(rows.map(row => ({
const structured = rows.map(row => ({
ressource: row.ressource,
profil: row.profil,
disponibilites: colonnesDates.reduce((acc, date) => {
acc[date] = parseFloat(row[date] || 0);
return acc;
}, {} as Record<string, number>)
})));
}));
planning.set(structured);
const payload = [];
for (const row of structured) {
for (const date of colonnesDates) {
payload.push({
ressource: row.ressource,
profil: row.profil,
date,
disponibilite: row.disponibilites[date]
});
}
}
await fetch('/api/planning', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
showSaveMessage();
}
});
}
function updateCell(rowIndex: number, date: string, value: string) {
async function updateCell(rowIndex: number, date: string, value: string) {
const val = parseFloat(value);
if (![0, 0.5, 1].includes(val)) return;
@ -62,6 +111,23 @@
current[rowIndex].disponibilites[date] = val;
return current;
});
const row = get(planning)[rowIndex];
await fetch('/api/planning', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify([
{
ressource: row.ressource,
profil: row.profil,
date,
disponibilite: val
}
])
});
showSaveMessage();
}
function totalByDate(date: string) {
@ -125,3 +191,11 @@
</tfoot>
</table>
{/if}
{#if $saveMessage}
<div
class="fixed bottom-4 right-4 bg-green-600 text-white px-4 py-2 rounded shadow-lg transition-opacity duration-300"
>
{$saveMessage}
</div>
{/if}