From c04505e95defbfd08dec2b9118091bc2c4c91abe Mon Sep 17 00:00:00 2001 From: Clayzxr Date: Tue, 21 Jan 2025 16:46:19 +0100 Subject: [PATCH] Working DB with table promotions --- .../mobility/(_islands)/ConsultStudents.tsx | 92 ++++++++----------- .../mobility/(_islands)/UploadStudents.tsx | 52 ++++------- routes/(apps)/mobility/api/insert_students.ts | 73 +++++++-------- routes/(apps)/mobility/api/promotions.ts | 31 ------- 4 files changed, 87 insertions(+), 161 deletions(-) delete mode 100644 routes/(apps)/mobility/api/promotions.ts diff --git a/routes/(apps)/mobility/(_islands)/ConsultStudents.tsx b/routes/(apps)/mobility/(_islands)/ConsultStudents.tsx index e1a758b..deeb2e6 100644 --- a/routes/(apps)/mobility/(_islands)/ConsultStudents.tsx +++ b/routes/(apps)/mobility/(_islands)/ConsultStudents.tsx @@ -11,83 +11,63 @@ interface Student { lastName: string; email: string; promotionId: number; + promotionName: string; } export default function ConsultStudents() { - const [promotions, setPromotions] = useState([]); - const [studentsByPromotion, setStudentsByPromotion] = useState>({}); + const [data, setData] = useState<{ promotions: Promotion[]; students: Student[] } | null>(null); const [error, setError] = useState(null); useEffect(() => { - const fetchPromotionsAndStudents = async () => { + const fetchData = async () => { try { - const promoResponse = await fetch("/mobility/api/promotions"); - if (!promoResponse.ok) { - throw new Error(`Error fetching promotions: ${promoResponse.statusText}`); + const response = await fetch("/mobility/api/insert_students"); + if (!response.ok) { + throw new Error(`Error fetching data: ${response.statusText}`); } - const promos: Promotion[] = await promoResponse.json(); - setPromotions(promos); - const studentsResponse = await fetch("/mobility/api/insert_students"); - if (!studentsResponse.ok) { - throw new Error(`Error fetching students: ${studentsResponse.statusText}`); - } - const students: Student[] = await studentsResponse.json(); - - const grouped: Record = {}; - for (const student of students) { - if (!grouped[student.promotionId]) { - grouped[student.promotionId] = []; - } - grouped[student.promotionId].push(student); - } - setStudentsByPromotion(grouped); + const result = await response.json(); + setData(result); } catch (err) { - console.error("Error fetching promotions or students:", err); + console.error("Error fetching data:", err); setError("Failed to load data. Please try again later."); } }; - fetchPromotionsAndStudents(); + fetchData(); }, []); return (

Consult Students

{error &&

{error}

} - {promotions.length === 0 ? ( -

No promotions found.

- ) : ( - promotions.map((promo) => ( -
-

Promotion: {promo.name}

- {studentsByPromotion[promo.id]?.length ? ( - - - - - - - + {data?.promotions.map((promo) => ( +
+

Promotion: {promo.name}

+
IDFirst NameLast NameEmail
+ + + + + + + + + + {data.students + .filter((student) => student.promotionId === promo.id) + .map((student) => ( + + + + + - - - {studentsByPromotion[promo.id].map((student) => ( - - - - - - - ))} - -
IDFirst NameLast NameEmail
{student.id}{student.firstName}{student.lastName}{student.email}
{student.id}{student.firstName}{student.lastName}{student.email}
- ) : ( -

No students in this promotion.

- )} -
- )) - )} + ))} + + + + ))}
); } diff --git a/routes/(apps)/mobility/(_islands)/UploadStudents.tsx b/routes/(apps)/mobility/(_islands)/UploadStudents.tsx index 763cdc4..bb9129b 100644 --- a/routes/(apps)/mobility/(_islands)/UploadStudents.tsx +++ b/routes/(apps)/mobility/(_islands)/UploadStudents.tsx @@ -11,18 +11,15 @@ export default function UploadStudents() { if (input.files && input.files.length > 0) { fileData.value = input.files[0]; statusMessage.value = "File selected: " + input.files[0].name; - console.log("File selected:", input.files[0].name); } else { fileData.value = null; statusMessage.value = "No file selected"; } }; - const confirmUpload = () => { - console.log("Confirm Upload"); + const confirmUpload = async () => { if (!fileData.value) { statusMessage.value = "Please select a file before confirming upload."; - console.error("Error: No file selected."); return; } @@ -30,42 +27,31 @@ export default function UploadStudents() { const reader = new FileReader(); reader.onload = async (e) => { - try { - const arrayBuffer = e.target?.result as ArrayBuffer; - const workbook = XLSX.read(arrayBuffer, { type: "array" }); + const arrayBuffer = e.target?.result as ArrayBuffer; + const workbook = XLSX.read(arrayBuffer, { type: "array" }); - for (const sheetName of workbook.SheetNames) { - const sheet = workbook.Sheets[sheetName]; - const data = XLSX.utils.sheet_to_json(sheet, { - header: ["Nom", "Prénom", "Mail"], - range: 1, // Ignorer les en-têtes - }); + for (const sheetName of workbook.SheetNames) { + const sheet = workbook.Sheets[sheetName]; + const data = XLSX.utils.sheet_to_json(sheet, { + header: ["Nom", "Prénom", "Mail"], + range: 1, // Ignorer les en-têtes + }); - console.log(`Data from sheet ${sheetName}:`, data); + const response = await fetch("/mobility/api/insert_students", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ promoName: sheetName, data }), + }); - const response = await fetch("/mobility/api/insert_students", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ promoName: sheetName, data }), - }); - - if (!response.ok) { - throw new Error( - `Failed to insert data for promotion ${sheetName}`, - ); - } + if (!response.ok) { + throw new Error(`Failed to insert data for promotion ${sheetName}`); } - - statusMessage.value = "Data uploaded and inserted successfully!"; - } catch (error) { - console.error("Error processing the file:", error); - statusMessage.value = - "Error processing the file. Please check its format."; } + + statusMessage.value = "Data uploaded and inserted successfully!"; }; - reader.onerror = (e) => { - console.error("FileReader error:", e); + reader.onerror = () => { statusMessage.value = "Error reading the file."; }; diff --git a/routes/(apps)/mobility/api/insert_students.ts b/routes/(apps)/mobility/api/insert_students.ts index 6fac691..d6e5fef 100644 --- a/routes/(apps)/mobility/api/insert_students.ts +++ b/routes/(apps)/mobility/api/insert_students.ts @@ -2,10 +2,19 @@ import { Handlers } from "$fresh/server.ts"; import { Database } from "@db/sqlite"; export const handler: Handlers = { - async GET(_request, context) { + async GET() { try { const db = new Database("databases/data/mobility.db"); + db.prepare( + ` + CREATE TABLE IF NOT EXISTS promotions ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT UNIQUE NOT NULL + ); + ` + ).run(); + db.prepare( ` CREATE TABLE IF NOT EXISTS students ( @@ -16,24 +25,33 @@ export const handler: Handlers = { promotionId INTEGER NOT NULL, FOREIGN KEY (promotionId) REFERENCES promotions (id) ); - ` + ` ).run(); - const rows = db + const promotions = db.prepare("SELECT id, name FROM promotions").all(); + + const students = db .prepare( - "SELECT students.id, firstName, lastName, email, promotionId FROM students" + ` + SELECT students.id, firstName, lastName, email, promotionId, promotions.name AS promotionName + FROM students + JOIN promotions ON students.promotionId = promotions.id + ` ) .all(); db.close(); - return new Response(JSON.stringify(rows), { - status: 200, - headers: { "Content-Type": "application/json" }, - }); + return new Response( + JSON.stringify({ promotions, students }), + { + status: 200, + headers: { "Content-Type": "application/json" }, + } + ); } catch (error) { - console.error("Error fetching students:", error); - return new Response("Failed to fetch students", { status: 500 }); + console.error("Error fetching data:", error); + return new Response("Failed to fetch data", { status: 500 }); } }, @@ -52,33 +70,6 @@ export const handler: Handlers = { const db = new Database("databases/data/mobility.db"); - console.log("Database opened successfully"); - - db.prepare( - ` - CREATE TABLE IF NOT EXISTS promotions ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - name TEXT UNIQUE NOT NULL - ); - ` - ).run(); - - db.prepare( - ` - CREATE TABLE IF NOT EXISTS students ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - firstName TEXT NOT NULL, - lastName TEXT NOT NULL, - email TEXT NOT NULL, - promotionId INTEGER NOT NULL, - FOREIGN KEY (promotionId) REFERENCES promotions (id) - ); - ` - ).run(); - - console.log("Tables ensured successfully"); - - // Insérer ou récupérer l'ID de la promotion db.prepare( "INSERT OR IGNORE INTO promotions (name) VALUES (?)" ).run(promoName); @@ -99,13 +90,13 @@ export const handler: Handlers = { insertQuery.run(student.Nom, student["Prénom"], student.Mail, promoId); } - console.log("All students inserted successfully"); db.close(); - return new Response("Students inserted successfully", { status: 201 }); + console.log("All data inserted successfully"); + return new Response("Data inserted successfully", { status: 201 }); } catch (error) { - console.error("Error inserting students:", error); - return new Response("Failed to insert students", { status: 500 }); + console.error("Error inserting data:", error); + return new Response("Failed to insert data", { status: 500 }); } }, }; diff --git a/routes/(apps)/mobility/api/promotions.ts b/routes/(apps)/mobility/api/promotions.ts deleted file mode 100644 index 288524b..0000000 --- a/routes/(apps)/mobility/api/promotions.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { Handlers } from "$fresh/server.ts"; -import { Database } from "@db/sqlite"; - -export const handler: Handlers = { - async GET() { - try { - const db = new Database("databases/data/mobility.db"); - - db.prepare( - ` - CREATE TABLE IF NOT EXISTS promotions ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - name TEXT UNIQUE NOT NULL - ); - ` - ).run(); - - const promotions = db.prepare("SELECT id, name FROM promotions").all(); - - db.close(); - - return new Response(JSON.stringify(promotions), { - status: 200, - headers: { "Content-Type": "application/json" }, - }); - } catch (error) { - console.error("Error fetching promotions:", error); - return new Response("Failed to fetch promotions", { status: 500 }); - } - }, -};