Browse Source

add file

master
andrymodeste 4 months ago
parent
commit
f1aefc3073
  1. 8
      database/Models/AnneeScolaire.js
  2. 13
      database/Models/Etudiants.backup.js
  3. 49
      database/Models/Etudiants.js
  4. 32
      database/Models/Matieres.backup.js
  5. 55
      database/Models/Matieres.js
  6. 8
      database/Models/Mentions.js
  7. 7
      database/Models/Niveau.js
  8. 4
      database/Models/NoteSysrem.js
  9. 10
      database/Models/Parcours.js
  10. 717
      database/database.backup.js
  11. 10
      database/database.js
  12. 7
      database/database2.js
  13. 2
      database/function/DownloadReleverNote.js
  14. 4
      database/function/System.js
  15. 470
      database/import/Etudiants.js
  16. 27
      electron.vite.config.1754936034364.mjs
  17. 20
      src/main/backup.js
  18. 20
      src/main/index.js
  19. 2
      src/preload/index.backup.js
  20. 6
      src/preload/index.js
  21. 2
      src/renderer/src/assets/AllStyleComponents.module.css
  22. 8
      src/renderer/src/components/AddAnneeScolaire.jsx
  23. 5
      src/renderer/src/components/AddNotes.jsx
  24. 6
      src/renderer/src/components/AddStudent.jsx
  25. 4
      src/renderer/src/components/AnneeScolaire.jsx
  26. 2
      src/renderer/src/components/Apropos.jsx
  27. 38
      src/renderer/src/components/ExportEtudiants.jsx
  28. 78
      src/renderer/src/components/Matieres.jsx
  29. 2
      src/renderer/src/components/ModalExportFichr.jsx
  30. 132
      src/renderer/src/components/NiveauMatiere.jsx
  31. 2
      src/renderer/src/components/ParcourMatiere.jsx
  32. 2
      src/renderer/src/components/Parcours.jsx
  33. 4
      src/renderer/src/components/Resultat.jsx
  34. 2
      src/renderer/src/components/Sidenav.jsx
  35. 6
      src/renderer/src/components/SingleAnneeScolaire.jsx
  36. 2
      src/renderer/src/components/SingleEtudiant.jsx
  37. 36
      src/renderer/src/components/Student.jsx
  38. 2
      src/renderer/src/components/TesteDatagrid.jsx
  39. 1
      src/renderer/src/components/UpdateTranche.jsx
  40. 2
      src/renderer/src/components/function/GenerateFiche.js
  41. 2
      src/renderer/src/components/function/PDFEditor.js
  42. 2
      src/renderer/src/components/function/PDFEditorV2.js
  43. 2
      src/renderer/src/test/qr.html
  44. 2
      src/renderer/src/test/relever.html
  45. 2
      text.txt

8
database/Models/AnneeScolaire.js

@ -71,13 +71,13 @@ async function deleteAnneeScolaire(id) {
if (result.affectedRows === 0) { if (result.affectedRows === 0) {
return { return {
success: false, success: false,
message: 'Année universitaire non trouvé.' message: 'Année Scolaire non trouvé.'
} }
} }
return { return {
success: true, success: true,
message: 'Année universitaire supprimé avec succès.' message: 'Année Scolaire supprimé avec succès.'
} }
} catch (error) { } catch (error) {
return { success: false, error: 'Erreur veullez réeseyer' } return { success: false, error: 'Erreur veullez réeseyer' }
@ -93,13 +93,13 @@ async function updateAnneeScolaire(id, code, debut, fin) {
if (result.affectedRows === 0) { if (result.affectedRows === 0) {
return { return {
success: false, success: false,
message: 'Année universitaire non trouvé ou aucune modification effectuée.' message: 'Année Scolaire non trouvé ou aucune modification effectuée.'
} }
} }
return { return {
success: true, success: true,
message: 'Année universitaire mis à jour avec succès.' message: 'Année Scolaire mis à jour avec succès.'
} }
} catch (error) { } catch (error) {
return { success: false, error: 'Erreur veullez réeseyer' } return { success: false, error: 'Erreur veullez réeseyer' }

13
database/Models/Etudiants.backup.js

@ -280,6 +280,18 @@ async function deleteTranche(id) {
} }
} }
async function deleteEtudiant(id) {
const query = database.prepare('DELETE FROM etudiants WHERE id = ?')
try {
let response = query.run(id)
return response
} catch (error) {
return error
}
}
async function getSingleTranche(id) { async function getSingleTranche(id) {
try { try {
return await database.prepare('SELECT * FROM trancheecolage WHERE id = ?').get(id) return await database.prepare('SELECT * FROM trancheecolage WHERE id = ?').get(id)
@ -301,5 +313,6 @@ module.exports = {
getTranche, getTranche,
updateTranche, updateTranche,
deleteTranche, deleteTranche,
deleteEtudiant,
getSingleTranche getSingleTranche
} }

49
database/Models/Etudiants.js

@ -176,13 +176,13 @@ async function updateEtudiant(
if (result.affectedRows === 0) { if (result.affectedRows === 0) {
return { return {
success: false, success: false,
message: 'Année universitaire non trouvé.' message: 'Année Scolaire non trouvé.'
} }
} }
return { return {
success: true, success: true,
message: 'Année universitaire supprimé avec succès.' message: 'Année Scolaire supprimé avec succès.'
} }
} catch (error) { } catch (error) {
return error return error
@ -222,13 +222,13 @@ async function changePDP(photos, id) {
if (result.affectedRows === 0) { if (result.affectedRows === 0) {
return { return {
success: false, success: false,
message: 'Année universitaire non trouvé.' message: 'Année Scolaire non trouvé.'
} }
} }
return { return {
success: true, success: true,
message: 'Année universitaire supprimé avec succès.' message: 'Année Scolaire supprimé avec succès.'
} }
} catch (error) { } catch (error) {
return error return error
@ -244,13 +244,13 @@ async function updateParcours(parcours, id) {
if (result.affectedRows === 0) { if (result.affectedRows === 0) {
return { return {
success: false, success: false,
message: 'Année universitaire non trouvé.' message: 'Année Scolaire non trouvé.'
} }
} }
return { return {
success: true, success: true,
message: 'Année universitaire supprimé avec succès.' message: 'Année Scolaire supprimé avec succès.'
} }
} catch (error) { } catch (error) {
return error return error
@ -289,19 +289,21 @@ async function updateTranche(id, tranchename, montant) {
try { try {
const [result] = await pool.query(sql, [tranchename, montant, id]) const [result] = await pool.query(sql, [tranchename, montant, id])
console.log('resultat tranche:',result);
if (result.affectedRows === 0) { if (result.affectedRows === 0) {
return { return {
success: false, success: false,
message: 'Année universitaire non trouvé.' message: 'Année Scolaire non trouvé.'
} }
} }
return { return {
success: true, success: true,
message: 'Année universitaire supprimé avec succès.' message: 'Année Scolaire supprimé avec succès.'
} }
} catch (error) { } catch (error) {
console.log('resultat error:',error);
return error return error
} }
} }
@ -315,19 +317,45 @@ async function deleteTranche(id) {
if (result.affectedRows === 0) { if (result.affectedRows === 0) {
return { return {
success: false, success: false,
message: 'Année universitaire non trouvé.' message: 'Année Scolaire non trouvé.'
} }
} }
return { return {
success: true, success: true,
message: 'Année universitaire supprimé avec succès.' message: 'Année Scolaire supprimé avec succès.'
} }
} catch (error) { } catch (error) {
return error return error
} }
} }
async function deleteEtudiant(id) {
console.log("id: ", id);
const sql = 'DELETE FROM etudiants WHERE id = ?';
try {
let [result] = await pool.query(sql, [id]);
console.log("Résultat DELETE:", result);
if (result.affectedRows === 0) {
return {
success: false,
message: 'Etudiant non trouvée.'
};
}
return {
success: true,
message: 'Matière supprimée avec succès.'
};
} catch (error) {
console.log("err: ",+ error)
return { success: false, error: 'Erreur, veuillez réessayer: ' + error };
}
}
async function getSingleTranche(id) { async function getSingleTranche(id) {
const sql = 'SELECT * FROM trancheecolage WHERE id = ?' const sql = 'SELECT * FROM trancheecolage WHERE id = ?'
try { try {
@ -351,5 +379,6 @@ module.exports = {
getTranche, getTranche,
updateTranche, updateTranche,
deleteTranche, deleteTranche,
deleteEtudiant,
getSingleTranche getSingleTranche
} }

32
database/Models/Matieres.backup.js

@ -29,7 +29,7 @@ async function createMatiere(nom, credit, uniter, ue) {
* @returns Promise * @returns Promise
*/ */
async function getMatiere() { async function getMatiere() {
const query = database.prepare('SELECT * FROM matieres ORDER BY id DESC') const query = database.prepare('SELECT m.*, n.nom AS niveau_nom FROM matieres m LEFT JOIN niveaus n ON m.niveau_id = n.id ORDER BY m.id DESC')
try { try {
let response = await query.all() let response = await query.all()
@ -141,6 +141,35 @@ async function updateMatiere(nom, id, credit, uniter, ue) {
} }
} }
async function updateMatiereNiveau(formData) {
console.log('formdata:', formData);
const { niveau_id, id } = formData;
const sql = 'UPDATE matieres SET niveau_id = ? WHERE id = ?';
try {
const [result] = await pool.query(sql, [niveau_id, id]);
if (result.affectedRows === 0) {
return {
success: false,
message: 'Matière non trouvée ou aucune modification effectuée.'
};
}
return {
success: true,
message: 'Niveau mis à jour avec succès.'
};
} catch (error) {
console.error(error);
return {
success: false,
error: 'Erreur lors de la mise à jour du niveau : ' + error.message
};
}
}
async function deleteMatiere(id) { async function deleteMatiere(id) {
const query = database.prepare('DELETE FROM matieres WHERE id = ?') const query = database.prepare('DELETE FROM matieres WHERE id = ?')
@ -340,6 +369,7 @@ module.exports = {
getMatiere, getMatiere,
getSingleMatiere, getSingleMatiere,
updateMatiere, updateMatiere,
updateMatiereNiveau,
displayMatiereFromForm, displayMatiereFromForm,
deleteMatiere, deleteMatiere,
asygnationToMention, asygnationToMention,

55
database/Models/Matieres.js

@ -31,7 +31,7 @@ async function createMatiere(nom, credit, uniter, ue) {
* @returns Promise * @returns Promise
*/ */
async function getMatiere() { async function getMatiere() {
const sql = 'SELECT * FROM matieres ORDER BY id DESC' const sql = 'SELECT m.*, n.nom AS niveau_nom FROM matieres m LEFT JOIN niveaus n ON m.niveau_id = n.id ORDER BY m.id DESC'
try { try {
let [rows] = await pool.query(sql) let [rows] = await pool.query(sql)
@ -149,41 +149,71 @@ async function updateMatiere(nom, id, credit, uniter, ue) {
if (result.affectedRows === 0) { if (result.affectedRows === 0) {
return { return {
success: false, success: false,
message: 'Année universitaire non trouvé ou aucune modification effectuée.' message: 'Année Scolaire non trouvé ou aucune modification effectuée.'
} }
} }
return { return {
success: true, success: true,
message: 'Année universitaire mis à jour avec succès.' message: 'Année Scolaire mis à jour avec succès.'
} }
} catch (error) { } catch (error) {
return { success: false, error: 'Erreur veullez réeseyer' + error } return { success: false, error: 'Erreur veullez réeseyer' + error }
} }
} }
async function updateMatiereNiveau(formData) {
const { niveau_id, id } = formData; // ici id sera bien défini
const sql = 'UPDATE matieres SET niveau_id = ? WHERE id = ?';
try {
const [result] = await pool.query(sql, [niveau_id, id]);
if (result.affectedRows === 0) {
return {
success: false,
message: `Matière avec id ${id} non trouvée ou niveau déjà attribué.`
};
}
return {
success: true,
message: `Niveau de la matière ${id} mis à jour avec succès.`
};
} catch (error) {
return {
success: false,
error: 'Erreur lors de la mise à jour : ' + error.message
};
}
}
async function deleteMatiere(id) { async function deleteMatiere(id) {
const sql = 'DELETE FROM matieres WHERE id = ?' console.log("id: ", id);
const sql = 'DELETE FROM matieres WHERE id = ?';
try { try {
let [result] = await pool.query(sql, [id]) let [result] = await pool.query(sql, [id]);
console.log("Résultat DELETE:", result);
if (result.affectedRows === 0) { if (result.affectedRows === 0) {
return { return {
success: false, success: false,
message: 'Année universitaire non trouvé.' message: 'Matière non trouvée.'
} };
} }
return { return {
success: true, success: true,
message: 'Année universitaire supprimé avec succès.' message: 'Matière supprimée avec succès.'
} };
} catch (error) { } catch (error) {
return { success: false, error: 'Erreur veullez réeseyer' + error } console.log("err: ",+ error)
return { success: false, error: 'Erreur, veuillez réessayer: ' + error };
} }
} }
/** /**
* Assign mentions to a matiere * Assign mentions to a matiere
* @param {Object} formData - keys = mention_ids, values = true/false * @param {Object} formData - keys = mention_ids, values = true/false
@ -444,13 +474,13 @@ async function updateProf(matiere_id, nom, prenom, contact, date) {
if (result.affectedRows === 0) { if (result.affectedRows === 0) {
return { return {
success: false, success: false,
message: 'Année universitaire non trouvé.' message: 'Année Scolaire non trouvé.'
} }
} }
return { return {
success: true, success: true,
message: 'Année universitaire supprimé avec succès.' message: 'Année Scolaire supprimé avec succès.'
} }
} catch (error) { } catch (error) {
console.error(error) console.error(error)
@ -464,6 +494,7 @@ module.exports = {
getMatiere, getMatiere,
getSingleMatiere, getSingleMatiere,
updateMatiere, updateMatiere,
updateMatiereNiveau,
displayMatiereFromForm, displayMatiereFromForm,
deleteMatiere, deleteMatiere,
asygnationToMention, asygnationToMention,

8
database/Models/Mentions.js

@ -24,13 +24,13 @@ async function deleteMention(id) {
if (result.affectedRows === 0) { if (result.affectedRows === 0) {
return { return {
success: false, success: false,
message: 'Année universitaire non trouvé.' message: 'Année Scolaire non trouvé.'
} }
} }
return { return {
success: true, success: true,
message: 'Année universitaire supprimé avec succès.' message: 'Année Scolaire supprimé avec succès.'
} }
} catch (error) { } catch (error) {
return { success: false, error: 'Erreur veullez réeseyer' + error } return { success: false, error: 'Erreur veullez réeseyer' + error }
@ -70,13 +70,13 @@ async function updateMention(nom, uniter, id) {
if (result.affectedRows === 0) { if (result.affectedRows === 0) {
return { return {
success: false, success: false,
message: 'Année universitaire non trouvé ou aucune modification effectuée.' message: 'Année Scolaire non trouvé ou aucune modification effectuée.'
} }
} }
return { return {
success: true, success: true,
message: 'Année universitaire mis à jour avec succès.' message: 'Année Scolaire mis à jour avec succès.'
} }
} catch (error) { } catch (error) {
return { success: false, error: 'Erreur veullez réeseyer' + error } return { success: false, error: 'Erreur veullez réeseyer' + error }

7
database/Models/Niveau.js

@ -89,17 +89,18 @@ async function updateNiveau(nom, id) {
* function to get all niveau * function to get all niveau
*/ */
async function getNiveau() { async function getNiveau() {
const sql = 'SELECT * FROM niveaus' const sql = 'SELECT niveaus.*,niveaus.id AS niveau_id FROM niveaus'
try { try {
let [rows] = await pool.query(sql) let [rows] = await pool.query(sql)
console.log("maka niveau: ", rows);
return rows return rows
} catch (error) { } catch (error) {
return { success: false, error: 'Erreur veullez réeseyer' } return { success: false, error: 'Erreur veullez réeseyer' }
} }
} }
async function deleteNiveau(id) { async function deleteNiveau(id) {
const sql = 'DELETE FROM niveaus WHERE id = ?' const sql = 'DELETE FROM niveaus WHERE id = ?'
@ -130,5 +131,5 @@ module.exports = {
insertNiveau, insertNiveau,
getSingleNiveau, getSingleNiveau,
updateNiveau, updateNiveau,
deleteNiveau deleteNiveau,
} }

4
database/Models/NoteSysrem.js

@ -33,13 +33,13 @@ async function updateSysteme(id, admis, redouble, renvoyer) {
if (result.affectedRows === 0) { if (result.affectedRows === 0) {
return { return {
success: false, success: false,
message: 'Année universitaire non trouvé.' message: 'Année Scolaire non trouvé.'
} }
} }
return { return {
success: true, success: true,
message: 'Année universitaire supprimé avec succès.' message: 'Année Scolaire supprimé avec succès.'
} }
} catch (error) { } catch (error) {
return error return error

10
database/Models/Parcours.js

@ -30,7 +30,7 @@ async function getParcourMatiere(id) {
} }
async function getParcours() { async function getParcours() {
const sql = 'SELECT * FROM parcours ORDER BY id DESC' const sql = 'SELECT parcours.*, mentions.nom AS mention_nom FROM parcours LEFT JOIN mentions ON parcours.mention_id = mentions.id ORDER BY parcours.id DESC'
try { try {
let [rows] = await pool.query(sql) let [rows] = await pool.query(sql)
@ -62,13 +62,13 @@ async function deletes(id) {
if (result.affectedRows === 0) { if (result.affectedRows === 0) {
return { return {
success: false, success: false,
message: 'Année universitaire non trouvé.' message: 'Année Scolaire non trouvé.'
} }
} }
return { return {
success: true, success: true,
message: 'Année universitaire supprimé avec succès.' message: 'Année Scolaire supprimé avec succès.'
} }
} catch (error) { } catch (error) {
return error return error
@ -84,13 +84,13 @@ async function updateparcour(id, nom, uniter, mention_id) {
if (result.affectedRows === 0) { if (result.affectedRows === 0) {
return { return {
success: false, success: false,
message: 'Année universitaire non trouvé ou aucune modification effectuée.' message: 'Année Scolaire non trouvé ou aucune modification effectuée.'
} }
} }
return { return {
success: true, success: true,
message: 'Année universitaire mis à jour avec succès.' message: 'Année Scolaire mis à jour avec succès.'
} }
} catch (error) { } catch (error) {
return error return error

717
database/database.backup.js

@ -1,444 +1,307 @@
const sqlite = require('better-sqlite3') const mysql = require('mysql2/promise')
const bcrypt = require('bcryptjs') const bcrypt = require('bcryptjs')
const pool = mysql.createPool({
host: '127.0.0.1',
user: 'root',
password: '',
database: 'university',
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
})
// Construct the database path using the detected IP async function createTables() {
let dbPath = `./base/data.db`; const connection = await pool.getConnection()
// Connect to SQLite database with the initial path try {
let database = new sqlite(dbPath); // Users table
await connection.query(`
CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(200) NOT NULL,
email VARCHAR(250) NOT NULL UNIQUE,
// Create the users table if it doesn't exist password TEXT NOT NULL,
const createUserTableQuery = ` roles VARCHAR(250) NOT NULL,
CREATE TABLE IF NOT EXISTS users ( created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
username VARCHAR(200) NOT NULL, ) ENGINE=InnoDB;
email VARCHAR(250) NOT NULL UNIQUE, `)
password TEXT NOT NULL,
roles VARCHAR(250) NOT NULL, // Status table
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, await connection.query(`
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP CREATE TABLE IF NOT EXISTS status (
); id INT AUTO_INCREMENT PRIMARY KEY,
` nom VARCHAR(200) NOT NULL,
database.prepare(createUserTableQuery).run() created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
// Insert a default admin user if not exists ) ENGINE=InnoDB;
const insertDefaultUserQuery = ` `)
INSERT INTO users (username, email, password, roles)
SELECT 'admin', 'admin@example.com', ?, 'admin' // Mentions table
WHERE NOT EXISTS (SELECT 1 FROM users WHERE username = 'admin'); await connection.query(`
` CREATE TABLE IF NOT EXISTS mentions (
id INT AUTO_INCREMENT PRIMARY KEY,
// Hash the password '1234' before storing nom VARCHAR(250) NOT NULL,
const hashedPassword = bcrypt.hashSync('123456789', 10) uniter VARCHAR(50) NOT NULL,
database.prepare(insertDefaultUserQuery).run(hashedPassword) created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
// create table for note status ) ENGINE=InnoDB;
const createStatusTableQuery = ` `)
CREATE TABLE IF NOT EXISTS status (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, await connection.query(`
nom VARCHAR(200) NOT NULL, CREATE TABLE IF NOT EXISTS niveaus (
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, id INT AUTO_INCREMENT PRIMARY KEY,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP nom VARCHAR(50) UNIQUE NOT NULL,
); created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
` updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
database.prepare(createStatusTableQuery).run() ) ENGINE=InnoDB;
`)
// create table for mention
const createMentionTableQuery = ` await connection.query(`
CREATE TABLE IF NOT EXISTS mentions ( CREATE TABLE IF NOT EXISTS etudiants (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, id INT AUTO_INCREMENT PRIMARY KEY,
nom VARCHAR(250) NOT NULL, nom VARCHAR(250) DEFAULT NULL,
uniter VARCHAR(50) NOT NULL, -- Abréviation du nom prenom VARCHAR(250) DEFAULT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, photos TEXT DEFAULT NULL,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP date_de_naissances DATE DEFAULT NULL,
); niveau VARCHAR(250) NOT NULL,
` annee_scolaire VARCHAR(20) NOT NULL,
database.prepare(createMentionTableQuery).run() status INT DEFAULT NULL,
mention_id INT NOT NULL,
// Create the niveau table if it doesn't exist num_inscription TEXT UNIQUE NOT NULL,
const createNiveauTableQuery = ` sexe VARCHAR(20) DEFAULT NULL,
CREATE TABLE IF NOT EXISTS niveaus ( cin VARCHAR(250) DEFAULT NULL,
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, date_delivrance TEXT DEFAULT NULL,
nom VARCHAR(50) NOT NULL, -- Exemple: L1, L2, L3, etc. nationalite VARCHAR(250) DEFAULT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, annee_bacc TEXT DEFAULT NULL,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP serie VARCHAR(20) DEFAULT NULL,
); boursier VARCHAR(20) DEFAULT NULL,
` domaine VARCHAR(250) DEFAULT NULL,
database.prepare(createNiveauTableQuery).run() contact VARCHAR(20) DEFAULT NULL,
parcours VARCHAR(250) DEFAULT NULL,
// Create the etudiants table if it doesn't exist created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
const createEtudiantsTableQuery = ` updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
CREATE TABLE IF NOT EXISTS etudiants ( FOREIGN KEY (status) REFERENCES status(id),
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, FOREIGN KEY (mention_id) REFERENCES mentions(id)
nom VARCHAR(250) DEFAULT NULL, ) ENGINE=InnoDB;
prenom VARCHAR(250) DEFAULT NULL, `)
photos TEXT DEFAULT NULL,
date_de_naissances DATE DEFAULT NULL, await connection.query(`
niveau VARCHAR(250) NOT NULL, -- Clé étrangère vers niveaus CREATE TABLE IF NOT EXISTS matieres (
annee_scolaire VARCHAR(20) NOT NULL, id INT AUTO_INCREMENT PRIMARY KEY,
status INTEGER DEFAULT NULL, nom VARCHAR(250) UNIQUE NOT NULL,
mention_id INTEGER NOT NULL, -- Clé étrangère vers mentions unite_enseignement VARCHAR(250) NOT NULL,
num_inscription TEXT NOT NULL, credit INT NOT NULL,
sexe VARCHAR(20) DEFAULT NULL, heure INT NOT NULL,
cin VARCHAR(250) DEFAULT NULL, ue VARCHAR(10) NOT NULL,
date_delivrance DEFAULT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
nationalite DATE DEFAULT NULL, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
annee_bacc DATE DEFAULT NULL, ) ENGINE=InnoDB;
serie VARCHAR(20) DEFAULT NULL, `)
boursier BOOLEAN DEFAULT FALSE,
domaine VARCHAR(250) DEFAULT NULL, await connection.query(`
contact VARCHAR(20) DEFAULT NULL, CREATE TABLE IF NOT EXISTS semestres (
parcours VARCHAR(250) DEFAULT NULL, id INT AUTO_INCREMENT PRIMARY KEY,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, nom VARCHAR(30) NOT NULL,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (status) REFERENCES status(id), updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
FOREIGN KEY (mention_id) REFERENCES mentions(id) ) ENGINE=InnoDB;
); `)
`
database.prepare(createEtudiantsTableQuery).run() await connection.query(`
CREATE TABLE IF NOT EXISTS matiere_mention (
// Create the notes table if it doesn't exist id INT AUTO_INCREMENT PRIMARY KEY,
const createMatiereTableQuery = ` matiere_id INT NOT NULL,
CREATE TABLE IF NOT EXISTS matieres ( mention_id INT NOT NULL,
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, FOREIGN KEY (matiere_id) REFERENCES matieres(id),
nom VARCHAR(250) UNIQUE NOT NULL, FOREIGN KEY (mention_id) REFERENCES mentions(id)
unite_enseignement VARCHAR(250) NOT NULL, ) ENGINE=InnoDB;
credit INTEGER NOT NULL, `)
heure INTEGER NOT NULL,
ue VARCHAR(10) NOT NULL, await connection.query(`
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, CREATE TABLE IF NOT EXISTS matiere_semestre (
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP id INT AUTO_INCREMENT PRIMARY KEY,
); matiere_id INT NOT NULL,
` semestre_id INT NOT NULL,
database.prepare(createMatiereTableQuery).run() mention_id INT NOT NULL,
FOREIGN KEY (matiere_id) REFERENCES matieres(id),
// Create the semestre table if it doesn't exist FOREIGN KEY (semestre_id) REFERENCES semestres(id),
const createSemestreTableQuery = ` FOREIGN KEY (mention_id) REFERENCES mentions(id)
CREATE TABLE IF NOT EXISTS semestres ( ) ENGINE=InnoDB;
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `)
nom VARCHAR(30) NOT NULL, -- Exemple: S1, S2, S3, etc.
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, await connection.query(`
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP CREATE TABLE IF NOT EXISTS notes (
); id INT AUTO_INCREMENT PRIMARY KEY,
` etudiant_id INT NOT NULL,
database.prepare(createSemestreTableQuery).run() matiere_id INT NOT NULL,
etudiant_niveau VARCHAR(50) NOT NULL,
// Create the semestre table if it doesn't exist mention_id INT NOT NULL,
const createMatiere_mentionTableQuery = ` note FLOAT DEFAULT NULL,
CREATE TABLE IF NOT EXISTS matiere_mention ( annee_scolaire VARCHAR(50) NOT NULL,
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
matiere_id INTEGER NOT NULL, -- Clé étrangère vers matieres updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
mention_id INTEGER NOT NULL, -- Clé étrangère vers mentions FOREIGN KEY (etudiant_id) REFERENCES etudiants(id),
FOREIGN KEY (matiere_id) REFERENCES matieres(id), FOREIGN KEY (matiere_id) REFERENCES matieres(id),
FOREIGN KEY (mention_id) REFERENCES mentions(id) FOREIGN KEY (mention_id) REFERENCES mentions(id)
); ) ENGINE=InnoDB;
` `)
database.prepare(createMatiere_mentionTableQuery).run()
await connection.query(`
const createMatiere_semestreTableQuery = ` CREATE TABLE IF NOT EXISTS notesrepech (
CREATE TABLE IF NOT EXISTS matiere_semestre ( id INT AUTO_INCREMENT PRIMARY KEY,
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, etudiant_id INT NOT NULL,
matiere_id INTEGER NOT NULL, -- Clé étrangère vers matieres matiere_id INT NOT NULL,
semestre_id INTEGER NOT NULL, -- Clé étrangère vers semestres etudiant_niveau VARCHAR(50) NOT NULL,
mention_id INTEGER NOT NULL, -- Clé étrangère vers niveaus mention_id INT NOT NULL,
FOREIGN KEY (matiere_id) REFERENCES matieres(id), note FLOAT DEFAULT NULL,
FOREIGN KEY (semestre_id) REFERENCES semestres(id), annee_scolaire VARCHAR(50) NOT NULL,
FOREIGN KEY (mention_id) REFERENCES mentions(id) created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
); updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
` FOREIGN KEY (etudiant_id) REFERENCES etudiants(id),
database.prepare(createMatiere_semestreTableQuery).run() FOREIGN KEY (matiere_id) REFERENCES matieres(id),
FOREIGN KEY (mention_id) REFERENCES mentions(id)
// Create the notes table if it doesn't exist ) ENGINE=InnoDB;
const createNoteTableQuery = ` `)
CREATE TABLE IF NOT EXISTS notes (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, await connection.query(`
etudiant_id INTEGER NOT NULL, -- Clé étrangère vers etudiants CREATE TABLE IF NOT EXISTS notesystems (
matiere_id INTEGER NOT NULL, -- Clé étrangère vers matieres id INT AUTO_INCREMENT PRIMARY KEY,
etudiant_niveau VARCHAR(50) NOT NULL, admis FLOAT NOT NULL DEFAULT 10,
mention_id INTEGER NOT NULL, redouble FLOAT NOT NULL DEFAULT 9.99,
note FLOAT DEFAULT NULL, renvoyer FLOAT NOT NULL DEFAULT 7.99,
annee_scolaire VARCHAR(50) NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, ) ENGINE=InnoDB;
FOREIGN KEY (etudiant_id) REFERENCES etudiants(id), `)
FOREIGN KEY (matiere_id) REFERENCES matieres(id)
FOREIGN KEY (mention_id) REFERENCES mentions(id) await connection.query(`
); CREATE TABLE IF NOT EXISTS anneescolaire (
` id INT AUTO_INCREMENT PRIMARY KEY,
database.prepare(createNoteTableQuery).run() code VARCHAR(30) NOT NULL,
debut DATE NOT NULL,
// Create the notes second session table if it doesn't exist fin DATE NOT NULL,
const createNoteRepechTableQuery = ` is_current TINYINT(1) DEFAULT 0,
CREATE TABLE IF NOT EXISTS notesrepech ( created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
etudiant_id INTEGER NOT NULL, -- Clé étrangère vers etudiants ) ENGINE=InnoDB;
matiere_id INTEGER NOT NULL, -- Clé étrangère vers matieres `)
etudiant_niveau VARCHAR(50) NOT NULL,
mention_id INTEGER NOT NULL, await connection.query(`
note FLOAT DEFAULT NULL, CREATE TABLE IF NOT EXISTS traitmentsystem (
annee_scolaire VARCHAR(50) NOT NULL, id INT AUTO_INCREMENT PRIMARY KEY,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, code VARCHAR(30) NOT NULL,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, debut DATE NOT NULL,
FOREIGN KEY (etudiant_id) REFERENCES etudiants(id), fin DATE NOT NULL,
FOREIGN KEY (matiere_id) REFERENCES matieres(id) is_finished TINYINT(1) DEFAULT 0,
FOREIGN KEY (mention_id) REFERENCES mentions(id) created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
); updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
` ) ENGINE=InnoDB;
database.prepare(createNoteRepechTableQuery).run() `)
// create table for note système await connection.query(`
const createNoteSystemeTableQuery = ` CREATE TABLE IF NOT EXISTS nessesaryTable (
CREATE TABLE IF NOT EXISTS notesystems ( id INT AUTO_INCREMENT PRIMARY KEY,
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, uniter_heure INT NOT NULL,
admis FLOAT NOT NULL DEFAULT 10, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
redouble FLOAT NOT NULL DEFAULT 9.99, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
renvoyer FLOAT NOT NULL DEFAULT 7.99, ) ENGINE=InnoDB;
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, `)
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
); await connection.query(`
` CREATE TABLE IF NOT EXISTS matiereEnseignants (
database.prepare(createNoteSystemeTableQuery).run() id INT AUTO_INCREMENT PRIMARY KEY,
matiere_id INT NOT NULL,
// create table année scolaire nom_enseignant VARCHAR(250) NOT NULL,
const createAnneeScolaireTableQuery = ` prenom_enseignant VARCHAR(250) NOT NULL,
CREATE TABLE IF NOT EXISTS anneescolaire ( contact VARCHAR(11) NOT NULL,
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, date DATE NOT NULL,
code VARCHAR(30) NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
debut DATE NOT NULL, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
fin DATE NOT NULL, FOREIGN KEY (matiere_id) REFERENCES matieres(id)
is_current INTEGER DEFAULT 0, ) ENGINE=InnoDB;
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, `)
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
); await connection.query(`
` CREATE TABLE IF NOT EXISTS parcours (
database.prepare(createAnneeScolaireTableQuery).run() id INT AUTO_INCREMENT PRIMARY KEY,
nom VARCHAR(250) NOT NULL,
// create traitement systeme uniter VARCHAR(250) NOT NULL,
const createTraitementSystemQuery = ` mention_id INT DEFAULT NULL,
CREATE TABLE IF NOT EXISTS traitmentsystem ( created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
code VARCHAR(30) NOT NULL, ) ENGINE=InnoDB;
debut DATE NOT NULL, `)
fin DATE NOT NULL,
is_finished INTEGER DEFAULT 0, await connection.query(`
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, CREATE TABLE IF NOT EXISTS parcoursmatiere (
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP id INT AUTO_INCREMENT PRIMARY KEY,
); matiere_id INT NOT NULL,
` parcour_id INT NOT NULL,
database.prepare(createTraitementSystemQuery).run() FOREIGN KEY (matiere_id) REFERENCES matieres(id),
FOREIGN KEY (parcour_id) REFERENCES parcours(id)
const createNecessaryParameterTableQuery = ` ) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS nessesaryTable ( `)
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
uniter_heure INTEGER NOT NULL, await connection.query(`
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, CREATE TABLE IF NOT EXISTS trancheecolage (
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP id INT AUTO_INCREMENT PRIMARY KEY,
); etudiant_id INT NOT NULL,
` tranchename VARCHAR(255) NOT NULL,
database.prepare(createNecessaryParameterTableQuery).run() montant DOUBLE NOT NULL
) ENGINE=InnoDB;
const createMatiereEnseignantTableQuery = ` `)
CREATE TABLE IF NOT EXISTS matiereEnseignants (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, await connection.query(`
matiere_id INTEGER NOT NULL, CREATE TABLE IF NOT EXISTS ipconfig (
nom_enseignant VARCHAR(250) NOT NULL, id INT AUTO_INCREMENT PRIMARY KEY,
prenom_enseignant VARCHAR(250) NOT NULL, ipname VARCHAR(255) NOT NULL
contact VARCHAR(11) NOT NULL, ) ENGINE=InnoDB;
date DATE NOT NULL, `)
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, } finally {
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, connection.release()
FOREIGN KEY (matiere_id) REFERENCES matieres(id)
);
`
database.prepare(createMatiereEnseignantTableQuery).run()
const createParcourTableQuery = `
CREATE TABLE IF NOT EXISTS parcours (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
nom VARCHAR(250) NOT NULL,
uniter VARCHAR(250) NOT NULL,
mention_id INTEGER DEFAULT NULL, -- Clé étrangère vers mentions
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
`
database.prepare(createParcourTableQuery).run()
const createParcourSemestreTableQuery = `
CREATE TABLE IF NOT EXISTS parcoursmatiere (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
matiere_id INTEGER NOT NULL,
parcour_id INTEGER NOT NULL,
FOREIGN KEY (matiere_id) REFERENCES matieres(id),
FOREIGN KEY (parcour_id) REFERENCES parcours(id)
);
`
database.prepare(createParcourSemestreTableQuery).run()
const createTableEcolageQuery = `
CREATE TABLE IF NOT EXISTS trancheecolage (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
etudiant_id INTEGER NOT NULL,
tranchename VARCHAR(255) NOT NULL,
montant DOUBLE NOT NULL
);
`
database.prepare(createTableEcolageQuery).run()
const createTableStoreIP = `
CREATE TABLE IF NOT EXISTS ipconfig (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
ipname VARCHAR(255) NOT NULL
);
`;
database.prepare(createTableStoreIP).run()
// -------------------------------------- function pre-excuter --------------------------------------------
async function insertStatusesIfNotExist() {
// Préparation des requêtes
const checkStatusQuery = database.prepare(`
SELECT COUNT(*) AS count FROM status WHERE nom = ?;
`)
const insertStatusQuery = database.prepare(`
INSERT INTO status (nom) VALUES (?);
`)
// Tableau des statuts à vérifier/insérer
const arrayStatus = ['Nouveau', 'Passant', 'Redoublant', 'Renvoyé', 'Ancien']
for (let index = 0; index < arrayStatus.length; index++) {
const statusName = arrayStatus[index]
// Vérification si le statut existe déjà
const result = checkStatusQuery.get(statusName)
// Si le statut n'existe pas, on l'insère
if (result.count === 0) {
insertStatusQuery.run(statusName)
}
}
}
// execute the function
insertStatusesIfNotExist()
async function insertDefaultNoteSystemIfNotExist() {
// Préparation de la requête pour vérifier si une entrée existe déjà
const checkNoteSystemQuery = database.prepare(`
SELECT COUNT(*) AS count FROM notesystems;
`)
// Préparation de la requête pour insérer une entrée par défaut
const insertNoteSystemQuery = database.prepare(`
INSERT INTO notesystems (admis, redouble, renvoyer)
VALUES (?, ?, ?);
`)
// Valeurs par défaut à insérer
const defaultValues = {
admis: 10.0,
redouble: 9.99,
renvoyer: 7.99
}
// Vérification si une entrée existe déjà
const result = checkNoteSystemQuery.get()
if (result.count === 0) {
// Insérer les valeurs par défaut si aucune entrée n'existe
insertNoteSystemQuery.run(defaultValues.admis, defaultValues.redouble, defaultValues.renvoyer)
} }
} }
insertDefaultNoteSystemIfNotExist() async function insertDefaultAdmin() {
const conn = await pool.getConnection()
async function semestreCreate() {
const query = database.prepare('INSERT INTO semestres (nom) VALUES (?)')
// Préparation de la requête pour vérifier si une entrée existe déjà
const checkSemestreQuery = database.prepare(`
SELECT COUNT(*) AS count FROM semestres;
`)
try { try {
let arraySemestre = [ const [rows] = await conn.query(`SELECT COUNT(*) as count FROM users WHERE username = ?`, [
'S1', 'admin'
'S2', ])
'S3', if (rows[0].count === 0) {
'S4', const hashedPassword = bcrypt.hashSync('123456789', 10)
'S5', await conn.query(
'S6', `
'S7', INSERT INTO users (username, email, password, roles)
'S8', VALUES (?, ?, ?, ?)`,
'S9', ['admin', 'admin@example.com', hashedPassword, 'admin']
'S10', )
'S11',
'S12',
'S13',
'S14',
'S14',
'S16'
]
// Vérification si une entrée existe déjà
const result = checkSemestreQuery.get()
if (result.count === 0) {
database.transaction(() => {
for (let index = 0; index < arraySemestre.length; index++) {
query.run(arraySemestre[index])
}
})()
} }
} catch (error) { } finally {
console.log(error) conn.release()
}
}
const createNecessaryParameterTable = () => {
// Check if the table is empty
const rowCount = database.prepare(`SELECT COUNT(*) AS count FROM nessesaryTable`).get().count
// If the table is empty, insert the default value
if (rowCount === 0) {
const insertDefaultQuery = `
INSERT INTO nessesaryTable (uniter_heure) VALUES (15);
`
database.prepare(insertDefaultQuery).run()
} }
} }
// Call the function when the app runs async function insertStatusesIfNotExist() {
createNecessaryParameterTable() const conn = await pool.getConnection()
try {
semestreCreate() const statuses = ['Nouveau', 'Passant', 'Redoublant', 'Renvoyé', 'Ancien']
for (let name of statuses) {
// Function to get the IP from the database const [rows] = await conn.query(`SELECT COUNT(*) as count FROM status WHERE nom = ?`, [name])
function getIP() { if (rows[0].count === 0) {
const data = database.prepare("SELECT * FROM ipconfig WHERE id = 1").get(); await conn.query(`INSERT INTO status (nom) VALUES (?)`, [name])
}
if (data) { }
return data.ipname; } finally {
} else { conn.release()
return null; // Explicitly return `null` if no data is found
} }
} }
// Get the new IP from the database
let newIP = getIP();
if (newIP) {
// Construct the database path using the new IP from the database
dbPath = `\\\\${newIP}\\base\\data.db`;
// Reconnect to SQLite database with the updated path
database = new sqlite(dbPath); // Re-initialize database connection with new path
console.log("now COnnect to the ", dbPath);
}
module.exports = { module.exports = {
database pool,
createTables,
insertDefaultAdmin,
insertStatusesIfNotExist
} }

10
database/database.js

@ -1,11 +1,11 @@
const mysql = require('mysql2/promise') const mysql = require('mysql2/promise')
const bcrypt = require('bcryptjs') const bcrypt = require('bcryptjs')
const pool = mysql.createPool({ const pool = mysql.createPool({
host: '127.0.0.1', host: '127.0.0.1',
user: 'root', user: 'root',
password: '', password: '',
database: 'university', database: 'university',
waitForConnections: true, waitForConnections: true,
connectionLimit: 10, connectionLimit: 10,
queueLimit: 0 queueLimit: 0

7
database/database2.js

@ -6,11 +6,12 @@ const pool = mysql.createPool({
user: 'root', user: 'root',
password: '', password: '',
database: 'university', database: 'university',
waitForConnections: true, waitForConnections: true,
connectionLimit: 10, connectionLimit: 10,
queueLimit: 0 queueLimit: 0
}) })
async function createTables() { async function createTables() {
const connection = await pool.getConnection() const connection = await pool.getConnection()

2
database/function/DownloadReleverNote.js

@ -14,7 +14,7 @@ async function modifyPDF(filepath) {
const firstPage = pages[0] const firstPage = pages[0]
// Replace text based on your data object // Replace text based on your data object
const data = { f1: 'Nom', f2: 'Prénom', f3: 23 } const data = { f1: 'Nom', f2: 'Prenom', f3: 23 }
// Example of replacing placeholders // Example of replacing placeholders
firstPage.drawText(data.f1, { x: 120, y: 700, size: 12 }) firstPage.drawText(data.f1, { x: 120, y: 700, size: 12 })

4
database/function/System.js

@ -287,13 +287,13 @@ async function updateNessesaryTable(id, multiplicateur) {
if (result.affectedRows === 0) { if (result.affectedRows === 0) {
return { return {
success: false, success: false,
message: 'Année universitaire non trouvé.' message: 'Année Scolaire non trouvé.'
} }
} }
return { return {
success: true, success: true,
message: 'Année universitaire supprimé avec succès.' message: 'Année Scolaire supprimé avec succès.'
} }
} catch (error) { } catch (error) {
return error return error

470
database/import/Etudiants.js

@ -1,264 +1,316 @@
const fs = require('fs') const fs = require('fs');
const path = require('path') const path = require('path');
const XLSX = require('xlsx') const XLSX = require('xlsx');
const { getCompressedDefaultImage } = require('../function/GetImageDefaault') const { getCompressedDefaultImage } = require('../function/GetImageDefaault');
const { parse } = require('csv-parse/sync') const { parse } = require('csv-parse/sync');
const { pool } = require('../database') const { pool } = require('../database');
const dayjs = require('dayjs') const dayjs = require('dayjs');
// const { getStatusMention } = require('../function/Helper') const customParseFormat = require('dayjs/plugin/customParseFormat');
const customParseFormat = require('dayjs/plugin/customParseFormat') dayjs.extend(customParseFormat);
// const { log } = require('console')
// const customParseFormatt = require('dayjs/plu') // ✅ Fonction de correction d'encodage
dayjs.extend(customParseFormat) function fixEncoding(str) {
if (typeof str !== 'string') return str;
// Function to convert any date format to 'YYYY-MM-DD' return str
.replace(/├®/g, 'é')
.replace(/├à/g, 'à')
.replace(/├©/g, 'é')
.replace(/├ô/g, 'ô')
.replace(/├ù/g, 'ù')
.replace(/’/g, "'")
.replace(/â€/g, '…')
.replace(/â€/g, '-');
}
function convertToISODate(input) { function convertToISODate(input) {
// Try parsing the date with different formats if (!input) return null;
const formats = [
'DD/MM/YYYY', console.log('🔍 Input original:', input, 'Type:', typeof input);
'MM/DD/YYYY',
'YYYY-MM-DD', // Si input est un objet Date valide
'DD-MM-YYYY', if (input instanceof Date && !isNaN(input)) {
'MM-DD-YYYY', const result = dayjs(input).format('YYYY-MM-DD');
'DD/MM/YY', console.log('📅 Date object convertie:', result);
'MM/DD/YY', return result;
'DD-MMM-YY'
]
const parsedDate = dayjs(input, formats, true) // Strict parsing to ensure formats are matched correctly
// If the date is valid, return it in the YYYY-MM-DD format
if (parsedDate.isValid()) {
return parsedDate.format('YYYY-MM-DD')
} }
// Handle cases like "Vers 2000" // Si input est un nombre (numéro de série Excel)
const versMatch = typeof input === 'string' && input.match(/vers\s*(\d{4})/i); if (typeof input === 'number') {
if (versMatch) { // Formule Excel: (numéro - 25569) * 86400 * 1000
return `${versMatch[1]}-01-01`; // Return in ISO format const excelDate = new Date((input - 25569) * 86400 * 1000);
const result = dayjs(excelDate).format('YYYY-MM-DD');
console.log('📊 Numéro Excel', input, 'converti en:', result);
return result;
} }
function excelDateToJSDate(serial) { // Si input est une chaîne
const utc_days = Math.floor(serial - 25569); // days from Jan 1, 1970 if (typeof input === 'string') {
const utc_value = utc_days * 86400; // seconds in a day const cleanInput = input.trim();
return new Date(utc_value * 1000); // JS Date uses milliseconds
// Cas spécial "vers YYYY"
const versMatch = cleanInput.match(/vers\s*(\d{4})/i);
if (versMatch) {
const result = `${versMatch[1]}-01-01`;
console.log('📝 "Vers" détecté:', result);
return result;
}
// Formats à tester dans l'ordre de priorité
const formats = [
'DD/MM/YYYY', 'D/M/YYYY', // Format français prioritaire
'YYYY-MM-DD', // Format ISO
'DD-MM-YYYY', 'D-M-YYYY', // Format français avec tirets
'MM/DD/YYYY', 'M/D/YYYY', // Format américain
'MM-DD-YYYY', 'M-D-YYYY', // Format américain avec tirets
'DD/MM/YY', 'D/M/YY', // Années courtes
'MM/DD/YY', 'M/D/YY',
'DD-MM-YY', 'D-M-YY',
'MM-DD-YY', 'M-D-YY'
];
// Test avec parsing strict pour éviter les interprétations erronées
for (const format of formats) {
const parsedDate = dayjs(cleanInput, format, true); // true = strict parsing
if (parsedDate.isValid()) {
const result = parsedDate.format('YYYY-MM-DD');
console.log(`✅ Format "${format}" réussi:`, cleanInput, '->', result);
// Vérification supplémentaire pour les dates invalides comme 29/02 en année non-bissextile
if (format.includes('DD/MM') || format.includes('D/M')) {
const day = parsedDate.date();
const month = parsedDate.month() + 1; // dayjs month is 0-indexed
const year = parsedDate.year();
// Vérifier si c'est le 29 février d'une année non-bissextile
if (month === 2 && day === 29 && !isLeapYear(year)) {
console.warn('⚠️ Date invalide détectée: 29 février en année non-bissextile');
return null; // ou retourner une date par défaut
}
}
return result;
}
}
// Si aucun format strict ne fonctionne, essayer le parsing libre en dernier recours
const freeParseDate = dayjs(cleanInput);
if (freeParseDate.isValid()) {
const result = freeParseDate.format('YYYY-MM-DD');
console.log('🆓 Parsing libre réussi:', cleanInput, '->', result);
return result;
}
} }
let jsDate = excelDateToJSDate(input); console.error('❌ Impossible de convertir:', input);
return null;
}
// If the input is not a valid date, return 'Invalid Date' // Fonction utilitaire pour vérifier les années bissextiles
return jsDate function isLeapYear(year) {
return (year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0);
} }
// ✅ Mise à jour d'un étudiant existant
async function updateEtudiant(row) {
const sql = `
UPDATE etudiants SET
nom = ?,
prenom = ?,
photos = ?,
date_de_naissances = ?,
niveau = ?,
annee_scolaire = ?,
status = ?,
mention_id = ?,
num_inscription = ?,
sexe = ?,
date_delivrance = ?,
nationalite = ?,
annee_bacc = ?,
serie = ?,
boursier = ?,
domaine = ?,
contact = ?,
parcours = ?
WHERE cin = ? OR (LOWER(nom) = ? AND LOWER(prenom) = ?)
`;
const params = [
row.nom,
row.prenom,
getCompressedDefaultImage(),
convertToISODate(row.date_naissance),
row.niveau,
row.annee_scolaire,
row.code_redoublement,
row.mention,
row.num_inscription.toString(),
row.sexe,
convertToISODate(row.date_de_delivrance),
row.nationaliter,
parseInt(row.annee_baccalaureat, 10),
row.serie,
row.boursier,
fixEncoding(row.domaine),
row.contact,
null,
row.cin,
row.nom.toLowerCase().trim(),
row.prenom.toLowerCase().trim()
];
try {
const [result] = await pool.query(sql, params);
console.log(`Update effectué pour CIN ${row.cin} ou nom ${row.nom} ${row.prenom}, affectedRows=${result.affectedRows}`);
return { success: true, affectedRows: result.affectedRows };
} catch (error) {
console.error('❌ Erreur MySQL update :', error.message);
return { success: false, error: error.message };
}
}
// ✅ Insertion réelle multiple
async function insertMultipleEtudiants(etudiants) { async function insertMultipleEtudiants(etudiants) {
const sql = ` const sql = `
INSERT INTO etudiants ( INSERT INTO etudiants (
nom, prenom, photos, date_de_naissances, niveau, annee_scolaire, status, nom, prenom, photos, date_de_naissances, niveau, annee_scolaire, status,
mention_id, num_inscription, sexe, cin, date_delivrance, nationalite, mention_id, num_inscription, sexe, cin, date_delivrance, nationalite,
annee_bacc, serie, boursier, domaine, contact, parcours annee_bacc, serie, boursier, domaine, contact, parcours
) ) VALUES ?
VALUES ? `;
`
// Prepare values as array of arrays const values = etudiants.map(row => [
const values = etudiants.map((row) => [
row.nom, row.nom,
row.prenom, row.prenom,
getCompressedDefaultImage(), // photos (you can adjust this if needed) getCompressedDefaultImage(),
convertToISODate(row.date_naissance), convertToISODate(row.date_naissance),
row.niveau, row.niveau,
row.annee_scolaire, row.annee_scolaire,
row.code_redoublement, row.code_redoublement,
row.mention, row.mention,
row.num_inscription, row.num_inscription.toString(),
row.sexe, row.sexe,
row.cin, row.cin,
convertToISODate(row.date_de_delivrance), convertToISODate(row.date_de_delivrance),
row.nationaliter, row.nationaliter,
row.annee_baccalaureat, parseInt(row.annee_baccalaureat, 10),
row.serie, row.serie,
row.boursier, row.boursier,
row.domaine, fixEncoding(row.domaine),
row.contact, row.contact,
null // parcours null
]) ]);
try { try {
const [result] = await pool.query(sql, [values]) const [result] = await pool.query(sql, [values]);
return { return { success: true, affectedRows: result.affectedRows };
success: true,
affectedRows: result.affectedRows,
insertId: result.insertId
}
} catch (error) { } catch (error) {
return { success: false, error: error.message } console.error('❌ Erreur MySQL :', error.message);
return { success: false, error: error.message };
} }
} }
/** // ✅ Import fichier vers base
* Function to import data from XLSX or CSV file into SQLite database
* @param {string} filePath - Path to the file (either .xlsx or .csv)
*/
async function importFileToDatabase(filePath) { async function importFileToDatabase(filePath) {
const fileExtension = path.extname(filePath).toLowerCase() const fileExtension = path.extname(filePath).toLowerCase();
let records;
// Determine the file type and parse accordingly
let records
if (fileExtension === '.xlsx') { if (fileExtension === '.xlsx') {
// Read and parse XLSX file const workbook = XLSX.readFile(filePath);
const workbook = XLSX.readFile(filePath) const worksheet = workbook.Sheets[workbook.SheetNames[0]];
const worksheet = workbook.Sheets[workbook.SheetNames[0]] // Assuming data is in the first sheet // raw: true pour garder les valeurs brutes, surtout pour les dates
records = XLSX.utils.sheet_to_json(worksheet, { defval: '', raw: false }) records = XLSX.utils.sheet_to_json(worksheet, { defval: ''});
} else if (fileExtension === '.csv') { } else if (fileExtension === '.csv') {
// Read and parse CSV file const fileContent = fs.readFileSync(filePath, 'utf8');
const fileContent = fs.readFileSync(filePath, 'utf8') records = parse(fileContent, { columns: true, skip_empty_lines: true });
records = parse(fileContent, { }else {
columns: true, console.error('Unsupported file format.');
skip_empty_lines: true return { error: true, message: 'Format de fichier non supporté.' };
})
} else {
console.error('Unsupported file format. Only .xlsx and .csv are allowed.')
return
} }
// ✅ Count number of data rows console.log(`📄 Nombre de lignes : ${records.length}`);
const numberOfLines = records.length
console.log(`Number of data rows: ${numberOfLines}`)
try { // Vérifier champs obligatoires
let error = true const requiredFields = [
let message = '' 'nom', 'date_naissance', 'niveau', 'annee_scolaire',
'mention', 'num_inscription', 'nationaliter', 'sexe',
// Vérifier les données en une seule boucle 'annee_baccalaureat', 'serie', 'code_redoublement',
let oldNum = '' 'boursier', 'domaine'
for (const row of records) { ];
if (
!row.nom || for (const [i, row] of records.entries()) {
// !row.prenom || for (const field of requiredFields) {
!row.date_naissance || if (!row[field]) {
!row.niveau || const msg = `Le champ '${field}' est manquant à la ligne ${i + 2}`;
!row.annee_scolaire || console.error(msg);
!row.mention || return { error: true, message: msg };
!row.num_inscription ||
!row.nationaliter ||
!row.sexe ||
// !row.cin ||
// !row.date_de_delivrance ||
!row.annee_baccalaureat ||
!row.serie ||
!row.code_redoublement ||
!row.boursier ||
!row.domaine
// ||
// !row.contact
) {
if (!row.nom) {
message = "Le champ 'nom' est inconnu"
}
// else if (!row.prenom) {
// message = "Le champ 'prenom' est inconnu"
// }
else if (!row.date_naissance) {
message = "Le champ 'date_naissance' est inconnu"
} else if (!row.niveau) {
message = "Le champ 'niveau' est inconnu"
} else if (!row.annee_scolaire) {
message = "Le champ 'annee_scolaire' est inconnu"
} else if (!row.mention) {
message = "Le champ 'mention' est inconnu"
} else if (!row.num_inscription) {
message = "Le champ 'num_inscription' est inconnu"
} else if (!row.nationaliter) {
message = "Le champ 'nationaliter' est inconnu"
} else if (!row.sexe) {
message = "Le champ 'sexe' est inconnu"
}
// else if (!row.cin) {
// message = "Le champ 'cin' est inconnu"
// } else if (!row.date_de_delivrance) {
// message = "Le champ 'date_de_delivrance' est inconnu"
// }
else if (!row.annee_baccalaureat) {
message = "Le champ 'annee_baccalaureat' est inconnu"
} else if (!row.serie) {
message = "Le champ 'serie' est inconnu"
} else if (!row.code_redoublement) {
message = "Le champ 'code_redoublement' est inconnu"
} else if (!row.boursier) {
message = "Le champ 'boursier' est inconnu"
} else if (!row.domaine) {
message = "Le champ 'domaine' est inconnu"
}
// else if (!row.contact) {
// message = "Le champ 'contact' est inconnu"
// }
error = false
break
} }
} }
}
const query = 'SELECT * FROM mentions' const [mentionRows] = await pool.query('SELECT * FROM mentions');
const [rows] = await pool.query(query) const [statusRows] = await pool.query('SELECT * FROM status');
const MentionList = rows
console.log(MentionList)
if (error !== false) {
let newReccord = []
// Utiliser transaction pour éviter une latence si l'insertion dépasse 100
for (const row of records) {
// Convert row.mention to uppercase and compare with ListMention.nom and ListMention.uniter (also converted to uppercase)
const matchedMention = MentionList.find(
(mention) =>
mention.nom.toUpperCase() === row.mention.toUpperCase() ||
mention.uniter.toUpperCase() === row.mention.toUpperCase()
)
// If a match is found, update row.mention with ListMention.id
if (matchedMention) {
row.mention = matchedMention.id
}
const query = 'SELECT * FROM status' const etudiantsToInsert = [];
const doublons = [];
let [rows] = await pool.query(query) console.log(records);
let response = rows
let statutCode
for (let index = 0; index < response.length; index++) {
let nom = response[index].nom
let nomLower = nom.toLowerCase() // Correct method
let find1 = row.code_redoublement.slice(0, 1)
let find2 = row.code_redoublement.slice(0, 3)
if (nomLower.slice(0, 1) == find1.toLowerCase()) {
statutCode = response[index].id
} else if (nomLower.slice(0, 3) == find2.toLowerCase()) {
statutCode = response[index].id
}
}
row.code_redoublement = statutCode for (const row of records) {
row.num_inscription = row.num_inscription.toString() // Mapping mention
try { console.log('Avant conversion date_naissance:', row.date_naissance);
let compare = row.num_inscription row.date_naissance = convertToISODate(row.date_naissance);
if (compare == oldNum) { console.log('Après conversion date_naissance:', row.date_naissance);
row.num_inscription = String(row.num_inscription) const matchedMention = mentionRows.find(
} m => m.nom.toUpperCase() === row.mention.toUpperCase() ||
console.log(row.code_redoublement) m.uniter.toUpperCase() === row.mention.toUpperCase()
newReccord.push(row) );
oldNum = compare if (matchedMention) row.mention = matchedMention.id;
} catch (error) {
console.log(error) // Gestion code_redoublement -> status id
} if (row.code_redoublement) {
row.code_redoublement = row.code_redoublement.trim().substring(0, 1);
} else {
row.code_redoublement = 'N';
}
const statusMatch = statusRows.find(
s => s.nom.toLowerCase().startsWith(row.code_redoublement.toLowerCase())
);
if (statusMatch) row.code_redoublement = statusMatch.id;
// Vérification doublons (extraction complet)
const nomComplet = (row.nom + ' ' + row.prenom).toLowerCase().trim();
const [existing] = await pool.query(
'SELECT * FROM etudiants WHERE LOWER(CONCAT(nom, " ", prenom)) = ? OR cin = ?',
[nomComplet, row.cin]
);
if (existing.length > 0) {
doublons.push({ nom: row.nom, prenom: row.prenom, cin: row.cin });
// Mise à jour
const updateResult = await updateEtudiant(row);
if (!updateResult.success) {
return { error: true, message: `Erreur lors de la mise à jour de ${row.nom} ${row.prenom} : ${updateResult.error}` };
} }
console.log(insertMultipleEtudiants(newReccord)) continue;
} }
return { error, message } etudiantsToInsert.push(row);
} catch (error) {
console.error('Error inserting record:', error)
return { error: 'error' }
} }
}
module.exports = { console.log(etudiantsToInsert);
importFileToDatabase
// Insertion des nouveaux
let insertResult = { success: true, affectedRows: 0 };
if (etudiantsToInsert.length > 0) {
insertResult = await insertMultipleEtudiants(etudiantsToInsert);
if (!insertResult.success) {
return { error: true, message: `Erreur lors de l'insertion : ${insertResult.error}` };
}
}
let msg = `Importation réussie. ${etudiantsToInsert.length} nouvel(le)(s) étudiant(s) inséré(s). ${doublons.length} étudiant(s) mis à jour.`;
return { error: false, message: msg };
} }
module.exports = { importFileToDatabase };

27
electron.vite.config.1754936034364.mjs

@ -0,0 +1,27 @@
// electron.vite.config.mjs
import { resolve } from "path";
import { defineConfig, externalizeDepsPlugin } from "electron-vite";
import react from "@vitejs/plugin-react";
var electron_vite_config_default = defineConfig({
main: {
plugins: [externalizeDepsPlugin()]
},
preload: {
plugins: [externalizeDepsPlugin()]
},
renderer: {
resolve: {
alias: {
"@renderer": resolve("src/renderer/src")
}
},
plugins: [react()]
},
worker: {
format: "es"
// Use ES module for worker (you can also use 'iife')
}
});
export {
electron_vite_config_default as default
};

20
src/main/backup.js

@ -25,6 +25,7 @@ const {
getTranche, getTranche,
updateTranche, updateTranche,
deleteTranche, deleteTranche,
deleteEtudiant,
getSingleTranche getSingleTranche
} = require('../../database/Models/Etudiants') } = require('../../database/Models/Etudiants')
const { const {
@ -45,6 +46,7 @@ const {
createMatiere, createMatiere,
getSingleMatiere, getSingleMatiere,
updateMatiere, updateMatiere,
updateMatiereNiveau,
displayMatiereFromForm, displayMatiereFromForm,
deleteMatiere, deleteMatiere,
asygnationToMention, asygnationToMention,
@ -537,6 +539,12 @@ ipcMain.handle('updateMatiere', async (event, credentials) => {
return update return update
}) })
ipcMain.handle('updateMatiereNiveau', async (event, credentials) => {
// credentials = { niveau_id, id }
const update = await updateMatiereNiveau(credentials) // ✅ on passe id + niveau_id
return update
})
// event for importExcel // event for importExcel
ipcMain.handle('importexcel', async (event, credentials) => { ipcMain.handle('importexcel', async (event, credentials) => {
const files = credentials const files = credentials
@ -672,12 +680,10 @@ ipcMain.handle('deleteNiveaus', async (event, credentials) => {
return get return get
}) })
ipcMain.handle('deleteMatiere', async (event, credentials) => { ipcMain.handle('deleteMatiere', async (event, id) => {
const { id } = credentials return await deleteMatiere(id);
});
const get = deleteMatiere(id)
return get
})
ipcMain.handle('asign', async (event, credentials) => { ipcMain.handle('asign', async (event, credentials) => {
const { formData, id } = credentials const { formData, id } = credentials
@ -887,6 +893,10 @@ ipcMain.handle('deleteTranche', async (event, credentials) => {
return get return get
}) })
ipcMain.handle('deleteEtudiant', async (event, id) => {
return await deleteEtudiant(id);
});
ipcMain.handle('getSingleTranche', async (event, credentials) => { ipcMain.handle('getSingleTranche', async (event, credentials) => {
const { id } = credentials const { id } = credentials
// console.log(formData, id); // console.log(formData, id);

20
src/main/index.js

@ -45,8 +45,10 @@ const {
createMatiere, createMatiere,
getSingleMatiere, getSingleMatiere,
updateMatiere, updateMatiere,
updateMatiereNiveau,
displayMatiereFromForm, displayMatiereFromForm,
deleteMatiere, deleteMatiere,
deleteEtudiant,
asygnationToMention, asygnationToMention,
getMentionMatiere, getMentionMatiere,
getMentionMatiereChecked, getMentionMatiereChecked,
@ -520,6 +522,12 @@ ipcMain.handle('updateMatiere', async (event, credentials) => {
return update return update
}) })
ipcMain.handle('updateMatiereNiveau', async (event, credentials) => {
// credentials = { niveau_id, id }
const update = await updateMatiereNiveau(credentials) // ✅ on passe id + niveau_id
return update
})
// event for importExcel // event for importExcel
ipcMain.handle('importexcel', async (event, credentials) => { ipcMain.handle('importexcel', async (event, credentials) => {
const files = credentials const files = credentials
@ -654,13 +662,13 @@ ipcMain.handle('deleteNiveaus', async (event, credentials) => {
const get = deleteNiveau(id) const get = deleteNiveau(id)
return get return get
}) })
ipcMain.handle('deleteMatiere', async (event, id) => {
return await deleteMatiere(id);
});
ipcMain.handle('deleteEtudiant', async (event, id) => {
return await deleteEtudiant(id);
});
ipcMain.handle('deleteMatiere', async (event, credentials) => {
const { id } = credentials
const get = deleteMatiere(id)
return get
})
ipcMain.handle('asign', async (event, credentials) => { ipcMain.handle('asign', async (event, credentials) => {
const { formData, id } = credentials const { formData, id } = credentials

2
src/preload/index.backup.js

@ -132,10 +132,12 @@ if (process.contextIsolated) {
createMatiere: (credentials) => ipcRenderer.invoke('createMatiere', credentials), createMatiere: (credentials) => ipcRenderer.invoke('createMatiere', credentials),
getMatiereByID: (credentials) => ipcRenderer.invoke('getMatiereByID', credentials), getMatiereByID: (credentials) => ipcRenderer.invoke('getMatiereByID', credentials),
updateMatiere: (credentials) => ipcRenderer.invoke('updateMatiere', credentials), updateMatiere: (credentials) => ipcRenderer.invoke('updateMatiere', credentials),
updateMatiereNiveau: (credentials) => ipcRenderer.invoke('updateMatiereNiveau', credentials),
importExcel: (credentials) => ipcRenderer.invoke('importExcelMatiere', credentials), importExcel: (credentials) => ipcRenderer.invoke('importExcelMatiere', credentials),
displayMatiereFromForm: (credentials) => displayMatiereFromForm: (credentials) =>
ipcRenderer.invoke('displayMatiereFromForm', credentials), ipcRenderer.invoke('displayMatiereFromForm', credentials),
deleteMatiere: (credentials) => ipcRenderer.invoke('deleteMatiere', credentials), deleteMatiere: (credentials) => ipcRenderer.invoke('deleteMatiere', credentials),
deleteEtudiant: (credentials) => ipcRenderer.invoke('deleteEtudiant', credentials),
asign: (credentials) => ipcRenderer.invoke('asign', credentials), asign: (credentials) => ipcRenderer.invoke('asign', credentials),
getAsign: (credentials) => ipcRenderer.invoke('getAsign', credentials), getAsign: (credentials) => ipcRenderer.invoke('getAsign', credentials),
asignSemestre: (credentials) => ipcRenderer.invoke('asignSemestre', credentials), asignSemestre: (credentials) => ipcRenderer.invoke('asignSemestre', credentials),

6
src/preload/index.js

@ -1,7 +1,6 @@
import { contextBridge, ipcRenderer } from 'electron' import { contextBridge, ipcRenderer } from 'electron'
import { electronAPI } from '@electron-toolkit/preload' import { electronAPI } from '@electron-toolkit/preload'
const { getNessesarytable } = require('../../database/function/System') const { getNessesarytable } = require('../../database/function/System')
const { getNiveau } = require('../../database/Models/Niveau')
const { getAllUsers } = require('../../database/Models/Users') const { getAllUsers } = require('../../database/Models/Users')
const { getAllEtudiants, getDataToDashboard } = require('../../database/Models/Etudiants') const { getAllEtudiants, getDataToDashboard } = require('../../database/Models/Etudiants')
const { verifyEtudiantIfHeHasNotes, blockShowMoyene } = require('../../database/Models/Notes') const { verifyEtudiantIfHeHasNotes, blockShowMoyene } = require('../../database/Models/Notes')
@ -12,6 +11,7 @@ const { getAnneeScolaire, getInterval } = require('../../database/Models/AnneeSc
const { getMentions } = require('../../database/Models/Mentions') const { getMentions } = require('../../database/Models/Mentions')
const { getAll } = require('../../database/api/Get') const { getAll } = require('../../database/api/Get')
const { getParcours } = require('../../database/Models/Parcours') const { getParcours } = require('../../database/Models/Parcours')
const { getNiveau } = require('../../database/Models/Niveau')
const { getIPConfig } = require('../../database/Models/IpConfig') const { getIPConfig } = require('../../database/Models/IpConfig')
// Custom APIs for renderer // Custom APIs for renderer
@ -128,10 +128,12 @@ if (process.contextIsolated) {
createMatiere: (credentials) => ipcRenderer.invoke('createMatiere', credentials), createMatiere: (credentials) => ipcRenderer.invoke('createMatiere', credentials),
getMatiereByID: (credentials) => ipcRenderer.invoke('getMatiereByID', credentials), getMatiereByID: (credentials) => ipcRenderer.invoke('getMatiereByID', credentials),
updateMatiere: (credentials) => ipcRenderer.invoke('updateMatiere', credentials), updateMatiere: (credentials) => ipcRenderer.invoke('updateMatiere', credentials),
updateMatiereNiveau: (credentials) => ipcRenderer.invoke('updateMatiereNiveau', credentials),
importExcel: (credentials) => ipcRenderer.invoke('importExcelMatiere', credentials), importExcel: (credentials) => ipcRenderer.invoke('importExcelMatiere', credentials),
displayMatiereFromForm: (credentials) => displayMatiereFromForm: (credentials) =>
ipcRenderer.invoke('displayMatiereFromForm', credentials), ipcRenderer.invoke('displayMatiereFromForm', credentials),
deleteMatiere: (credentials) => ipcRenderer.invoke('deleteMatiere', credentials), deleteMatiere: (id) => ipcRenderer.invoke('deleteMatiere', id),
deleteEtudiant: (id) => ipcRenderer.invoke('deleteEtudiant', id),
asign: (credentials) => ipcRenderer.invoke('asign', credentials), asign: (credentials) => ipcRenderer.invoke('asign', credentials),
getAsign: (credentials) => ipcRenderer.invoke('getAsign', credentials), getAsign: (credentials) => ipcRenderer.invoke('getAsign', credentials),
asignSemestre: (credentials) => ipcRenderer.invoke('asignSemestre', credentials), asignSemestre: (credentials) => ipcRenderer.invoke('asignSemestre', credentials),

2
src/renderer/src/assets/AllStyleComponents.module.css

@ -1,5 +1,5 @@
.h1style { .h1style {
text-transform: uppercase; /* text-transform: uppercase; */
font-weight: 900; font-weight: 900;
/* 6636af4a 6636af ffae01 */ /* 6636af4a 6636af ffae01 */
border-left: 10px solid #ffff; border-left: 10px solid #ffff;

8
src/renderer/src/components/AddAnneeScolaire.jsx

@ -98,7 +98,7 @@ const AddAnneeScolaire = () => {
{status === 200 ? ( {status === 200 ? (
<Typography style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}> <Typography style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
<img src={svgSuccess} alt="" width={50} height={50} />{' '} <img src={svgSuccess} alt="" width={50} height={50} />{' '}
<span>Année universitaire insérer avec succes</span> <span>Année Scolaire insérer avec succes</span>
</Typography> </Typography>
) : ( ) : (
<Typography style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}> <Typography style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
@ -136,7 +136,7 @@ const AddAnneeScolaire = () => {
<div className={classe.h1style}> <div className={classe.h1style}>
<div className={classeHome.blockTitle}> <div className={classeHome.blockTitle}>
<h1 style={{ display: 'flex', alignItems: 'center', gap: '10px' }}> <h1 style={{ display: 'flex', alignItems: 'center', gap: '10px' }}>
<FaCalendarPlus /> Ajout Année universitaire <FaCalendarPlus /> Ajout Année Scolaire
</h1> </h1>
<Link to={'#'} onClick={() => window.history.back()}> <Link to={'#'} onClick={() => window.history.back()}>
<Button color="warning" variant="contained"> <Button color="warning" variant="contained">
@ -170,12 +170,12 @@ const AddAnneeScolaire = () => {
}} }}
> >
<h4 style={{ textAlign: 'center', padding: '0 0 3% 0' }}> <h4 style={{ textAlign: 'center', padding: '0 0 3% 0' }}>
Creation de nouvelle année universitaire Creation de nouvelle Année Scolaire
</h4> </h4>
<Grid container spacing={2}> <Grid container spacing={2}>
<Grid item xs={12} sm={6}> <Grid item xs={12} sm={6}>
<TextField <TextField
label={'Année universitaire'} label={'Année Scolaire'}
name={'code'} name={'code'}
placeholder="2024-2025" placeholder="2024-2025"
color="warning" color="warning"

5
src/renderer/src/components/AddNotes.jsx

@ -52,6 +52,9 @@ const AddNotes = () => {
window.matieres.displayMatiereFromForm({ niveau, mention_id, parcours }).then((response) => { window.matieres.displayMatiereFromForm({ niveau, mention_id, parcours }).then((response) => {
setMatieres(response) setMatieres(response)
console.log("resulat teste:1", response);
console.log("resulat teste:2", mention_id);
console.log("resulat teste:3", parcours);
}) })
setIsSubmitted(false) setIsSubmitted(false)
} }
@ -109,6 +112,8 @@ const AddNotes = () => {
} }
} }
console.log('matiere: ',matieres);
const [statut, setStatut] = useState(200) const [statut, setStatut] = useState(200)
/** /**

6
src/renderer/src/components/AddStudent.jsx

@ -503,13 +503,13 @@ const AddStudent = () => {
variant="outlined" variant="outlined"
> >
<InputLabel id="demo-select-small-label" color="warning"> <InputLabel id="demo-select-small-label" color="warning">
Année Universitaire Année Scolaire
</InputLabel> </InputLabel>
<Select <Select
labelId="demo-select-small-label" labelId="demo-select-small-label"
id="demo-select-small" id="demo-select-small"
value={formData.annee_scolaire} value={formData.annee_scolaire}
label="Année Universitaire" label="Année Scolaire"
color="warning" color="warning"
size="small" size="small"
onChange={handleInputChange} onChange={handleInputChange}
@ -521,7 +521,7 @@ const AddStudent = () => {
<FaCalendarAlt /> <FaCalendarAlt />
</InputAdornment> </InputAdornment>
} }
label="Année Universitaire" label="Année Scolaire"
/> />
} }
sx={{ sx={{

4
src/renderer/src/components/AnneeScolaire.jsx

@ -48,7 +48,7 @@ const AnneeScolaire = () => {
const [ids, setIds] = useState(0) const [ids, setIds] = useState(0)
const column = [ const column = [
{ field: 'code', headerName: 'Année universitaire', width: 130 }, { field: 'code', headerName: 'Année Scolaire', width: 130 },
{ field: 'debut', headerName: 'Date de début', width: 130 }, { field: 'debut', headerName: 'Date de début', width: 130 },
{ field: 'fin', headerName: 'Date de fin', width: 130 }, { field: 'fin', headerName: 'Date de fin', width: 130 },
{ {
@ -259,7 +259,7 @@ const AnneeScolaire = () => {
<div className={classe.h1style}> <div className={classe.h1style}>
<div className={classeHome.blockTitle}> <div className={classeHome.blockTitle}>
<h1 style={{ display: 'flex', alignItems: 'center', gap: '10px' }}> <h1 style={{ display: 'flex', alignItems: 'center', gap: '10px' }}>
<BsCalendar2Date /> Année Universitaire <BsCalendar2Date /> Année Scolaire
</h1> </h1>
<Link to={'/addanneescolaire'}> <Link to={'/addanneescolaire'}>
<Button color="warning" variant="contained"> <Button color="warning" variant="contained">

2
src/renderer/src/components/Apropos.jsx

@ -47,7 +47,7 @@ const Apropos = () => {
<p style={{ color: 'black' }}> <p style={{ color: 'black' }}>
Nom du Logiciel: CUniversity <br /> Nom du Logiciel: CUniversity <br />
<br /> Description : logiciel de gestion d'universiter <br /> <br /> <br /> Description : logiciel de gestion d'espt <br /> <br />
Createur: CPAY COMPANY FOR MADAGASCAR <br /> Createur: CPAY COMPANY FOR MADAGASCAR <br />
<br /> Licence: A vie <br /> <br /> Licence: A vie <br />
<br /> Contact: 0348415301 <br /> Contact: 0348415301

38
src/renderer/src/components/ExportEtudiants.jsx

@ -142,25 +142,35 @@ const ExportEtudiants = () => {
* fonction qui envoye dans le back * fonction qui envoye dans le back
*/ */
const handleImport = async () => { const handleImport = async () => {
// Code to handle file import (can open a file dialog or call handleFileChange) if (!files) {
setError("Veuillez choisir un fichier d'abord.")
let response = await window.etudiants.importExcel(files.path) return
console.log(response)
if (response.message) {
setMessage(response.message)
} }
try {
if (response.error) { let response = await window.etudiants.importExcel(files.path)
setIsinserted(true)
setOpen(true) console.log(response)
setTableData([])
} else { if (response.message) {
setMessage(response.message)
}
if (response.error) {
setIsinserted(false)
setOpen(true)
// Ne vide pas tableData, ça permet à l'utilisateur de corriger le fichier
} else {
setIsinserted(true)
setOpen(true)
setTableData([]) // vider seulement si insertion réussie
}
} catch (err) {
setMessage('Erreur inattendue lors de l’import')
setIsinserted(false) setIsinserted(false)
setOpen(true) setOpen(true)
} }
} }
/** /**
* hook to open modal * hook to open modal

78
src/renderer/src/components/Matieres.jsx

@ -28,9 +28,12 @@ import ParcourMatiere from './ParcourMatiere'
import UpdateModalProf from './UpdateModalProf' import UpdateModalProf from './UpdateModalProf'
import ModalProcessFichePresence from './ModalProcessFichePresence' import ModalProcessFichePresence from './ModalProcessFichePresence'
import ModalExportFichr from './ModalExportFichr' import ModalExportFichr from './ModalExportFichr'
import NiveauMatiere from './NiveauMatiere'
const Matieres = () => { const Matieres = () => {
const [matiere, setMatiere] = useState([]) const [matiere, setMatiere] = useState([])
const [openAssignNiveau, setOpenAssignNiveau] = useState(false)
const [matiereIdAssign, setMatiereIdAssign] = useState(null)
const [Enseignants, setEnseignants] = useState([]) const [Enseignants, setEnseignants] = useState([])
useEffect(() => { useEffect(() => {
@ -62,6 +65,29 @@ const Matieres = () => {
} }
}) })
const openAssignNiveauModal = (id) => {
setMatiereIdAssign(id)
setOpenAssignNiveau(true)
}
const closeAssignNiveauModal = () => {
setOpenAssignNiveau(false)
setMatiereIdAssign(null)
}
const handleNiveauAssignSuccess = (status) => {
if (status) {
// Rafraîchir les données des matières et enseignants
window.matieres.getMatiere().then((response) => {
setMatiere(response)
})
window.matieres.getENseignant().then((response) => {
setEnseignants(response)
})
}
}
const [isDeleted, setIsDeleted] = useState(false) const [isDeleted, setIsDeleted] = useState(false)
const [ids, setIds] = useState(0) const [ids, setIds] = useState(0)
@ -71,6 +97,7 @@ const Matieres = () => {
{ field: 'heure', headerName: 'Heure', width: 80 }, { field: 'heure', headerName: 'Heure', width: 80 },
{ field: 'uniter', headerName: "Unité d'enseignement", width: 180 }, { field: 'uniter', headerName: "Unité d'enseignement", width: 180 },
{ field: 'ue', headerName: 'UE', width: 80 }, { field: 'ue', headerName: 'UE', width: 80 },
{ field: 'niveau_id', headerName: 'Niveau', width: 80 },
{ field: 'enseignant', headerName: 'Professeur actuele', width: 230 }, { field: 'enseignant', headerName: 'Professeur actuele', width: 230 },
{ {
field: 'action', field: 'action',
@ -109,23 +136,47 @@ const Matieres = () => {
</Button> </Button>
</Link> </Link>
<Link <Link
to={`/asignmatieresemestre/${params.value}`} to={`/asignmatieresemestre/${params.value}`}
className={`sem${params.value}`} className={`sem${params.value}`}
style={{ textDecoration: 'none' }}
>
<Tooltip
anchorSelect={`.sem${params.value}`}
style={{ fontSize: '15px', zIndex: 9 }}
place="top"
>
Assigner à un semestre
</Tooltip>
<Button color="warning" variant="contained">
<FaS style={{ fontSize: '20px', color: 'white' }} />
</Button>
</Link>
{/* ----------- BOUTON ASSIGNER NIVEAU ----------- */}
<Link
to="#"
className={`niveau${params.value}`}
style={{ textDecoration: 'none' }} style={{ textDecoration: 'none' }}
onClick={(e) => {
e.preventDefault(); // empêche le # de provoquer un scroll
openAssignNiveauModal(params.value);
}}
> >
<Tooltip <Tooltip
anchorSelect={`.sem${params.value}`} anchorSelect={`.niveau${params.value}`}
style={{ fontSize: '15px', zIndex: 9 }} style={{ fontSize: '15px', zIndex: 9 }}
place="top" place="top"
> >
Assigner à un semestre Assigner à un niveau
</Tooltip> </Tooltip>
<Button color="warning" variant="contained"> <Button color="warning" variant="contained">
<FaS style={{ fontSize: '20px', color: 'white' }} /> {/* Icône de ton choix, ici FaRegPlusSquare par exemple */}
<FaRegPlusSquare style={{ fontSize: '20px', color: 'white' }} />
</Button> </Button>
</Link> </Link>
<Link <Link
to={`#`} to="#"
style={{ textDecoration: 'none' }} style={{ textDecoration: 'none' }}
className={`parcour${params.value}`} className={`parcour${params.value}`}
onClick={() => openParcoursFunction(params.value)} onClick={() => openParcoursFunction(params.value)}
@ -141,6 +192,7 @@ const Matieres = () => {
<FaP style={{ fontSize: '20px', color: 'white' }} /> <FaP style={{ fontSize: '20px', color: 'white' }} />
</Button> </Button>
</Link> </Link>
<Link to={`#`}> <Link to={`#`}>
<Button color="warning" variant="contained"> <Button color="warning" variant="contained">
<GiTeacher <GiTeacher
@ -253,13 +305,14 @@ const Matieres = () => {
heure: mat.heure, heure: mat.heure,
uniter: mat.unite_enseignement, uniter: mat.unite_enseignement,
ue: mat.ue, ue: mat.ue,
niveau_id: mat.niveau_nom ?? 'pas de niveau',
enseignant: enseignant:
compareMatieres(mat.id) != '' ? compareMatieres(mat.id) : 'Veuillez assigner un professeur', compareMatieres(mat.id) != '' ? compareMatieres(mat.id) : 'Veuillez assigner un professeur',
action: mat.id // Ensure this is a valid URL for the image action: mat.id // Ensure this is a valid URL for the image
})) }))
const deleteButton = async (id) => { const deleteButton = async (id) => {
let response = await window.matieres.deleteMatiere({ id }) let response = await window.matieres.deleteMatiere(id);
if (response.success) { if (response.success) {
const updatedMatieres = matiere.filter((matiere) => matiere.id !== id) const updatedMatieres = matiere.filter((matiere) => matiere.id !== id)
setMatiere(updatedMatieres) setMatiere(updatedMatieres)
@ -431,6 +484,15 @@ const Matieres = () => {
open={openUppdateProf} open={openUppdateProf}
/> />
<ModalProcessFichePresence matiere_id={matiereId} onClose={onCloseFiche} open={openFiche} /> <ModalProcessFichePresence matiere_id={matiereId} onClose={onCloseFiche} open={openFiche} />
{/* Modal NiveauMatiere */}
<NiveauMatiere
open={openAssignNiveau}
onClose={closeAssignNiveauModal}
matiere_id={matiereIdAssign}
onSubmitSuccess={handleNiveauAssignSuccess}
/>
<div className={classeAdd.header}> <div className={classeAdd.header}>
<div className={classe.h1style}> <div className={classe.h1style}>
<div className={classeHome.blockTitle}> <div className={classeHome.blockTitle}>
@ -499,4 +561,4 @@ const Matieres = () => {
) )
} }
export default Matieres export default Matieres

2
src/renderer/src/components/ModalExportFichr.jsx

@ -170,7 +170,7 @@ const ModalExportFichr = () => {
</tr> </tr>
<tr style={{ borderBottom: 'solid 1px gray' }}> <tr style={{ borderBottom: 'solid 1px gray' }}>
<th style={{ borderRight: 'solid 1px gray' }}>N°</th> <th style={{ borderRight: 'solid 1px gray' }}>N°</th>
<th style={{ borderRight: 'solid 1px gray' }}>Nom et Prénom</th> <th style={{ borderRight: 'solid 1px gray' }}>Nom et Prenom</th>
<th style={{ borderRight: 'solid 1px gray' }}>Mention</th> <th style={{ borderRight: 'solid 1px gray' }}>Mention</th>
<th>Emergement</th> <th>Emergement</th>
</tr> </tr>

132
src/renderer/src/components/NiveauMatiere.jsx

@ -0,0 +1,132 @@
import React, { useEffect, useState } from 'react';
import {
Dialog,
DialogActions,
DialogContent,
DialogTitle,
Button,
Box,
Grid,
FormControl,
InputLabel,
Select,
OutlinedInput,
MenuItem
} from '@mui/material'
const NiveauMatiere = ({ open, onClose, matiere_id }) => {
const [formData, setFormData] = useState({
niveau_id: '',
id: ''
})
const [niveaux, setNiveaux] = useState([])
const [niveauxMatiere, setNiveauxMatiere] = useState([])
console.log(niveaux);
useEffect(() => {
window.niveaus.getNiveau().then((response) => {
setNiveaux(response)
})
}, [])
useEffect(() => {
if (niveauxMatiere.length !== 0) {
const niveauIds = niveauxMatiere.map((item) => item.niveau_id)
setFormData((prevState) => ({
...prevState,
niveau_id: niveauIds
}))
}
}, [niveauxMatiere])
useEffect(() => {
if (matiere_id) {
setFormData(prev => ({
...prev,
id: matiere_id
}));
}
}, [matiere_id]);
const handleChange = (event) => {
const { name, value } = event.target
setFormData(prevState => ({
...prevState,
niveau_id: value // pas de tableau
}));
}
const formSubmit = async (e) => {
e.preventDefault();
console.log("Form envoyé côté front:", formData);
let response = await window.matieres.updateMatiereNiveau(formData);
console.log("Réponse backend:", response);
if (response.success) {
onClose();
}
};
return (
<Dialog open={open} onClose={onClose}>
<form action="" onSubmit={formSubmit}>
<DialogTitle>Assignation à des niveaux</DialogTitle>
<DialogContent>
<Box sx={{ flexGrow: 1 }}>
<Grid container spacing={2}>
<Grid item xs={12} sm={6}>
<FormControl sx={{ m: 1, width: 300 }}>
<InputLabel id="niveaux-select-label" color="warning">
Niveaux
</InputLabel>
<Select
labelId="niveaux-select-label"
id="niveaux-select"
name="niveau_id"
value={formData.niveau_id || ''}
onChange={handleChange}
color="warning"
size="small"
required
input={<OutlinedInput label="Niveaux" />}
MenuProps={{
PaperProps: {
style: {
maxHeight: 200,
width: 250
}
}
}}
>
{niveaux.map((niveau) => (
<MenuItem key={niveau.niveau_id} value={niveau.niveau_id}>
{niveau.nom}
</MenuItem>
))}
</Select>
</FormControl>
</Grid>
</Grid>
</Box>
</DialogContent>
<DialogActions>
<Button onClick={onClose} color="error">
Annuler
</Button>
<Button type="submit" color="warning">
Soumettre
</Button>
</DialogActions>
</form>
</Dialog>
)
}
export default NiveauMatiere

2
src/renderer/src/components/ParcourMatiere.jsx

@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react' import React, { useEffect, useState } from 'react';
import { import {
Dialog, Dialog,
DialogActions, DialogActions,

2
src/renderer/src/components/Parcours.jsx

@ -81,7 +81,7 @@ const Parcours = () => {
id: parc.id, id: parc.id,
nom: parc.nom, nom: parc.nom,
uniter: parc.uniter, uniter: parc.uniter,
mention: parc.mention_id, mention: parc.mention_nom || parc.mention || 'Mention non trouvée',
action: parc.id action: parc.id
})) }))

4
src/renderer/src/components/Resultat.jsx

@ -187,13 +187,13 @@ const Resultat = () => {
<tr> <tr>
<td colSpan={4} className="py-3"> <td colSpan={4} className="py-3">
<h6> <h6>
Niveau {niveau} | Année universitaire {scolaire} Niveau {niveau} | Année Scolaire {scolaire}
</h6> </h6>
</td> </td>
</tr> </tr>
<tr> <tr>
<th>Nom</th> <th>Nom</th>
<th>Prénom</th> <th>Prenom</th>
<th>Mention</th> <th>Mention</th>
<th>Moyenne</th> <th>Moyenne</th>
</tr> </tr>

2
src/renderer/src/components/Sidenav.jsx

@ -153,7 +153,7 @@ const Sidenav = () => {
> >
<BsCalendar2Date className="anneescolaire" style={{ outline: 'none' }} /> <BsCalendar2Date className="anneescolaire" style={{ outline: 'none' }} />
<Tooltip anchorSelect=".anneescolaire" className="custom-tooltip" place="top"> <Tooltip anchorSelect=".anneescolaire" className="custom-tooltip" place="top">
Année Universitaire Année Scolaire
</Tooltip> </Tooltip>
</Link> </Link>
</li> </li>

6
src/renderer/src/components/SingleAnneeScolaire.jsx

@ -121,7 +121,7 @@ const SingleAnneeScolaire = () => {
<div className={classeHome.blockTitle}> <div className={classeHome.blockTitle}>
<h1 style={{ display: 'flex', alignItems: 'center', gap: '10px' }}> <h1 style={{ display: 'flex', alignItems: 'center', gap: '10px' }}>
<BsCalendar2Date /> <BsCalendar2Date />
Mise a jour Année universitaire Mise a jour Année Scolaire
</h1> </h1>
<Link to={'#'} onClick={() => window.history.back()}> <Link to={'#'} onClick={() => window.history.back()}>
<Button color="warning" variant="contained"> <Button color="warning" variant="contained">
@ -155,12 +155,12 @@ const SingleAnneeScolaire = () => {
onSubmit={formSubmit} onSubmit={formSubmit}
> >
<h4 style={{ textAlign: 'center', padding: '0 0 3% 0' }}> <h4 style={{ textAlign: 'center', padding: '0 0 3% 0' }}>
mise a jour année universitaire mise a jour Année Scolaire
</h4> </h4>
<Grid container spacing={2}> <Grid container spacing={2}>
<Grid item xs={12} sm={6}> <Grid item xs={12} sm={6}>
<TextField <TextField
label={'Année universitaire'} label={'Année Scolaire'}
name={'code'} name={'code'}
placeholder="2024-2025" placeholder="2024-2025"
color="warning" color="warning"

2
src/renderer/src/components/SingleEtudiant.jsx

@ -540,7 +540,7 @@ const SingleEtudiant = () => {
<Grid item xs={6}> <Grid item xs={6}>
<TextField <TextField
fullWidth fullWidth
label="Année Universitaire" label="Année Scolaire"
name="annee_scolaire" name="annee_scolaire"
color="warning" color="warning"
defaultValue={etudiant.annee_scolaire} // Controlled component value defaultValue={etudiant.annee_scolaire} // Controlled component value

36
src/renderer/src/components/Student.jsx

@ -227,7 +227,7 @@ const Student = () => {
<Link style={{ display: 'flex', gap: '10px' }}> <Link style={{ display: 'flex', gap: '10px' }}>
<SeeNote params={params} /> <SeeNote params={params} />
<Link> <Link>
<Button <Button
onClick={() => handleOpen(params.value)} onClick={() => handleOpen(params.value)}
color="warning" color="warning"
variant="contained" variant="contained"
@ -309,16 +309,22 @@ const Student = () => {
} }
} }
// const paginationModel = { page: 0, pageSize: 20 } // PAGINATION CORRIGÉE - États pour la pagination complète
const [pageSize, setPageSize] = useState(20) const [paginationModel, setPaginationModel] = useState({
page: 0,
pageSize: 20
})
const [pageSizeOptions, setPageSizeOptions] = useState([20, 40, 60]) const [pageSizeOptions, setPageSizeOptions] = useState([20, 40, 60])
const handlePageSizeChange = (newPageSize) => { // Gestionnaire complet pour les changements de pagination (page ET pageSize)
setPageSize(newPageSize) const handlePaginationModelChange = (newModel) => {
console.log('📊 Pagination changed:', newModel) // Pour debug
// If the user picked the largest value, add next +20
setPaginationModel(newModel)
// Si l'utilisateur choisit la plus grande option, ajouter +20
const maxOption = Math.max(...pageSizeOptions) const maxOption = Math.max(...pageSizeOptions)
if (newPageSize === maxOption) { if (newModel.pageSize === maxOption) {
setPageSizeOptions((prev) => [...prev, maxOption + 20]) setPageSizeOptions((prev) => [...prev, maxOption + 20])
} }
} }
@ -360,16 +366,20 @@ const Student = () => {
} }
/** /**
* function to filter the data in dataGrid by Niveau * Fonction de filtrage avec reset de pagination
*/ */
const FilterData = async (e) => { const FilterData = async (e) => {
let niveau = e.target.value let niveau = e.target.value
if (niveau !== '') { if (niveau !== '') {
let data = await window.etudiants.FilterDataByNiveau({ niveau }) let data = await window.etudiants.FilterDataByNiveau({ niveau })
setEtudiants(data) setEtudiants(data)
// Reset vers la première page après filtrage
setPaginationModel(prev => ({ ...prev, page: 0 }))
} else { } else {
window.etudiants.getEtudiants().then((response) => { window.etudiants.getEtudiants().then((response) => {
setEtudiants(response) setEtudiants(response)
// Reset vers la première page
setPaginationModel(prev => ({ ...prev, page: 0 }))
}) })
} }
} }
@ -541,11 +551,9 @@ const Student = () => {
<DataGrid <DataGrid
rows={dataRow} rows={dataRow}
columns={columns} columns={columns}
// initialState={{ pagination: { paginationModel } }}
// pageSizeOptions={[20, 40, 60]}
pageSizeOptions={pageSizeOptions} pageSizeOptions={pageSizeOptions}
paginationModel={{ pageSize, page: 0 }} paginationModel={paginationModel} // Utilise l'état complet
onPaginationModelChange={(model) => handlePageSizeChange(model.pageSize)} onPaginationModelChange={handlePaginationModelChange} // Gère page ET pageSize
sx={{ sx={{
border: 0, border: 0,
width: 'auto', // Ensures the DataGrid takes full width width: 'auto', // Ensures the DataGrid takes full width
@ -573,4 +581,4 @@ const Student = () => {
) )
} }
export default Student export default Student

2
src/renderer/src/components/TesteDatagrid.jsx

@ -248,7 +248,7 @@ const TesteDatagrid = ({ id, niveau, annee_scolaire, nomPrenom, inscription, ref
</div> </div>
</div> </div>
<div style={{ fontSize: '13px', margin: '1%' }}> <div style={{ fontSize: '13px', margin: '1%' }}>
<span>Nom & Prénoms: </span> <span>Nom & Prenoms: </span>
<span>{nomPrenom}</span> <span>{nomPrenom}</span>
<br /> <br />
<div style={{ display: 'flex', justifyContent: 'space-between' }}> <div style={{ display: 'flex', justifyContent: 'space-between' }}>

1
src/renderer/src/components/UpdateTranche.jsx

@ -47,7 +47,6 @@ const UpdateTranche = ({ open, onClose, onSubmitSuccess, id }) => {
const handleSubmit = async (e) => { const handleSubmit = async (e) => {
e.preventDefault() e.preventDefault()
console.log(formData)
let response = await window.etudiants.updateTranche(formData) let response = await window.etudiants.updateTranche(formData)
if (response.changes) { if (response.changes) {

2
src/renderer/src/components/function/GenerateFiche.js

@ -40,7 +40,7 @@ export const generatePDF = async (students) => {
y -= 30 y -= 30
const headers = ['N°', 'Nom et Prénom', 'Mention', 'Émergement'] const headers = ['N°', 'Nom et Prenom', 'Mention', 'Émergement']
const columnWidths = [50, 200, 100, 100] const columnWidths = [50, 200, 100, 100]
const xPositions = [ const xPositions = [
margin, margin,

2
src/renderer/src/components/function/PDFEditor.js

@ -73,7 +73,7 @@ const PDFEditor = async (data) => {
// ----------------------------------------------- carte arriere ------------------------------------------- // ----------------------------------------------- carte arriere -------------------------------------------
const paperContent = ` const paperContent = `
CUniversity CUniversity
Nom et prénom: ${data.f1} Nom et prenom: ${data.f1}
Date de naissance: ${data.f2} Date de naissance: ${data.f2}
Niveau: ${data.f3} Niveau: ${data.f3}
Année scolaire: ${data.f4} Année scolaire: ${data.f4}

2
src/renderer/src/components/function/PDFEditorV2.js

@ -79,7 +79,7 @@ async function fillPdfFields(jsonData) {
const paperContent = ` const paperContent = `
C-University C-University
Nom et prénom: ${jsonData.f1} Nom et prenom: ${jsonData.f1}
Date de naissance: ${jsonData.f2} Date de naissance: ${jsonData.f2}
Niveau: ${jsonData.f3} Niveau: ${jsonData.f3}
Année scolaire: ${jsonData.f4} Année scolaire: ${jsonData.f4}

2
src/renderer/src/test/qr.html

@ -23,7 +23,7 @@
</div> </div>
<div class="cart-info"> <div class="cart-info">
<p><b>Nom</b> : BE</p> <p><b>Nom</b> : BE</p>
<p><b>Prénom</b> : Joseph Fabrice</p> <p><b>Prenom</b> : Joseph Fabrice</p>
<p><b>Date de naissance</b> : 11-12-2001</p> <p><b>Date de naissance</b> : 11-12-2001</p>
<p><b>Niveau</b> : L3</p> <p><b>Niveau</b> : L3</p>
<p><b>Année scolaire</b> : 2023-2024</p> <p><b>Année scolaire</b> : 2023-2024</p>

2
src/renderer/src/test/relever.html

@ -19,7 +19,7 @@
<div class="releve"> <div class="releve">
<h3>RELEVÉE DE NOTE</h3> <h3>RELEVÉE DE NOTE</h3>
<p><strong>Nom & Prénoms :</strong> F3</p> <p><strong>Nom & Prenoms :</strong> F3</p>
<p> <p>
<strong>Niveau :</strong> L1 <span><strong>Année scolaire :</strong> 2022-2023</span> <strong>Niveau :</strong> L1 <span><strong>Année scolaire :</strong> 2022-2023</span>
</p> </p>

2
text.txt

@ -244,7 +244,7 @@ const FileUploader = () => {
<thead> <thead>
<tr> <tr>
<th>Nom</th> <th>Nom</th>
<th>Prénom</th> <th>Prenom</th>
<th>Photos</th> <th>Photos</th>
<th>Date de Naissances</th> <th>Date de Naissances</th>
<th>Niveau</th> <th>Niveau</th>

Loading…
Cancel
Save