@ -0,0 +1,14 @@ |
|||
[ |
|||
{ |
|||
"type": "sqlite", |
|||
"path": "c:\\laragon\\www\\electron-react\\data.db" |
|||
}, |
|||
{ |
|||
"type": "sqlite", |
|||
"path": "c:\\laragon\\www\\electron-react\\base\\data.db" |
|||
}, |
|||
{ |
|||
"type": "sqlite", |
|||
"path": "d:\\dart\\project\\CUNIVERSITY\\base\\data.db" |
|||
} |
|||
] |
|||
@ -0,0 +1,9 @@ |
|||
root = true |
|||
|
|||
[*] |
|||
charset = utf-8 |
|||
indent_style = space |
|||
indent_size = 2 |
|||
end_of_line = lf |
|||
insert_final_newline = true |
|||
trim_trailing_whitespace = true |
|||
@ -0,0 +1,4 @@ |
|||
node_modules |
|||
dist |
|||
out |
|||
.gitignore |
|||
@ -0,0 +1,9 @@ |
|||
module.exports = { |
|||
extends: [ |
|||
'eslint:recommended', |
|||
'plugin:react/recommended', |
|||
'plugin:react/jsx-runtime', |
|||
'@electron-toolkit', |
|||
'@electron-toolkit/eslint-config-prettier' |
|||
] |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
node_modules |
|||
dist |
|||
out |
|||
fashion-street-style-horizontal-business-card-template.zip |
|||
.DS_Store |
|||
*.log* |
|||
data.db |
|||
package-lock.json |
|||
@ -0,0 +1,6 @@ |
|||
out |
|||
dist |
|||
pnpm-lock.yaml |
|||
LICENSE.md |
|||
tsconfig.json |
|||
tsconfig.*.json |
|||
@ -0,0 +1,4 @@ |
|||
singleQuote: true |
|||
semi: false |
|||
printWidth: 100 |
|||
trailingComma: none |
|||
@ -0,0 +1,3 @@ |
|||
{ |
|||
"recommendations": ["dbaeumer.vscode-eslint"] |
|||
} |
|||
@ -0,0 +1,39 @@ |
|||
{ |
|||
"version": "0.2.0", |
|||
"configurations": [ |
|||
{ |
|||
"name": "Debug Main Process", |
|||
"type": "node", |
|||
"request": "launch", |
|||
"cwd": "${workspaceRoot}", |
|||
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron-vite", |
|||
"windows": { |
|||
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron-vite.cmd" |
|||
}, |
|||
"runtimeArgs": ["--sourcemap"], |
|||
"env": { |
|||
"REMOTE_DEBUGGING_PORT": "9222" |
|||
} |
|||
}, |
|||
{ |
|||
"name": "Debug Renderer Process", |
|||
"port": 9222, |
|||
"request": "attach", |
|||
"type": "chrome", |
|||
"webRoot": "${workspaceFolder}/src/renderer", |
|||
"timeout": 60000, |
|||
"presentation": { |
|||
"hidden": true |
|||
} |
|||
} |
|||
], |
|||
"compounds": [ |
|||
{ |
|||
"name": "Debug All", |
|||
"configurations": ["Debug Main Process", "Debug Renderer Process"], |
|||
"presentation": { |
|||
"order": 1 |
|||
} |
|||
} |
|||
] |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
{ |
|||
"[typescript]": { |
|||
"editor.defaultFormatter": "esbenp.prettier-vscode" |
|||
}, |
|||
"[javascript]": { |
|||
"editor.defaultFormatter": "vscode.typescript-language-features" |
|||
}, |
|||
"[json]": { |
|||
"editor.defaultFormatter": "esbenp.prettier-vscode" |
|||
}, |
|||
"editor.wordBasedSuggestions": "matchingDocuments" |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
# package.json |
|||
|
|||
An Electron application with React |
|||
|
|||
## Recommended IDE Setup |
|||
|
|||
- [VSCode](https://code.visualstudio.com/) + [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) + [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) |
|||
|
|||
## Project Setup |
|||
|
|||
### Install |
|||
|
|||
```bash |
|||
$ npm install |
|||
``` |
|||
|
|||
### Development |
|||
|
|||
```bash |
|||
$ npm run dev |
|||
``` |
|||
|
|||
### Build |
|||
|
|||
```bash |
|||
# For windows |
|||
$ npm run build:win |
|||
|
|||
# For macOS |
|||
$ npm run build:mac |
|||
|
|||
# For Linux |
|||
$ npm run build:linux |
|||
``` |
|||
@ -0,0 +1,118 @@ |
|||
import { app, shell, BrowserWindow, ipcMain } from 'electron' |
|||
import { join } from 'path' |
|||
import { electronApp, optimizer, is } from '@electron-toolkit/utils' |
|||
import icon from '../../resources/icon.png?asset' |
|||
const { loginUser, forgotPassword } = require('../../database/Models/Users') |
|||
|
|||
let mainWindow |
|||
let splashWindow |
|||
|
|||
function createSplashWindow() { |
|||
// Create the splash screen window
|
|||
splashWindow = new BrowserWindow({ |
|||
width: 400, // Width of the splash screen
|
|||
height: 300, // Height of the splash screen
|
|||
frame: false, // Remove window frame for a cleaner look
|
|||
alwaysOnTop: true, // Keep the splash screen on top of the main window
|
|||
transparent: true, // Make the window background transparent (optional)
|
|||
resizable: false, |
|||
webPreferences: { |
|||
nodeIntegration: true, |
|||
contextIsolation: false |
|||
} |
|||
}) |
|||
|
|||
// Load your splash screen HTML or content
|
|||
splashWindow.loadFile(join('src/renderer/splash.html')) // Adjust path to your splash HTML file
|
|||
} |
|||
|
|||
function createMainWindow() { |
|||
// Create the main browser window
|
|||
mainWindow = new BrowserWindow({ |
|||
width: 1000, |
|||
minWidth: 1000, |
|||
height: 670, |
|||
minHeight: 670, |
|||
show: false, |
|||
autoHideMenuBar: true, |
|||
fullscreen: true, // This will make the window fullscreen when opened
|
|||
...(process.platform === 'linux' ? { icon } : {}), |
|||
webPreferences: { |
|||
preload: join(__dirname, '../preload/index.js'), |
|||
nodeIntegration: true, |
|||
contextIsolation: true, |
|||
sandbox: false |
|||
} |
|||
}) |
|||
|
|||
mainWindow.on('ready-to-show', () => { |
|||
// Show the main window after it is ready
|
|||
mainWindow.show() |
|||
splashWindow.close() // Close the splash screen
|
|||
}) |
|||
|
|||
mainWindow.webContents.setWindowOpenHandler((details) => { |
|||
shell.openExternal(details.url) |
|||
return { action: 'deny' } |
|||
}) |
|||
|
|||
// Load the remote URL for development or the local HTML file for production
|
|||
if (is.dev && process.env['ELECTRON_RENDERER_URL']) { |
|||
mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL']) |
|||
} else { |
|||
mainWindow.loadFile(join(__dirname, '../renderer/index.html')) |
|||
} |
|||
} |
|||
|
|||
// This method will be called when Electron has finished
|
|||
// initialization and is ready to create browser windows.
|
|||
// Some APIs can only be used after this event occurs.
|
|||
app.whenReady().then(() => { |
|||
// Set app user model ID for Windows
|
|||
electronApp.setAppUserModelId('com.electron') |
|||
|
|||
// Create splash screen
|
|||
createSplashWindow() |
|||
|
|||
// Create main window
|
|||
createMainWindow() |
|||
|
|||
app.on('activate', function () { |
|||
// On macOS, recreate a window in the app when the dock icon is clicked
|
|||
if (BrowserWindow.getAllWindows().length === 0) createMainWindow() |
|||
}) |
|||
}) |
|||
|
|||
// Quit when all windows are closed, except on macOS.
|
|||
app.on('window-all-closed', () => { |
|||
if (process.platform !== 'darwin') { |
|||
app.quit() |
|||
} |
|||
}) |
|||
|
|||
// In this file you can include the rest of your app"s specific main process
|
|||
// code. You can also put them in separate files and require them here.
|
|||
|
|||
// Event for handling login
|
|||
ipcMain.handle('login', async (event, credentials) => { |
|||
const { username, password } = credentials |
|||
|
|||
const users = await loginUser(username, password) |
|||
|
|||
if (users) { |
|||
return { success: true, user: users } |
|||
} else { |
|||
return { success: false } |
|||
} |
|||
}) |
|||
|
|||
// event for handlign forgot password
|
|||
ipcMain.handle('forgotPassword', async (event, credentials) => { |
|||
const { email, password, passwordConfirmation } = credentials |
|||
|
|||
const updated = await forgotPassword(email, password, passwordConfirmation) |
|||
|
|||
if (updated) { |
|||
return updated |
|||
} |
|||
}) |
|||
@ -0,0 +1,12 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
|||
<plist version="1.0"> |
|||
<dict> |
|||
<key>com.apple.security.cs.allow-jit</key> |
|||
<true/> |
|||
<key>com.apple.security.cs.allow-unsigned-executable-memory</key> |
|||
<true/> |
|||
<key>com.apple.security.cs.allow-dyld-environment-variables</key> |
|||
<true/> |
|||
</dict> |
|||
</plist> |
|||
|
After Width: | Height: | Size: 121 KiB |
|
After Width: | Height: | Size: 35 KiB |
@ -0,0 +1,113 @@ |
|||
const { database } = require('../database') |
|||
|
|||
/** |
|||
* function to create annee scolaire |
|||
* @param {*} code |
|||
* @param {*} debut |
|||
* @param {*} fin |
|||
* @returns promise |
|||
*/ |
|||
async function createAnneeScolaire(code, debut, fin) { |
|||
const query = database.prepare('INSERT INTO anneescolaire (code, debut, fin) VALUES (?, ?, ?)') |
|||
|
|||
try { |
|||
let response = await query.run(code, debut, fin) |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* function to get all année scolaire |
|||
* @returns promise |
|||
*/ |
|||
async function getAnneeScolaire() { |
|||
const query = database.prepare('SELECT * FROM anneescolaire ORDER BY code DESC') |
|||
|
|||
try { |
|||
let response = await query.all() |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
async function getInterval() { |
|||
const query = database.prepare('SELECT debut, fin FROM anneescolaire ORDER BY id DESC') |
|||
|
|||
try { |
|||
let response = await query.all() |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
async function getSingleAnneScolaire(id) { |
|||
const query = database.prepare('SELECT * FROM anneescolaire WHERE id = ?') |
|||
|
|||
try { |
|||
let response = await query.get(id) |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
async function deleteAnneeScolaire(id) { |
|||
const query = database.prepare('DELETE FROM anneescolaire WHERE id = ?') |
|||
|
|||
try { |
|||
let response = query.run(id) |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
async function updateAnneeScolaire(id, code, debut, fin) { |
|||
const query = database.prepare( |
|||
'UPDATE anneescolaire SET code = ?, debut = ?, fin = ? WHERE id = ?' |
|||
) |
|||
|
|||
try { |
|||
let response = query.run(code, debut, fin, id) |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
async function setCurrent(id) { |
|||
const query = database.prepare( |
|||
'UPDATE anneescolaire SET is_current = 0 WHERE id > 0 AND is_current = 1' |
|||
) |
|||
const query2 = database.prepare('UPDATE anneescolaire SET is_current = 1 WHERE id = ?') |
|||
|
|||
let clear = query.run() |
|||
console.log(clear) |
|||
try { |
|||
let response = query2.run(id) |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
module.exports = { |
|||
createAnneeScolaire, |
|||
getAnneeScolaire, |
|||
getInterval, |
|||
deleteAnneeScolaire, |
|||
getSingleAnneScolaire, |
|||
updateAnneeScolaire, |
|||
setCurrent |
|||
} |
|||
@ -0,0 +1,305 @@ |
|||
const { database } = require('../database') |
|||
|
|||
/** |
|||
* function to insert etudiant into databases |
|||
*/ |
|||
async function insertEtudiant( |
|||
nom, |
|||
prenom, |
|||
photos, |
|||
date_de_naissances, |
|||
niveau, |
|||
annee_scolaire, |
|||
status, |
|||
num_inscription, |
|||
mention_id, |
|||
sexe, |
|||
nationaliter, |
|||
cin, |
|||
date_delivrence, |
|||
annee_bacc, |
|||
serie, |
|||
boursier, |
|||
domaine, |
|||
contact, |
|||
parcours |
|||
) { |
|||
const query = database.prepare( |
|||
'INSERT INTO etudiants (nom, prenom, photos, date_de_naissances, niveau, annee_scolaire, status, mention_id, num_inscription, sexe, cin, date_delivrence, nationalite, annee_bacc, serie, boursier, domaine, contact, parcours) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)' |
|||
) |
|||
|
|||
try { |
|||
let response = await query.run( |
|||
nom, |
|||
prenom, |
|||
photos, |
|||
date_de_naissances, |
|||
niveau, |
|||
annee_scolaire, |
|||
status, |
|||
mention_id, |
|||
num_inscription, |
|||
sexe, |
|||
cin, |
|||
date_delivrence, |
|||
nationaliter, |
|||
annee_bacc, |
|||
serie, |
|||
boursier, |
|||
domaine, |
|||
contact, |
|||
parcours |
|||
) |
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* function to get all etudiants |
|||
* |
|||
* @returns JSON |
|||
*/ |
|||
async function getAllEtudiants() { |
|||
const query = database.prepare('SELECT * FROM etudiants ORDER BY annee_scolaire DESC') |
|||
try { |
|||
let response = await query.all() |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* function to return a single etudiant |
|||
* and display it on the screen |
|||
* |
|||
* @param {int} id |
|||
* @returns Promise |
|||
*/ |
|||
async function getSingleEtudiant(id) { |
|||
const query = database.prepare('SELECT * FROM etudiants WHERE id = ?') |
|||
|
|||
try { |
|||
const etudiants = await query.get(id) |
|||
|
|||
if (etudiants) { |
|||
return etudiants |
|||
} else { |
|||
return { message: 'etudiants pas trouver' } |
|||
} |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* function to get all etudiants M2 |
|||
* |
|||
* @returns JSON |
|||
*/ |
|||
async function FilterDataByNiveau(niveau) { |
|||
const query = database.prepare( |
|||
'SELECT * FROM etudiants WHERE niveau = ? ORDER BY annee_scolaire DESC' |
|||
) |
|||
try { |
|||
let response = await query.all(niveau) |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* function to update etudiants |
|||
* |
|||
* @param {*} nom |
|||
* @param {*} prenom |
|||
* @param {*} photos |
|||
* @param {*} date_de_naissances |
|||
* @param {*} niveau |
|||
* @param {*} annee_scolaire |
|||
* @param {*} status |
|||
* @param {*} num_inscription |
|||
* @param {*} id |
|||
* @returns promise |
|||
*/ |
|||
async function updateEtudiant( |
|||
nom, |
|||
prenom, |
|||
photos, |
|||
date_de_naissances, |
|||
niveau, |
|||
annee_scolaire, |
|||
status, |
|||
mention_id, |
|||
num_inscription, |
|||
id, |
|||
sexe, |
|||
nationalite, |
|||
cin, |
|||
date_delivrence, |
|||
annee_bacc, |
|||
serie, |
|||
boursier, |
|||
domaine, |
|||
contact, |
|||
parcours |
|||
) { |
|||
const query = database.prepare( |
|||
'UPDATE etudiants SET nom = ?, prenom = ?, photos = ?, date_de_naissances = ?, niveau = ?, annee_scolaire = ?, status = ?, mention_id = ?, num_inscription = ?, sexe = ?, cin = ?, date_delivrence = ?, nationalite = ?, annee_bacc = ?, serie = ?, boursier = ?, domaine = ?, contact = ?, parcours = ? WHERE id = ?' |
|||
) |
|||
|
|||
try { |
|||
let response = await query.run( |
|||
nom, |
|||
prenom, |
|||
photos, |
|||
date_de_naissances, |
|||
niveau, |
|||
annee_scolaire, |
|||
status, |
|||
mention_id, |
|||
num_inscription, |
|||
sexe, |
|||
cin, |
|||
date_delivrence, |
|||
nationalite, |
|||
annee_bacc, |
|||
serie, |
|||
boursier, |
|||
domaine, |
|||
contact, |
|||
parcours, |
|||
id |
|||
) |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* function to return the needed data in dashboard |
|||
* |
|||
* @returns promise |
|||
*/ |
|||
async function getDataToDashboard() { |
|||
const query = database.prepare('SELECT * FROM niveaus') |
|||
const query2 = database.prepare('SELECT * FROM etudiants') |
|||
const query3 = database.prepare('SELECT DISTINCT annee_scolaire FROM etudiants') // get all année scolaire sans doublan
|
|||
|
|||
try { |
|||
let niveau = query.all() |
|||
let etudiants = query2.all() |
|||
let anne_scolaire = query3.all() |
|||
|
|||
return { niveau, etudiants, anne_scolaire } |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
async function changePDP(photos, id) { |
|||
const query = database.prepare('UPDATE etudiants SET photos = ? WHERE id = ?') |
|||
|
|||
try { |
|||
let response = await query.run(photos, id) |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
async function updateParcours(parcours, id) { |
|||
const query = database.prepare('UPDATE etudiants SET parcours = ? WHERE id = ?') |
|||
|
|||
try { |
|||
let response = await query.run(parcours, id) |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
async function createTranche(etudiant_id, tranchename, montant) { |
|||
const query = database.prepare( |
|||
'INSERT INTO trancheecolage (etudiant_id, tranchename, montant) VALUES (?, ?, ?)' |
|||
) |
|||
|
|||
try { |
|||
let response = query.run(etudiant_id, tranchename, montant) |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
async function getTranche(id) { |
|||
const query = database.prepare('SELECT * FROM trancheecolage WHERE etudiant_id = ?') |
|||
|
|||
try { |
|||
let response = query.all(id) |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
async function updateTranche(id, tranchename, montant) { |
|||
const query = database.prepare( |
|||
'UPDATE trancheecolage SET tranchename = ?, montant = ? WHERE id = ?' |
|||
) |
|||
|
|||
try { |
|||
let response = query.run(tranchename, montant, id) |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
async function deleteTranche(id) { |
|||
const query = database.prepare('DELETE FROM trancheecolage WHERE id = ?') |
|||
|
|||
try { |
|||
let response = query.run(id) |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
async function getSingleTranche(id) { |
|||
try { |
|||
return await database.prepare('SELECT * FROM trancheecolage WHERE id = ?').get(id) |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
module.exports = { |
|||
insertEtudiant, |
|||
getAllEtudiants, |
|||
FilterDataByNiveau, |
|||
getSingleEtudiant, |
|||
updateEtudiant, |
|||
getDataToDashboard, |
|||
changePDP, |
|||
updateParcours, |
|||
createTranche, |
|||
getTranche, |
|||
updateTranche, |
|||
deleteTranche, |
|||
getSingleTranche |
|||
} |
|||
@ -0,0 +1,41 @@ |
|||
const { database } = require('../database'); |
|||
|
|||
const createConfigIp = (ipname) => { |
|||
const query = database.prepare('INSERT INTO ipconfig (ipname) VALUES (?)'); |
|||
|
|||
try { |
|||
let response = query.run(ipname) |
|||
|
|||
return response; |
|||
} catch (error) { |
|||
return error; |
|||
} |
|||
} |
|||
|
|||
const getIPConfig = async () => { |
|||
try { |
|||
let response = await database.prepare('SELECT * FROM ipconfig WHERE id = ?').get(1); |
|||
|
|||
return response; |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
const updateIPConfig = async (id, name) => { |
|||
let query = database.prepare('UPDATE ipconfig SET ipname = ? WHERE id = ?'); |
|||
|
|||
try { |
|||
let response = await query.run(name, id); |
|||
|
|||
return response; |
|||
} catch (error) { |
|||
return error; |
|||
} |
|||
} |
|||
|
|||
module.exports = { |
|||
createConfigIp, |
|||
getIPConfig, |
|||
updateIPConfig |
|||
} |
|||
@ -0,0 +1,354 @@ |
|||
const { database } = require('../database') |
|||
const { matiereSysteme } = require('../function/System') |
|||
const { convertArrayAndString } = require('../function/StringArrayConvertion') |
|||
|
|||
/** |
|||
* function uset to create matiere |
|||
* @param {*} nom |
|||
* @returns Promise |
|||
*/ |
|||
async function createMatiere(nom, credit, uniter, ue) { |
|||
const query = database.prepare( |
|||
'INSERT INTO matieres (nom, unite_enseignement, credit, heure, ue) VALUES (?, ?, ?, ?, ?)' |
|||
) |
|||
|
|||
const uniterHeure = database.prepare('SELECT uniter_heure FROM nessesaryTable').get() |
|||
const heure = credit * uniterHeure.uniter_heure |
|||
|
|||
try { |
|||
response = await query.run(nom, uniter, credit, heure, ue) |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* function to get all matieres |
|||
* @returns Promise |
|||
*/ |
|||
async function getMatiere() { |
|||
const query = database.prepare('SELECT * FROM matieres ORDER BY id DESC') |
|||
|
|||
try { |
|||
let response = await query.all() |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
async function displayMatiereFromForm(niveau, mention_id, parcours) { |
|||
// Fetch the semestre array
|
|||
let semestre = await matiereSysteme(niveau) // Ensure this returns an array with at least 2 items
|
|||
|
|||
if (niveau !== 'L1') { |
|||
if (semestre.length < 2) { |
|||
console.error('Error: Semestre array does not contain enough elements.') |
|||
return |
|||
} |
|||
|
|||
// Prepare the query
|
|||
let matiereQuery = database.prepare(` |
|||
SELECT DISTINCT m.* |
|||
FROM matieres m |
|||
JOIN matiere_semestre ms ON m.id = ms.matiere_id |
|||
JOIN semestres s ON ms.semestre_id = s.id |
|||
JOIN parcoursmatiere pm ON m.id = pm.matiere_id |
|||
JOIN parcours p ON pm.parcour_id = p.id |
|||
WHERE (s.nom LIKE ? OR s.nom LIKE ?) |
|||
AND ms.mention_id = ? |
|||
AND p.nom = ? |
|||
`)
|
|||
|
|||
try { |
|||
// Execute the query with parameters
|
|||
let response = matiereQuery.all(`%${semestre[0]}%`, `%${semestre[1]}%`, mention_id, parcours) |
|||
|
|||
console.log(response) |
|||
// Log the response
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} else { |
|||
if (semestre.length < 2) { |
|||
console.error('Error: Semestre array does not contain enough elements.') |
|||
return |
|||
} |
|||
|
|||
// Prepare the query
|
|||
let matiereQuery = database.prepare(` |
|||
SELECT DISTINCT m.* |
|||
FROM matieres m |
|||
JOIN matiere_semestre ms ON m.id = ms.matiere_id |
|||
JOIN semestres s ON ms.semestre_id = s.id |
|||
WHERE (s.nom LIKE ? OR s.nom LIKE ?) |
|||
AND ms.mention_id = ? |
|||
`)
|
|||
|
|||
try { |
|||
// Execute the query with parameters
|
|||
let response = matiereQuery.all(`%${semestre[0]}%`, `%${semestre[1]}%`, mention_id) |
|||
console.log(response) |
|||
// Log the response
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* function to get single matiere |
|||
* @param {*} id |
|||
* @returns promise |
|||
*/ |
|||
async function getSingleMatiere(id) { |
|||
const query = await database.prepare('SELECT * FROM matieres WHERE id = ?') |
|||
|
|||
try { |
|||
let response = query.get(id) |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* function used when updating matiere |
|||
* @param {*} nom |
|||
* @param {*} id |
|||
* @returns promise |
|||
*/ |
|||
async function updateMatiere(nom, id, credit, uniter, ue) { |
|||
const query = database.prepare( |
|||
'UPDATE matieres SET nom = ?, credit = ?, unite_enseignement = ?, heure = ?, ue = ? WHERE id = ?' |
|||
) |
|||
|
|||
const uniterHeure = await database.prepare('SELECT uniter_heure FROM nessesaryTable').get() |
|||
const heure = credit * uniterHeure.uniter_heure |
|||
|
|||
try { |
|||
response = await query.run(nom, credit, uniter, heure, ue, id) |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
async function deleteMatiere(id) { |
|||
const query = database.prepare('DELETE FROM matieres WHERE id = ?') |
|||
|
|||
try { |
|||
let response = query.run(id) |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
async function asygnationToMention(formData, id) { |
|||
const clearQuery = database.prepare('DELETE FROM matiere_mention WHERE matiere_id = ?') |
|||
const query = database.prepare( |
|||
'INSERT INTO matiere_mention (matiere_id, mention_id) VALUES (?,?)' |
|||
) |
|||
const selectedKeys = Object.keys(formData).filter((key) => formData[key]) |
|||
const placeholders = selectedKeys.map(() => '?').join(',') |
|||
// Prepare the query with placeholders
|
|||
const clearSemestreMentionQuery = database.prepare( |
|||
`DELETE FROM matiere_semestre WHERE matiere_id = ? AND mention_id NOT IN (${placeholders})` |
|||
) |
|||
|
|||
const clearNoreQuery = database.prepare( |
|||
`DELETE FROM notes WHERE matiere_id = ? AND mention_id NOT IN (${placeholders})` |
|||
) |
|||
|
|||
try { |
|||
let response |
|||
await clearQuery.run(id) |
|||
await clearNoreQuery.run(id, ...selectedKeys) |
|||
clearSemestreMentionQuery.run(id, ...selectedKeys) |
|||
// use transaction for speed execution
|
|||
database.transaction(() => { |
|||
for (let index = 0; index < selectedKeys.length; index++) { |
|||
response = query.run(id, selectedKeys[index]) |
|||
} |
|||
})() |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
async function getMentionMatiere(id) { |
|||
const query = database.prepare('SELECT * FROM matiere_mention WHERE matiere_id = ?') |
|||
|
|||
try { |
|||
let response = await query.all(id) |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
async function getMentionMatiereChecked(matiere_id) { |
|||
const getMentionMatiere = database.prepare('SELECT * FROM matiere_mention WHERE matiere_id = ?') |
|||
let MentionArray = await getMentionMatiere.all(matiere_id) |
|||
let arrayID = [] |
|||
|
|||
for (let index = 0; index < MentionArray.length; index++) { |
|||
arrayID.push(MentionArray[index].mention_id) |
|||
} |
|||
|
|||
const mentionQuery = database.prepare( |
|||
`SELECT * FROM mentions WHERE id IN (${arrayID.map(() => '?').join(', ')})` |
|||
) |
|||
|
|||
try { |
|||
const results = await mentionQuery.all(...arrayID) |
|||
|
|||
return results |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
async function getSemestreMatiere(id) { |
|||
const query = database.prepare('SELECT * FROM matiere_semestre WHERE matiere_id = ?') |
|||
|
|||
try { |
|||
let response = await query.all(id) |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
async function getSemestre() { |
|||
const query = database.prepare('SELECT * FROM semestres') |
|||
|
|||
try { |
|||
let response = await query.all() |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
async function insertUpdateMentionSemestre(matiere_id, formData) { |
|||
const clearQuery = database.prepare('DELETE FROM matiere_semestre WHERE matiere_id = ?') |
|||
clearQuery.run(matiere_id) |
|||
|
|||
const query = database.prepare( |
|||
'INSERT INTO matiere_semestre (matiere_id, semestre_id, mention_id) VALUES (?, ?, ?)' |
|||
) |
|||
let response |
|||
database.transaction(() => { |
|||
for (const key in formData) { |
|||
if (formData.hasOwnProperty(key)) { |
|||
for (let jindex = 0; jindex < formData[key].length; jindex++) { |
|||
response = query.run(matiere_id, formData[key][jindex], key) |
|||
} |
|||
} |
|||
} |
|||
})() |
|||
return response |
|||
} |
|||
|
|||
async function getEnseignants() { |
|||
const getIdQuery = database.prepare( |
|||
'SELECT id FROM matiereEnseignants GROUP BY matiere_id ORDER BY MAX(date) DESC' |
|||
) |
|||
|
|||
const query = database.prepare( |
|||
'SELECT * FROM matiereEnseignants WHERE id IN (' + |
|||
new Array(getIdQuery.all().length).fill('?').join(',') + |
|||
')' |
|||
) |
|||
|
|||
try { |
|||
// Get the latest `id` for each `matiere_id`
|
|||
const latestIds = getIdQuery.all().map((row) => row.id) |
|||
|
|||
// If no ids exist, return an empty array
|
|||
if (latestIds.length === 0) { |
|||
return [] |
|||
} |
|||
|
|||
// Fetch the full details using the filtered IDs
|
|||
let response = query.all(...latestIds) |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
async function insertNewProf(matiere_id, nom, prenom, contact, date) { |
|||
const query = database.prepare( |
|||
'INSERT INTO matiereEnseignants (matiere_id, nom_enseignant, prenom_enseignant, contact, date) VALUES (?, ?, ?, ?, ?)' |
|||
) |
|||
|
|||
try { |
|||
let response = query.run(matiere_id, nom, prenom, contact, date) |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
async function getSIngleProf(id) { |
|||
try { |
|||
const prof = await database |
|||
.prepare('SELECT * FROM matiereEnseignants WHERE matiere_id = ?') |
|||
.get(id) |
|||
|
|||
return prof |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
async function updateProf(matiere_id, nom, prenom, contact, date) { |
|||
const query = database.prepare( |
|||
'UPDATE matiereEnseignants SET nom_enseignant = ?, prenom_enseignant = ?, contact = ?, date = ? WHERE matiere_id = ?' |
|||
) |
|||
|
|||
try { |
|||
let response = query.run(nom, prenom, contact, date, matiere_id) |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
module.exports = { |
|||
createMatiere, |
|||
getSIngleProf, |
|||
getMatiere, |
|||
getSingleMatiere, |
|||
updateMatiere, |
|||
displayMatiereFromForm, |
|||
deleteMatiere, |
|||
asygnationToMention, |
|||
getMentionMatiere, |
|||
getMentionMatiereChecked, |
|||
getSemestreMatiere, |
|||
getSemestre, |
|||
insertUpdateMentionSemestre, |
|||
getEnseignants, |
|||
insertNewProf, |
|||
updateProf |
|||
} |
|||
@ -0,0 +1,69 @@ |
|||
const { database } = require('../database') |
|||
|
|||
async function createMention(nom, uniter) { |
|||
const query = database.prepare('INSERT INTO mentions (nom, uniter) VALUES (?, ?)') |
|||
|
|||
try { |
|||
let response = await query.run(nom, uniter) |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
async function deleteMention(id) { |
|||
const query = database.prepare('DELETE FROM mentions WHERE id = ?') |
|||
|
|||
try { |
|||
let response = await query.run(id) |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
async function getMentions() { |
|||
const query = database.prepare('SELECT * FROM mentions') |
|||
|
|||
try { |
|||
let response = await query.all() |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
async function getSingleMention(id) { |
|||
const query = database.prepare('SELECT * FROM mentions WHERE id = ?') |
|||
|
|||
try { |
|||
let response = query.get(id) |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
async function updateMention(nom, uniter, id) { |
|||
const query = database.prepare('UPDATE mentions SET nom = ?, uniter = ? WHERE id = ?') |
|||
|
|||
try { |
|||
let response = query.run(nom, uniter, id) |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
module.exports = { |
|||
createMention, |
|||
deleteMention, |
|||
getMentions, |
|||
getSingleMention, |
|||
updateMention |
|||
} |
|||
@ -0,0 +1,106 @@ |
|||
const { database } = require('../database') |
|||
|
|||
/** |
|||
* function to insert niveau to database |
|||
*/ |
|||
async function insertNiveau(nom) { |
|||
// Initialize an array to hold the individual names
|
|||
let nom_multiple = [] |
|||
|
|||
// Check if 'nom' contains a comma and split it into multiple names
|
|||
if (nom.includes(',')) { |
|||
nom_multiple = nom.split(',' || ', ').map((name) => name.trim()) // Trim to remove extra spaces
|
|||
} else { |
|||
nom_multiple = [nom] // Treat it as a single name
|
|||
} |
|||
|
|||
// Prepare the query for insertion
|
|||
const query = database.prepare('INSERT INTO niveaus (nom) VALUES (?)') |
|||
|
|||
try { |
|||
let responses = [] |
|||
for (const name of nom_multiple) { |
|||
// Insert each name and collect the response
|
|||
let response = await query.run(name) |
|||
responses.push(response) |
|||
} |
|||
if (nom_multiple.length === responses.length) { |
|||
return JSON.stringify({ |
|||
last_row: nom_multiple.length, |
|||
changes: 1 |
|||
}) |
|||
} else return false |
|||
} catch (error) { |
|||
return error // Return the error if any occurs
|
|||
} |
|||
} |
|||
|
|||
/** |
|||
* function to get single niveau for updating |
|||
* @param {*} id |
|||
* @returns Promise |
|||
*/ |
|||
async function getSingleNiveau(id) { |
|||
const query = database.prepare('SELECT * FROM niveaus WHERE id = ?') |
|||
|
|||
try { |
|||
let response = await query.get(id) |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* function used to update the niveau |
|||
* @param {*} nom |
|||
* @param {*} id |
|||
* @returns Promise |
|||
*/ |
|||
async function updateNiveau(nom, id) { |
|||
const query = database.prepare('UPDATE niveaus SET nom = ? WHERE id = ?') |
|||
|
|||
try { |
|||
let response = query.run(nom, id) |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* function to get all niveau |
|||
*/ |
|||
async function getNiveau() { |
|||
const query = database.prepare('SELECT * FROM niveaus') |
|||
|
|||
try { |
|||
let response = query.all() |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
async function deleteNiveau(id) { |
|||
const query = database.prepare('DELETE FROM niveaus WHERE id = ?') |
|||
|
|||
try { |
|||
let response = await query.run(id) |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
module.exports = { |
|||
getNiveau, |
|||
insertNiveau, |
|||
getSingleNiveau, |
|||
updateNiveau, |
|||
deleteNiveau |
|||
} |
|||
@ -0,0 +1,222 @@ |
|||
const { database } = require('../database') |
|||
const { getNiveau } = require('./Niveau') |
|||
const { matiereSysteme } = require('../function/System') |
|||
|
|||
/** |
|||
* Function to insert notes into the database |
|||
* @param {Object} formData - The form data containing subject names and values |
|||
* @param {number} etudiant_id - The student ID |
|||
* @param {string} etudiant_niveau - The student level |
|||
* @returns {Promise} - Promise resolving to the database response or an error |
|||
*/ |
|||
async function insertNoteRepech( |
|||
etudiant_id, |
|||
etudiant_niveau, |
|||
mention_id, |
|||
formData, |
|||
annee_scolaire |
|||
) { |
|||
// Extract keys and values dynamically
|
|||
const matiere_id = Object.keys(formData) |
|||
const values = Object.values(formData) |
|||
|
|||
const query = database.prepare( |
|||
`INSERT INTO notesrepech (etudiant_id, matiere_id, etudiant_niveau, mention_id, note, annee_scolaire) VALUES (?, ?, ?, ?, ?, ?)` |
|||
) |
|||
console.log(annee_scolaire) |
|||
try { |
|||
let response |
|||
for (let j = 0; j < matiere_id.length; j++) { |
|||
response = await query.run( |
|||
etudiant_id, |
|||
matiere_id[j], |
|||
etudiant_niveau, |
|||
mention_id, |
|||
parseFloat(values[j].replace(',', '.')) || 0, |
|||
annee_scolaire |
|||
) |
|||
} |
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* |
|||
* @returns promise |
|||
*/ |
|||
async function getNoteOnline() { |
|||
const query = database.prepare('SELECT notes.* FROM notes ') |
|||
|
|||
try { |
|||
let response = await query.all() |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* |
|||
* @returns promise |
|||
*/ |
|||
async function getNoteRepech(id, niveau) { |
|||
let semestre = await matiereSysteme(niveau) |
|||
|
|||
const query2 = database.prepare( |
|||
'SELECT notesrepech.*, matieres.* FROM notesrepech JOIN matieres ON (notesrepech.matiere_id = matieres.id) WHERE notesrepech.etudiant_id = ? AND notesrepech.etudiant_niveau = ?' |
|||
) |
|||
|
|||
try { |
|||
let response2 = query2.all(id, niveau) |
|||
return response2 |
|||
} catch (error) { |
|||
console.error('Error in query2:', error) |
|||
return error |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* Verify if a student has notes |
|||
* @returns {Promise<Array>} - Promise resolving to an array of notes or an empty array |
|||
*/ |
|||
async function verifyEtudiantIfHeHasNotesRepech() { |
|||
try { |
|||
// Prepare the query to filter by etudiant_id and etudiant_niveau
|
|||
const query = database.prepare('SELECT DISTINCT etudiant_id, etudiant_niveau FROM notesrepech') |
|||
|
|||
// Execute the query with the provided parameters
|
|||
const response = query.all() |
|||
|
|||
// Return the response
|
|||
return response |
|||
} catch (error) { |
|||
console.error('Error verifying student notes:', error) |
|||
throw error |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* function to show moyenne in screen |
|||
* |
|||
* @returns promise |
|||
*/ |
|||
async function showMoyenRepech(niveau, scolaire) { |
|||
const query = database.prepare( |
|||
`SELECT DISTINCT etudiant_id FROM notesrepech WHERE etudiant_niveau = ? AND annee_scolaire = ?` |
|||
) |
|||
|
|||
let etudiantWithNotes = await query.all(niveau, scolaire) |
|||
|
|||
let allEtudiantWithNotes = [] |
|||
|
|||
const query2 = database.prepare( |
|||
'SELECT notesrepech.*, etudiants.*, matieres.id, matieres.nom AS nomMat, matieres.credit FROM notesrepech INNER JOIN etudiants ON (notesrepech.etudiant_id = etudiants.id) INNER JOIN matieres ON (notesrepech.matiere_id = matieres.id) WHERE notesrepech.etudiant_id = ?' |
|||
) |
|||
|
|||
try { |
|||
for (let index = 0; index < etudiantWithNotes.length; index++) { |
|||
allEtudiantWithNotes.push(query2.all(etudiantWithNotes[index].etudiant_id)) |
|||
} |
|||
|
|||
return allEtudiantWithNotes |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* function used when updating note |
|||
* @param {Object} formData - The form data containing subject names and values |
|||
* @param {string} niveau - The student level |
|||
* @returns {Promise} - Promise resolving to the database response or an error |
|||
*/ |
|||
async function updateNoteRepech(formData, niveau, id) { |
|||
// Extract keys and values dynamically
|
|||
const matiere_id = Object.keys(formData) |
|||
const values = Object.values(formData) |
|||
|
|||
const query = database.prepare( |
|||
'UPDATE notesrepech SET note= ? WHERE etudiant_id = ? AND etudiant_niveau = ? AND matiere_id = ?' |
|||
) |
|||
|
|||
try { |
|||
let response |
|||
|
|||
for (let index = 0; index < matiere_id.length; index++) { |
|||
let data = values[index] |
|||
if (typeof data === 'string') { |
|||
console.log(parseFloat(data.replace(',', '.'))) |
|||
} else { |
|||
console.log(parseFloat(String(data).replace(',', '.'))) |
|||
} |
|||
response = await query.run(data, id, niveau, matiere_id[index]) |
|||
} |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
async function blockShowMoyeneRepech() { |
|||
const query = database.prepare( |
|||
'SELECT DISTINCT etudiant_niveau, annee_scolaire FROM notesrepech ORDER BY annee_scolaire DESC' |
|||
) |
|||
|
|||
const queryMention = database.prepare('SELECT * FROM mentions') |
|||
|
|||
try { |
|||
let response = await query.all() |
|||
let mention = await queryMention.all() |
|||
let niveau = response.map((item) => item.etudiant_niveau) |
|||
let annee_scolaire = response.map((item) => item.annee_scolaire) |
|||
const query2 = database.prepare( |
|||
`SELECT notesrepech.*, etudiants.id AS etudiantsId, etudiants.mention_id AS mentionId, etudiants.niveau, matieres.* FROM notesrepech INNER JOIN etudiants ON (notesrepech.etudiant_id = etudiants.id) INNER JOIN matieres ON (notesrepech.matiere_id = matieres.id) WHERE notesrepech.etudiant_niveau = ? AND notesrepech.annee_scolaire = ?` |
|||
) |
|||
|
|||
let allData = [] |
|||
|
|||
for (let index = 0; index < niveau.length; index++) { |
|||
allData.push(await query2.all(niveau[index], annee_scolaire[index])) |
|||
} |
|||
|
|||
return { response, allData, mention } |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* get all note with matiere for single student |
|||
* @param {*} id |
|||
* @param {*} niveau |
|||
* @param {*} annee_scolaire |
|||
* @returns promise |
|||
*/ |
|||
async function getMatiereAndNoteRepech(id, niveau, annee_scolaire) { |
|||
const query = database.prepare( |
|||
'SELECT * FROM notesrepech INNER JOIN matieres ON (notesrepech.matiere_id = matieres.id) WHERE notesrepech.etudiant_id = ? AND notesrepech.etudiant_niveau = ? AND notesrepech.annee_scolaire = ?' |
|||
) |
|||
|
|||
try { |
|||
let response = await query.all(id, niveau, annee_scolaire) |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
module.exports = { |
|||
insertNoteRepech, |
|||
getNoteRepech, |
|||
showMoyenRepech, |
|||
getNoteOnline, |
|||
verifyEtudiantIfHeHasNotesRepech, |
|||
updateNoteRepech, |
|||
blockShowMoyeneRepech, |
|||
getMatiereAndNoteRepech |
|||
} |
|||
@ -0,0 +1,44 @@ |
|||
const { database } = require('../database') |
|||
|
|||
/** |
|||
* function to get all Systeme note |
|||
* @returns promise |
|||
*/ |
|||
async function getSysteme() { |
|||
const query = database.prepare('SELECT * FROM notesystems') |
|||
|
|||
try { |
|||
let response = await query.get() |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* function to update systeme note |
|||
* @param {*} id |
|||
* @param {*} admis |
|||
* @param {*} redouble |
|||
* @param {*} renvoyer |
|||
* @returns promise |
|||
*/ |
|||
async function updateSysteme(id, admis, redouble, renvoyer) { |
|||
const query = database.prepare( |
|||
'UPDATE notesystems SET admis = ?, redouble = ?, renvoyer = ? WHERE id = ?' |
|||
) |
|||
|
|||
try { |
|||
let response = await query.run(admis, redouble, renvoyer, id) |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
module.exports = { |
|||
getSysteme, |
|||
updateSysteme |
|||
} |
|||
@ -0,0 +1,317 @@ |
|||
const { database } = require('../database') |
|||
const { getNiveau } = require('./Niveau') |
|||
const { matiereSysteme } = require('../function/System') |
|||
|
|||
/** |
|||
* Function to insert notes into the database |
|||
* @param {Object} formData - The form data containing subject names and values |
|||
* @param {number} etudiant_id - The student ID |
|||
* @param {string} etudiant_niveau - The student level |
|||
* @returns {Promise} - Promise resolving to the database response or an error |
|||
*/ |
|||
async function insertNote(etudiant_id, etudiant_niveau, mention_id, formData, annee_scolaire) { |
|||
// Extract keys and values dynamically
|
|||
const matiere_id = Object.keys(formData) |
|||
const values = Object.values(formData) |
|||
|
|||
const query = database.prepare( |
|||
`INSERT INTO notes (etudiant_id, matiere_id, etudiant_niveau, mention_id, note, annee_scolaire) VALUES (?, ?, ?, ?, ?, ?)` |
|||
) |
|||
|
|||
const insertRepechQuery = database.prepare( |
|||
`INSERT INTO notesrepech (etudiant_id, matiere_id, etudiant_niveau, mention_id, note, annee_scolaire) VALUES (?, ?, ?, ?, ?, ?)` |
|||
) |
|||
|
|||
console.log(annee_scolaire) |
|||
try { |
|||
let response |
|||
let newMatiereId = [] |
|||
|
|||
// run the session normale
|
|||
database.transaction(() => { |
|||
for (let j = 0; j < matiere_id.length; j++) { |
|||
if (values[j] < 10) { |
|||
newMatiereId.push(matiere_id[j]) |
|||
} |
|||
|
|||
response = query.run( |
|||
etudiant_id, |
|||
matiere_id[j], |
|||
etudiant_niveau, |
|||
mention_id, |
|||
parseFloat(values[j].replace(',', '.')) || 0, |
|||
annee_scolaire |
|||
) |
|||
} |
|||
})() |
|||
|
|||
// run the second session and set it to be 0 to display it from screen
|
|||
database.transaction(() => { |
|||
for (let j = 0; j < newMatiereId.length; j++) { |
|||
response = insertRepechQuery.run( |
|||
etudiant_id, |
|||
newMatiereId[j], |
|||
etudiant_niveau, |
|||
mention_id, |
|||
0, |
|||
annee_scolaire |
|||
) |
|||
} |
|||
})() |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* |
|||
* @returns promise |
|||
*/ |
|||
async function getNoteOnline() { |
|||
const query = database.prepare('SELECT notes.* FROM notes ') |
|||
|
|||
try { |
|||
let response = await query.all() |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* |
|||
* @returns promise |
|||
*/ |
|||
async function getNote(id, niveau, mention_id) { |
|||
let semestre = await matiereSysteme(niveau) |
|||
|
|||
const query = database.prepare( |
|||
'SELECT notes.*, matieres.* FROM notes JOIN matieres ON (notes.matiere_id = matieres.id) WHERE notes.etudiant_id = ? AND notes.etudiant_niveau = ?' |
|||
) |
|||
const matiereQuery = database.prepare(` |
|||
SELECT DISTINCT m.* |
|||
FROM matieres m |
|||
JOIN matiere_semestre ms ON m.id = ms.matiere_id |
|||
JOIN semestres s ON ms.semestre_id = s.id |
|||
WHERE (s.nom LIKE ? OR s.nom LIKE ?) |
|||
AND ms.mention_id = ? |
|||
`)
|
|||
|
|||
let res = await matiereQuery.all(`%${semestre[0]}%`, `%${semestre[1]}%`, mention_id) |
|||
|
|||
let response = await query.all(id, niveau) |
|||
const infoEtudiants = database.prepare('SELECT * FROM etudiants WHERE id = ?') |
|||
let etudiant = await infoEtudiants.get(id) |
|||
|
|||
let arrayResponseIdMatiere = [] |
|||
for (let index = 0; index < response.length; index++) { |
|||
arrayResponseIdMatiere.push(response[index].matiere_id) |
|||
} |
|||
|
|||
const filteredIds = res |
|||
.filter((matiere) => !arrayResponseIdMatiere.includes(matiere.id)) |
|||
.map((matiere) => matiere.id) |
|||
|
|||
const json = filteredIds.reduce((acc, id) => { |
|||
acc[id] = '0' |
|||
return acc |
|||
}, {}) |
|||
|
|||
const query2 = database.prepare( |
|||
'SELECT notes.*, matieres.* FROM notes JOIN matieres ON (notes.matiere_id = matieres.id) WHERE notes.etudiant_id = ? AND notes.etudiant_niveau = ?' |
|||
) |
|||
|
|||
try { |
|||
let response2 = query2.all(id, niveau) |
|||
return response2 |
|||
} catch (error) { |
|||
console.error('Error in query2:', error) |
|||
return error |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* Verify if a student has notes |
|||
* @returns {Promise<Array>} - Promise resolving to an array of notes or an empty array |
|||
*/ |
|||
async function verifyEtudiantIfHeHasNotes() { |
|||
try { |
|||
// Prepare the query to filter by etudiant_id and etudiant_niveau
|
|||
const query = database.prepare('SELECT DISTINCT etudiant_id, etudiant_niveau FROM notes') |
|||
|
|||
// Execute the query with the provided parameters
|
|||
const response = query.all() |
|||
|
|||
// Return the response
|
|||
return response |
|||
} catch (error) { |
|||
console.error('Error verifying student notes:', error) |
|||
throw error |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* function to show moyenne in screen |
|||
* |
|||
* @returns promise |
|||
*/ |
|||
async function showMoyen(niveau, scolaire) { |
|||
const query = database.prepare( |
|||
`SELECT DISTINCT etudiant_id FROM notes WHERE etudiant_niveau = ? AND annee_scolaire = ?` |
|||
) |
|||
|
|||
let etudiantWithNotes = await query.all(niveau, scolaire) |
|||
|
|||
let allEtudiantWithNotes = [] |
|||
|
|||
const query2 = database.prepare( |
|||
'SELECT notes.*, etudiants.*, matieres.id, matieres.nom AS nomMat, matieres.credit FROM notes INNER JOIN etudiants ON (notes.etudiant_id = etudiants.id) INNER JOIN matieres ON (notes.matiere_id = matieres.id) WHERE notes.etudiant_id = ?' |
|||
) |
|||
|
|||
try { |
|||
for (let index = 0; index < etudiantWithNotes.length; index++) { |
|||
allEtudiantWithNotes.push(query2.all(etudiantWithNotes[index].etudiant_id)) |
|||
} |
|||
|
|||
return allEtudiantWithNotes |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* function used when updating note |
|||
* @param {Object} formData - The form data containing subject names and values |
|||
* @param {string} niveau - The student level |
|||
* @returns {Promise} - Promise resolving to the database response or an error |
|||
*/ |
|||
async function updateNote(formData, niveau, id, mention_id, annee_scolaire) { |
|||
// Extract keys and values dynamically
|
|||
const matiere_id = Object.keys(formData) |
|||
const values = Object.values(formData) |
|||
|
|||
const query = database.prepare( |
|||
'UPDATE notes SET note= ? WHERE etudiant_id = ? AND etudiant_niveau = ? AND matiere_id = ?' |
|||
) |
|||
|
|||
const clearFromRepech = database.prepare( |
|||
'DELETE FROM notesrepech WHERE etudiant_id = ? AND etudiant_niveau = ? AND matiere_id = ?' |
|||
) |
|||
const insertRepechQuery = database.prepare( |
|||
`INSERT INTO notesrepech (etudiant_id, matiere_id, etudiant_niveau, mention_id, note, annee_scolaire) VALUES (?, ?, ?, ?, ?, ?)` |
|||
) |
|||
|
|||
const checkRepechQuery = database.prepare( |
|||
'SELECT * FROM notesrepech WHERE etudiant_id = ? AND matiere_id = ? AND etudiant_niveau = ?' |
|||
) |
|||
|
|||
try { |
|||
let response |
|||
|
|||
for (let index = 0; index < matiere_id.length; index++) { |
|||
let data = values[index] |
|||
if (typeof data === 'string') { |
|||
data = parseFloat(data.replace(',', '.')) |
|||
} else { |
|||
data = parseFloat(String(data).replace(',', '.')) |
|||
} |
|||
let check = await checkRepechQuery.get(id, matiere_id[index], niveau) |
|||
if (data < 10) { |
|||
if (!check) { |
|||
insertRepechQuery.run(id, matiere_id[index], niveau, mention_id, 0, annee_scolaire) |
|||
} |
|||
response = await query.run(data, id, niveau, matiere_id[index]) |
|||
} else { |
|||
clearFromRepech.run(id, niveau, matiere_id[index]) |
|||
response = await query.run(data, id, niveau, matiere_id[index]) |
|||
} |
|||
} |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
async function blockShowMoyene() { |
|||
const query = database.prepare( |
|||
'SELECT DISTINCT etudiant_niveau, annee_scolaire FROM notes ORDER BY annee_scolaire DESC' |
|||
) |
|||
|
|||
const queryMention = database.prepare('SELECT * FROM mentions') |
|||
|
|||
try { |
|||
let response = await query.all() |
|||
let mention = await queryMention.all() |
|||
let niveau = response.map((item) => item.etudiant_niveau) |
|||
let annee_scolaire = response.map((item) => item.annee_scolaire) |
|||
const query2 = database.prepare( |
|||
`SELECT notes.*, etudiants.id AS etudiantsId, etudiants.mention_id AS mentionId, etudiants.niveau, matieres.* FROM notes INNER JOIN etudiants ON (notes.etudiant_id = etudiants.id) INNER JOIN matieres ON (notes.matiere_id = matieres.id) WHERE notes.etudiant_niveau = ? AND notes.annee_scolaire = ?` |
|||
) |
|||
|
|||
let allData = [] |
|||
|
|||
for (let index = 0; index < niveau.length; index++) { |
|||
allData.push(await query2.all(niveau[index], annee_scolaire[index])) |
|||
} |
|||
|
|||
return { response, allData, mention } |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* get all note with matiere for single student |
|||
* @param {*} id |
|||
* @param {*} niveau |
|||
* @param {*} annee_scolaire |
|||
* @returns promise |
|||
*/ |
|||
async function getMatiereAndNote(id, niveau, annee_scolaire) { |
|||
const query = database.prepare( |
|||
'SELECT * FROM notes INNER JOIN matieres ON (notes.matiere_id = matieres.id) WHERE notes.etudiant_id = ? AND notes.etudiant_niveau = ? AND notes.annee_scolaire = ?' |
|||
) |
|||
|
|||
try { |
|||
let response = await query.all(id, niveau, annee_scolaire) |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
async function getNotesWithRepechToDisplay(id, anneescolaire, niveau) { |
|||
const queryNoteNormal = database.prepare( |
|||
'SELECT * FROM notes INNER JOIN matieres ON (notes.matiere_id = matieres.id) WHERE notes.etudiant_id = ? AND notes.annee_scolaire = ? AND notes.etudiant_niveau = ?' |
|||
) |
|||
let noteNormal = await queryNoteNormal.all(id, anneescolaire, niveau) |
|||
|
|||
const queryNoteRepech = database.prepare( |
|||
'SELECT * FROM notesrepech INNER JOIN matieres ON (notesrepech.matiere_id = matieres.id) WHERE notesrepech.etudiant_id = ? AND notesrepech.annee_scolaire = ? AND notesrepech.etudiant_niveau = ?' |
|||
) |
|||
let noteRepech = await queryNoteRepech.all(id, anneescolaire, niveau) |
|||
|
|||
const semestreQuery = database.prepare( |
|||
'SELECT * FROM semestres INNER JOIN matiere_semestre ON(semestres.id = matiere_semestre.semestre_id)' |
|||
) |
|||
let semestre = await semestreQuery.all() |
|||
|
|||
return { noteNormal, noteRepech, semestre } |
|||
} |
|||
|
|||
module.exports = { |
|||
insertNote, |
|||
getNote, |
|||
showMoyen, |
|||
getNoteOnline, |
|||
verifyEtudiantIfHeHasNotes, |
|||
updateNote, |
|||
blockShowMoyene, |
|||
getMatiereAndNote, |
|||
getNotesWithRepechToDisplay |
|||
} |
|||
@ -0,0 +1,179 @@ |
|||
const { database } = require('../database') |
|||
const { matiereSystemReverse } = require('../function/System') |
|||
const dayjs = require('dayjs') |
|||
|
|||
async function insertParcour(nom, uniter, mention_id) { |
|||
const query = database.prepare('INSERT INTO parcours (nom, uniter, mention_id) VALUES (?, ?, ?)') |
|||
|
|||
try { |
|||
let response = query.run(nom, uniter, mention_id == null ? 0 : mention_id) |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
async function getParcourMatiere(id) { |
|||
const parcourMatiereQuery = database.prepare('SELECT * FROM parcoursmatiere WHERE matiere_id = ?') |
|||
|
|||
try { |
|||
let response |
|||
return (response = await parcourMatiereQuery.all(id)) |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
async function getParcours() { |
|||
const query = database.prepare('SELECT * FROM parcours ORDER BY id DESC') |
|||
|
|||
try { |
|||
let response = query.all() |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
async function getSingleParcours(id) { |
|||
const query = database.prepare('SELECT * FROM parcours WHERE id = ?') |
|||
|
|||
try { |
|||
let response = await query.get(id) |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
async function deletes(id) { |
|||
const query = database.prepare('DELETE FROM parcours WHERE id = ?') |
|||
|
|||
try { |
|||
let response = await query.run(id) |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
async function updateparcour(id, nom, uniter, mention_id) { |
|||
const query = database.prepare( |
|||
'UPDATE parcours SET nom = ?, uniter = ?, mention_id = ? WHERE id = ?' |
|||
) |
|||
|
|||
try { |
|||
let response = await query.run(nom, uniter, mention_id, id) |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
async function parcourMatiere(matiere_id, parcour_id) { |
|||
const query = database.prepare( |
|||
'INSERT INTO parcoursmatiere (matiere_id, parcour_id) VALUES (?, ?)' |
|||
) |
|||
|
|||
database.prepare('DELETE FROM parcoursmatiere WHERE matiere_id = ?').run(matiere_id) |
|||
|
|||
try { |
|||
let response |
|||
database.transaction(() => { |
|||
for (let index = 0; index < parcour_id.length; index++) { |
|||
response = query.run(matiere_id, parcour_id[index]) |
|||
} |
|||
})() |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
async function extractFiche(matiere_id) { |
|||
const query = database.prepare( |
|||
'SELECT matiere_semestre.semestre_id, matiere_semestre.mention_id, semestres.* FROM matiere_semestre INNER JOIN semestres ON (matiere_semestre.semestre_id = semestres.id) WHERE matiere_semestre.matiere_id = ?' |
|||
) |
|||
const allStudentQuery = database.prepare( |
|||
'SELECT * FROM etudiants WHERE niveau LIKE ? AND annee_scolaire LIKE ?' |
|||
) |
|||
const parcourMatiereQuery = database.prepare( |
|||
'SELECT * FROM parcoursmatiere INNER JOIN parcours ON (parcoursmatiere.parcour_id = parcours.id) WHERE parcoursmatiere.matiere_id = ?' |
|||
) |
|||
|
|||
try { |
|||
let matiereSemestre = query.all(matiere_id) |
|||
let response = [] |
|||
let allSTudent = [] |
|||
let allMention_id = [] |
|||
let realSponse = [] |
|||
let now = dayjs().format('YYYY') |
|||
|
|||
realSponse = await database.transaction(async () => { |
|||
let parcours = parcourMatiereQuery.all(Number(matiere_id)) |
|||
for (let index = 0; index < matiereSemestre.length; index++) { |
|||
response.push(await matiereSystemReverse(matiereSemestre[index].nom)) |
|||
allMention_id.push(matiereSemestre[index].mention_id) |
|||
} |
|||
|
|||
let newResponse = [] |
|||
for (let index = 0; index < response.length; index++) { |
|||
if (response[index] != response[index + 1]) { |
|||
newResponse.push(response[index]) |
|||
} |
|||
} |
|||
|
|||
for (let index = 0; index < newResponse.length; index++) { |
|||
allSTudent = allStudentQuery.all(`%${newResponse[index]}%`, `%${now}%`) |
|||
} |
|||
|
|||
let studentFiltredMention = [] |
|||
for (let index = 0; index < allSTudent.length; index++) { |
|||
if (allMention_id.includes(allSTudent[index].mention_id)) { |
|||
studentFiltredMention.push(allSTudent[index]) |
|||
} |
|||
} |
|||
let allData = [] |
|||
|
|||
for (let j = 0; j < parcours.length; j++) { |
|||
for (let index = 0; index < studentFiltredMention.length; index++) { |
|||
if (parcours[j].parcour_id == 1) { |
|||
if ( |
|||
studentFiltredMention[index].parcours == null || |
|||
studentFiltredMention[index].parcours == parcours[j].nom |
|||
) { |
|||
allData.push(studentFiltredMention[index]) |
|||
} |
|||
} else { |
|||
if (studentFiltredMention[index].parcours == parcours[j].nom) { |
|||
allData.push(studentFiltredMention[index]) |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
return allData |
|||
})() |
|||
|
|||
return realSponse |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
module.exports = { |
|||
insertParcour, |
|||
getParcours, |
|||
getSingleParcours, |
|||
deletes, |
|||
updateparcour, |
|||
parcourMatiere, |
|||
extractFiche, |
|||
getParcourMatiere |
|||
} |
|||
@ -0,0 +1,21 @@ |
|||
const { database } = require('../database') |
|||
|
|||
/** |
|||
* function to return all status |
|||
* @returns promise |
|||
*/ |
|||
async function getStatus() { |
|||
const query = database.prepare('SELECT * FROM status') |
|||
|
|||
try { |
|||
let response = await query.all() |
|||
|
|||
return response |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
module.exports = { |
|||
getStatus |
|||
} |
|||
@ -0,0 +1,149 @@ |
|||
const { database } = require('../database') |
|||
const bcrypt = require('bcryptjs') |
|||
|
|||
// Function to insert a user into the database
|
|||
async function insertUser(username, email, password, roles) { |
|||
const saltRounds = 10 |
|||
|
|||
try { |
|||
// Await the bcrypt hashing to complete before proceeding
|
|||
const hashedPassword = await bcrypt.hash(password, saltRounds) |
|||
|
|||
// Prepare and run the insert query using the hashed password
|
|||
const insertUserQuery = database.prepare( |
|||
'INSERT INTO users (username, email, password, roles) VALUES (?, ?, ?, ?)' |
|||
) |
|||
const insertedUser = await insertUserQuery.run(username, email, hashedPassword, roles) |
|||
|
|||
return insertedUser |
|||
} catch (err) { |
|||
return err |
|||
} |
|||
} |
|||
|
|||
// Function to fetch all users from the database
|
|||
async function getAllUsers() { |
|||
const getUsersQuery = database.prepare('SELECT * FROM users') |
|||
let response = await getUsersQuery.all() |
|||
|
|||
return response |
|||
} |
|||
|
|||
// Function to login a user
|
|||
async function loginUser(username, password) { |
|||
// Prepare the query to get the user by username
|
|||
const loginUserQuery = database.prepare('SELECT * FROM users WHERE LOWER(username) = ?') |
|||
|
|||
try { |
|||
// Execute the query and get the user from the database
|
|||
const user = await loginUserQuery.get(username.toLowerCase()) |
|||
|
|||
if (user) { |
|||
// Use bcrypt to compare the provided password with the stored hashed password
|
|||
const isPasswordValid = await bcrypt.compare(password, user.password) |
|||
|
|||
if (isPasswordValid) { |
|||
// If password matches, return the user
|
|||
return user |
|||
} else { |
|||
// If password does not match
|
|||
console.log('Invalid password') |
|||
} |
|||
} else { |
|||
// If no user is found with the provided username
|
|||
console.log('User not found') |
|||
} |
|||
} catch (err) { |
|||
console.error('Error during login:', err) |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* function to use in forgit password |
|||
* |
|||
* @param {*} email |
|||
* @param {*} password |
|||
* @param {*} passwordConfirmation |
|||
* @returns |
|||
*/ |
|||
async function forgotPassword(email, password, passwordConfirmation) { |
|||
const saltRounds = 10 |
|||
const forgotPasswordQuery = database.prepare('SELECT * FROM users WHERE email = ?') |
|||
|
|||
if (password == passwordConfirmation) { |
|||
const user = await forgotPasswordQuery.get(email) |
|||
|
|||
if (user) { |
|||
const updateQuery = database.prepare('UPDATE users SET password = ? WHERE email = ?') |
|||
const hashedPassword = await bcrypt.hash(password, saltRounds) |
|||
|
|||
try { |
|||
await updateQuery.run(hashedPassword, email) |
|||
|
|||
return { message: 'Mot de passe modifier avec succes', status: 200 } |
|||
} catch (error) { |
|||
console.error('Error updating password:', error) |
|||
} |
|||
} else { |
|||
return { message: 'Email non trouver', status: 404 } |
|||
} |
|||
} else { |
|||
return { message: 'Mot de passe ne correspond pas', status: 401 } |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* function to use when updatign the users |
|||
* |
|||
* @param {*} username |
|||
* @param {*} email |
|||
* @param {*} password |
|||
* @param {*} id |
|||
* @returns promise |
|||
*/ |
|||
async function updateUser(username, email, password, id) { |
|||
const saltRounds = 10 |
|||
|
|||
try { |
|||
let query |
|||
let response |
|||
|
|||
if (password === '') { |
|||
// Update without changing the password
|
|||
if (username === '' && email !== '') { |
|||
query = database.prepare('UPDATE users SET email = ? WHERE id = ?') |
|||
response = await query.run(email, id) |
|||
} else if (email === '' && username !== '') { |
|||
query = database.prepare('UPDATE users SET username = ? WHERE id = ?') |
|||
response = await query.run(username, id) |
|||
} else if (username !== '' && email !== '') { |
|||
query = database.prepare('UPDATE users SET username = ?, email = ? WHERE id = ?') |
|||
response = await query.run(username, email, id) |
|||
} |
|||
} else { |
|||
// Update with a new hashed password
|
|||
const hashedPassword = await bcrypt.hash(password, saltRounds) |
|||
query = database.prepare( |
|||
'UPDATE users SET username = ?, email = ?, password = ? WHERE id = ?' |
|||
) |
|||
response = await query.run(username, email, hashedPassword, id) |
|||
} |
|||
|
|||
// Fetch the updated user after the update
|
|||
const getUserQuery = database.prepare('SELECT * FROM users WHERE id = ?') |
|||
const updatedUser = await getUserQuery.get(id) |
|||
|
|||
return updatedUser // Return the updated user
|
|||
} catch (error) { |
|||
console.error('Error updating user:', error) |
|||
throw error // Throw error to handle it in calling function if needed
|
|||
} |
|||
} |
|||
|
|||
module.exports = { |
|||
getAllUsers, |
|||
insertUser, |
|||
loginUser, |
|||
forgotPassword, |
|||
updateUser |
|||
} |
|||
@ -0,0 +1,142 @@ |
|||
CREATE TABLE IF NOT EXISTS users ( |
|||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, |
|||
username VARCHAR(200) NOT NULL, |
|||
email VARCHAR(250) NOT NULL UNIQUE, |
|||
password TEXT NOT NULL, |
|||
roles VARCHAR(250) NOT NULL, |
|||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
|||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP |
|||
); |
|||
|
|||
CREATE TABLE IF NOT EXISTS status ( |
|||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, |
|||
nom VARCHAR(200) NOT NULL, |
|||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
|||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP |
|||
); |
|||
|
|||
CREATE TABLE IF NOT EXISTS mentions ( |
|||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, |
|||
nom VARCHAR(250) NOT NULL, |
|||
uniter VARCHAR(50) NOT NULL, |
|||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
|||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP |
|||
); |
|||
|
|||
CREATE TABLE IF NOT EXISTS niveaus ( |
|||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, |
|||
nom VARCHAR(50) NOT NULL, |
|||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
|||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP |
|||
); |
|||
|
|||
CREATE TABLE IF NOT EXISTS etudiants ( |
|||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, |
|||
nom VARCHAR(250) NOT NULL, |
|||
prenom VARCHAR(250) NOT NULL, |
|||
photos TEXT NOT NULL, |
|||
date_de_naissances DATE NOT NULL, |
|||
niveau VARCHAR(250) NOT NULL, |
|||
annee_scolaire VARCHAR(20) NOT NULL, |
|||
status INTEGER NOT NULL, |
|||
mention_id INTEGER NOT NULL, |
|||
num_inscription TEXT NOT NULL UNIQUE, |
|||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
|||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
|||
FOREIGN KEY (status) REFERENCES status(id), |
|||
FOREIGN KEY (mention_id) REFERENCES mentions(id) |
|||
); |
|||
|
|||
CREATE TABLE IF NOT EXISTS matieres ( |
|||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, |
|||
nom VARCHAR(250) UNIQUE NOT NULL, |
|||
unite_enseignement VARCHAR(250) NOT NULL, |
|||
credit INTEGER NOT NULL, |
|||
heure INTEGER NOT NULL, |
|||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
|||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP |
|||
); |
|||
|
|||
CREATE TABLE IF NOT EXISTS semestres ( |
|||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, |
|||
nom VARCHAR(30) UNIQUE NOT NULL, |
|||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
|||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP |
|||
); |
|||
|
|||
CREATE TABLE IF NOT EXISTS matiere_mention ( |
|||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, |
|||
matiere_id INTEGER NOT NULL, |
|||
mention_id INTEGER NOT NULL, |
|||
FOREIGN KEY (matiere_id) REFERENCES matieres(id), |
|||
FOREIGN KEY (mention_id) REFERENCES mentions(id) |
|||
); |
|||
|
|||
CREATE TABLE IF NOT EXISTS matiere_semestre ( |
|||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, |
|||
matiere_id INTEGER NOT NULL, |
|||
semestre_id INTEGER NOT NULL, |
|||
mention_id INTEGER NOT NULL, |
|||
FOREIGN KEY (matiere_id) REFERENCES matieres(id), |
|||
FOREIGN KEY (semestre_id) REFERENCES semestres(id), |
|||
FOREIGN KEY (mention_id) REFERENCES mentions(id) |
|||
); |
|||
|
|||
CREATE TABLE IF NOT EXISTS notes ( |
|||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, |
|||
etudiant_id INTEGER NOT NULL, |
|||
matiere_id INTEGER NOT NULL, |
|||
etudiant_niveau VARCHAR(50) NOT NULL, |
|||
mention_id INTEGER NOT NULL, |
|||
note FLOAT DEFAULT NULL, |
|||
annee_scolaire VARCHAR(50) NOT NULL, |
|||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
|||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
|||
FOREIGN KEY (etudiant_id) REFERENCES etudiants(id), |
|||
FOREIGN KEY (matiere_id) REFERENCES matieres(id), |
|||
FOREIGN KEY (mention_id) REFERENCES mentions(id) |
|||
); |
|||
|
|||
CREATE TABLE IF NOT EXISTS notesrepech ( |
|||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, |
|||
etudiant_id INTEGER NOT NULL, |
|||
matiere_id INTEGER NOT NULL, |
|||
etudiant_niveau VARCHAR(50) NOT NULL, |
|||
mention_id INTEGER NOT NULL, |
|||
note FLOAT DEFAULT NULL, |
|||
annee_scolaire VARCHAR(50) NOT NULL, |
|||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
|||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
|||
FOREIGN KEY (etudiant_id) REFERENCES etudiants(id), |
|||
FOREIGN KEY (matiere_id) REFERENCES matieres(id), |
|||
FOREIGN KEY (mention_id) REFERENCES mentions(id) |
|||
); |
|||
|
|||
CREATE TABLE IF NOT EXISTS notesystems ( |
|||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, |
|||
admis FLOAT NOT NULL DEFAULT 10, |
|||
redouble FLOAT NOT NULL DEFAULT 9.99, |
|||
renvoyer FLOAT NOT NULL DEFAULT 7.99, |
|||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
|||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP |
|||
); |
|||
|
|||
CREATE TABLE IF NOT EXISTS anneescolaire ( |
|||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, |
|||
code VARCHAR(30) NOT NULL, |
|||
debut DATE NOT NULL, |
|||
fin DATE NOT NULL, |
|||
is_current INTEGER DEFAULT 0, |
|||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
|||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP |
|||
); |
|||
|
|||
CREATE TABLE IF NOT EXISTS traitmentsystem ( |
|||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, |
|||
code VARCHAR(30) NOT NULL, |
|||
debut DATE NOT NULL, |
|||
fin DATE NOT NULL, |
|||
is_finished INTEGER DEFAULT 0, |
|||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
|||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP |
|||
); |
|||
@ -0,0 +1,151 @@ |
|||
/** |
|||
* URL fro the server web, you can modify it like your Domain name |
|||
*/ |
|||
const { URL } = require('./Config') |
|||
|
|||
const { getNoteOnline, insertNote } = require('../Models/Notes') |
|||
|
|||
async function getAllNotesFeched() { |
|||
const notes = await getNoteOnline() |
|||
|
|||
return notes |
|||
} |
|||
|
|||
/** |
|||
* send data to the database in the web |
|||
*/ |
|||
async function verifyNoteToWeb() { |
|||
/** |
|||
* class AJAX, don't touch it |
|||
*/ |
|||
const XHR = new XMLHttpRequest() |
|||
|
|||
let notes = await getAllNotesFeched() |
|||
|
|||
XHR.onreadystatechange = () => { |
|||
if (XHR.readyState === 4) { |
|||
if (XHR.status === 200) { |
|||
// nothing here because the statement is in the server web
|
|||
} else { |
|||
console.log('impossible de contacter le server pour la syncronisation') |
|||
} |
|||
} |
|||
} |
|||
|
|||
const data = new FormData() |
|||
|
|||
data.append('Verification', JSON.stringify(notes)) |
|||
|
|||
XHR.open('POST', `${URL}/verifywebNote`, true) |
|||
XHR.setRequestHeader('x-requested-with', 'xmlhttprequest') |
|||
XHR.send(data) |
|||
} |
|||
|
|||
async function verifyNoteToLocal() { |
|||
/** |
|||
* class AJAX, don't touch it |
|||
*/ |
|||
const XHR = new XMLHttpRequest() |
|||
let notes = await getAllNotesFeched() |
|||
|
|||
XHR.onreadystatechange = () => { |
|||
if (XHR.readyState === 4) { |
|||
if (XHR.status === 200) { |
|||
const noteOnline = JSON.parse(XHR.responseText) |
|||
|
|||
let data_note = [] |
|||
// let bool = false;
|
|||
|
|||
if (notes.length === 0) { |
|||
// Case when local data is empty, insert all online data
|
|||
for (let index = 0; index < noteOnline.length; index++) { |
|||
console.log(noteOnline[index]['etudiant_id']) |
|||
insertNote( |
|||
noteOnline[index].etudiant_id, |
|||
noteOnline[index].etudiant_niveau, |
|||
noteOnline[index].Algebre, |
|||
noteOnline[index].Analyse, |
|||
noteOnline[index].Mecanique_Generale_I, |
|||
noteOnline[index].Resistance_Materiaux, |
|||
noteOnline[index].Electricite, |
|||
noteOnline[index].Chimie_Generale_1, |
|||
noteOnline[index].Algorithmique, |
|||
noteOnline[index].Thermodynamique_Physique, |
|||
noteOnline[index].Mecanique_Fluide, |
|||
noteOnline[index].Optique_Geometrique, |
|||
noteOnline[index].Calcul_Numerique, |
|||
noteOnline[index].Calcul_Vectoriel_Integral, |
|||
noteOnline[index].Francais, |
|||
noteOnline[index].Anglais, |
|||
noteOnline[index].Dessin_Technique, |
|||
noteOnline[index].Programmation |
|||
) |
|||
} |
|||
} else { |
|||
// Case when online data has more entries than local data
|
|||
// Loop through the notes array
|
|||
for (let index = 0; index < notes.length; index++) { |
|||
// Push an object with the desired properties
|
|||
data_note.push({ |
|||
etudiant_id: notes[index].etudiant_id, |
|||
etudiant_niveau: notes[index].etudiant_niveau |
|||
}) |
|||
} |
|||
for (let index = 0; index < noteOnline.length; index++) { |
|||
let bool = true |
|||
|
|||
for (let jindex = 0; jindex < data_note.length; jindex++) { |
|||
if ( |
|||
noteOnline[index].etudiant_id === data_note[jindex].etudiant_id && |
|||
noteOnline[index].etudiant_niveau === data_note[jindex].etudiant_niveau |
|||
) { |
|||
bool = false |
|||
break |
|||
} |
|||
} |
|||
|
|||
if (bool) { |
|||
insertNote( |
|||
noteOnline[index].etudiant_id, |
|||
noteOnline[index].etudiant_niveau, |
|||
noteOnline[index].Algebre, |
|||
noteOnline[index].Analyse, |
|||
noteOnline[index].Mecanique_General_I, |
|||
noteOnline[index].Resistance_Materiaux, |
|||
noteOnline[index].Electricite, |
|||
noteOnline[index].Chimie_Generale_1, |
|||
noteOnline[index].Algorithmique, |
|||
noteOnline[index].Thermodynamique_Physique, |
|||
noteOnline[index].Mecanique_Fluide, |
|||
noteOnline[index].Optique_Geometrique, |
|||
noteOnline[index].Calcul_Numerique, |
|||
noteOnline[index].Calcul_Vectoriel_Integral, |
|||
noteOnline[index].Francais, |
|||
noteOnline[index].Anglais, |
|||
noteOnline[index].Dessin_Technique, |
|||
noteOnline[index].Programmation |
|||
) |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
XHR.open('GET', `${URL}/verifylocalNote`, true) |
|||
XHR.setRequestHeader('x-requested-with', 'xmlhttprequest') |
|||
XHR.send() |
|||
} |
|||
|
|||
async function synchronizeDataNotes() { |
|||
try { |
|||
await verifyNoteToWeb() |
|||
await verifyNoteToLocal() |
|||
} catch (error) { |
|||
console.error('Error during synchronization:', error) |
|||
} |
|||
} |
|||
|
|||
module.exports = { |
|||
synchronizeDataNotes |
|||
} |
|||
@ -0,0 +1,5 @@ |
|||
const URL = 'https://api.polytechnique.c4m.mg' |
|||
|
|||
module.exports = { |
|||
URL |
|||
} |
|||
@ -0,0 +1,75 @@ |
|||
const { insertEtudiant } = require('../Models/Etudiants') |
|||
const { database } = require('../database') |
|||
const { URL } = require('./Config') |
|||
const dayjs = require('dayjs') |
|||
|
|||
const getEtudiants = async () => { |
|||
const XHR = new XMLHttpRequest() |
|||
const allEtudiants = await database.prepare('SELECT * FROM etudiants').all() |
|||
|
|||
if (XHR.readyState === 4) { |
|||
if (XHR.status === 200) { |
|||
const etudiantFromWeb = JSON.parse(XHR.responseText) |
|||
|
|||
let numInscArray = [] |
|||
for (let index = 0; index < allEtudiants.length; index++) { |
|||
numInscArray.push(allEtudiants[index].num_inscription) |
|||
} |
|||
|
|||
database.transaction(() => { |
|||
for (let index = 0; index < etudiantFromWeb.length; index++) { |
|||
if (numInscArray.includes(etudiantFromWeb[index]['num_inscription']) === false) { |
|||
insertEtudiant( |
|||
etudiantFromWeb[index]['nom'], |
|||
etudiantFromWeb[index]['prenom'], |
|||
etudiantFromWeb[index]['photos'], |
|||
etudiantFromWeb[index]['date_de_naissances'], |
|||
etudiantFromWeb[index]['niveau'], |
|||
etudiantFromWeb[index]['annee_scolaire'], |
|||
etudiantFromWeb[index]['status'], |
|||
etudiantFromWeb[index]['num_inscription'], |
|||
etudiantFromWeb[index]['mention_id'] |
|||
) |
|||
} else { |
|||
const getTheEtudiant = database |
|||
.prepare('SELECT * FROM etudiants WHERE id = ?') |
|||
.get(etudiantFromWeb[index]['id']) |
|||
|
|||
if (getTheEtudiant.updated_at < etudiantFromWeb[index]['updated_at']) { |
|||
database |
|||
.prepare( |
|||
'UPDATE etudiants SET nom = ?, prenom = ?, photos = ?, date_de_naissances = ?, niveau = ?, annee_scolaire = ?, status = ?, mention_id = ?, num_inscription = ? WHERE id = ?' |
|||
) |
|||
.run( |
|||
etudiantFromWeb[index]['nom'], |
|||
etudiantFromWeb[index]['prenom'], |
|||
etudiantFromWeb[index]['photos'], |
|||
etudiantFromWeb[index]['date_de_naissances'], |
|||
etudiantFromWeb[index]['niveau'], |
|||
etudiantFromWeb[index]['annee_scolaire'], |
|||
etudiantFromWeb[index]['status'], |
|||
etudiantFromWeb[index]['num_inscription'], |
|||
etudiantFromWeb[index]['mention_id'], |
|||
etudiantFromWeb[index]['id'] |
|||
) |
|||
} |
|||
} |
|||
} |
|||
})() |
|||
} else { |
|||
console.log('impossible de contacter le server') |
|||
} |
|||
} |
|||
|
|||
XHR.open('GET', `${URL}/getEtudiants`, true) |
|||
XHR.setRequestHeader('x-requested-with', 'xmlhttprequest') |
|||
XHR.send() |
|||
} |
|||
|
|||
async function getAll() { |
|||
await getEtudiants() |
|||
} |
|||
|
|||
module.exports = { |
|||
getAll |
|||
} |
|||
@ -0,0 +1,422 @@ |
|||
const { database } = require('../database') |
|||
const { URL } = require('./Config') |
|||
|
|||
/** |
|||
* send data etudiants in server |
|||
*/ |
|||
const sendEtudiants = async () => { |
|||
const XHR = new XMLHttpRequest() |
|||
const queryEtudiants = await database.prepare('SELECT * FROM etudiants').all() |
|||
|
|||
XHR.onreadystatechange = () => { |
|||
if (XHR.readyState === 4) { |
|||
if (XHR.status === 200) { |
|||
let response = XHR.responseText |
|||
|
|||
console.log(response) |
|||
} else { |
|||
console.log('impossible de contacter le serveur') |
|||
} |
|||
} |
|||
} |
|||
|
|||
const data = new FormData() |
|||
|
|||
data.append('Verification', JSON.stringify(queryEtudiants)) |
|||
|
|||
XHR.open('POST', `${URL}/etudiants`, true) |
|||
XHR.setRequestHeader('x-requested-with', 'xmlhttprequest') |
|||
XHR.send(data) |
|||
} |
|||
|
|||
/** |
|||
* send data matieres to server |
|||
*/ |
|||
const sendMatieres = async () => { |
|||
const XHR = new XMLHttpRequest() |
|||
const queryMatieres = await database.prepare('SELECT * FROM matieres').all() |
|||
|
|||
XHR.onreadystatechange = () => { |
|||
if (XHR.readyState === 4) { |
|||
if (XHR.status === 200) { |
|||
let response = XHR.responseText |
|||
|
|||
console.log(response) |
|||
} else { |
|||
console.log('impossible de contacter le serveur') |
|||
} |
|||
} |
|||
} |
|||
|
|||
const data = new FormData() |
|||
|
|||
data.append('Verification', JSON.stringify(queryMatieres)) |
|||
|
|||
XHR.open('POST', `${URL}/matieres`, true) |
|||
XHR.setRequestHeader('x-requested-with', 'xmlhttprequest') |
|||
XHR.send(data) |
|||
} |
|||
|
|||
/** |
|||
* send data users to server |
|||
*/ |
|||
const sendUsers = async () => { |
|||
const XHR = new XMLHttpRequest() |
|||
const queryUsers = database.prepare('SELECT * FROM users').all() |
|||
|
|||
XHR.onreadystatechange = () => { |
|||
if (XHR.readyState === 4) { |
|||
if (XHR.status === 200) { |
|||
let response = XHR.responseText |
|||
|
|||
console.log(response) |
|||
} else { |
|||
console.log('impossible de contacter le serveur') |
|||
} |
|||
} |
|||
} |
|||
|
|||
const data = new FormData() |
|||
|
|||
data.append('Verification', JSON.stringify(queryUsers)) |
|||
|
|||
XHR.open('POST', `${URL}/users`, true) |
|||
XHR.setRequestHeader('x-requested-with', 'xmlhttprequest') |
|||
XHR.send(data) |
|||
} |
|||
|
|||
/** |
|||
* send status to server |
|||
*/ |
|||
const sendStatus = async () => { |
|||
const XHR = new XMLHttpRequest() |
|||
const queryStatus = database.prepare('SELECT * FROM status').all() |
|||
|
|||
XHR.onreadystatechange = () => { |
|||
if (XHR.readyState === 4) { |
|||
if (XHR.status === 200) { |
|||
let response = XHR.responseText |
|||
|
|||
console.log(response) |
|||
} else { |
|||
console.log('impossible de contacter le serveur') |
|||
} |
|||
} |
|||
} |
|||
|
|||
const data = new FormData() |
|||
|
|||
data.append('Verification', JSON.stringify(queryStatus)) |
|||
|
|||
XHR.open('POST', `${URL}/status`, true) |
|||
XHR.setRequestHeader('x-requested-with', 'xmlhttprequest') |
|||
XHR.send(data) |
|||
} |
|||
|
|||
/** |
|||
* send mention to server |
|||
*/ |
|||
const sendMentions = async () => { |
|||
const XHR = new XMLHttpRequest() |
|||
const queryMentions = database.prepare('SELECT * FROM mentions').all() |
|||
|
|||
XHR.onreadystatechange = () => { |
|||
if (XHR.readyState === 4) { |
|||
if (XHR.status === 200) { |
|||
let response = XHR.responseText |
|||
|
|||
console.log(response) |
|||
} else { |
|||
console.log('impossible de contacter le serveur') |
|||
} |
|||
} |
|||
} |
|||
|
|||
const data = new FormData() |
|||
|
|||
data.append('Verification', JSON.stringify(queryMentions)) |
|||
|
|||
XHR.open('POST', `${URL}/mentions`, true) |
|||
XHR.setRequestHeader('x-requested-with', 'xmlhttprequest') |
|||
XHR.send(data) |
|||
} |
|||
|
|||
/** |
|||
* send niveaus to server |
|||
*/ |
|||
const sendNiveaus = async () => { |
|||
const XHR = new XMLHttpRequest() |
|||
const queryNiveaus = database.prepare('SELECT * FROM niveaus').all() |
|||
|
|||
XHR.onreadystatechange = () => { |
|||
if (XHR.readyState === 4) { |
|||
if (XHR.status === 200) { |
|||
let response = XHR.responseText |
|||
|
|||
console.log(response) |
|||
} else { |
|||
console.log('impossible de contacter le serveur') |
|||
} |
|||
} |
|||
} |
|||
|
|||
const data = new FormData() |
|||
|
|||
data.append('Verification', JSON.stringify(queryNiveaus)) |
|||
|
|||
XHR.open('POST', `${URL}/niveaus`, true) |
|||
XHR.setRequestHeader('x-requested-with', 'xmlhttprequest') |
|||
XHR.send(data) |
|||
} |
|||
|
|||
/** |
|||
* send semestre to server |
|||
*/ |
|||
const sendSemestres = async () => { |
|||
const XHR = new XMLHttpRequest() |
|||
const querySemestres = database.prepare('SELECT * FROM semestres').all() |
|||
|
|||
XHR.onreadystatechange = () => { |
|||
if (XHR.readyState === 4) { |
|||
if (XHR.status === 200) { |
|||
let response = XHR.responseText |
|||
|
|||
console.log(response) |
|||
} else { |
|||
console.log('impossible de contacter le serveur') |
|||
} |
|||
} |
|||
} |
|||
|
|||
const data = new FormData() |
|||
|
|||
data.append('Verification', JSON.stringify(querySemestres)) |
|||
|
|||
XHR.open('POST', `${URL}/semestres`, true) |
|||
XHR.setRequestHeader('x-requested-with', 'xmlhttprequest') |
|||
XHR.send(data) |
|||
} |
|||
|
|||
/** |
|||
* send matiereMention to server |
|||
*/ |
|||
const sendMatiereMention = async () => { |
|||
const XHR = new XMLHttpRequest() |
|||
const queryMatieremantion = database.prepare('SELECT * FROM matiere_mention').all() |
|||
|
|||
XHR.onreadystatechange = () => { |
|||
if (XHR.readyState === 4) { |
|||
if (XHR.status === 200) { |
|||
let response = XHR.responseText |
|||
|
|||
console.log(response) |
|||
} else { |
|||
console.log('impossible de contacter le serveur') |
|||
} |
|||
} |
|||
} |
|||
|
|||
const data = new FormData() |
|||
|
|||
data.append('Verification', JSON.stringify(queryMatieremantion)) |
|||
|
|||
XHR.open('POST', `${URL}/matiere_mention`, true) |
|||
XHR.setRequestHeader('x-requested-with', 'xmlhttprequest') |
|||
XHR.send(data) |
|||
} |
|||
|
|||
/** |
|||
* send matiereSemestre to server |
|||
*/ |
|||
const sendMatiereSemestre = async () => { |
|||
const XHR = new XMLHttpRequest() |
|||
const queryMatieresemestre = database.prepare('SELECT * FROM matiere_semestre').all() |
|||
|
|||
XHR.onreadystatechange = () => { |
|||
if (XHR.readyState === 4) { |
|||
if (XHR.status === 200) { |
|||
let response = XHR.responseText |
|||
|
|||
console.log(response) |
|||
} else { |
|||
console.log('impossible de contacter le serveur') |
|||
} |
|||
} |
|||
} |
|||
|
|||
const data = new FormData() |
|||
|
|||
data.append('Verification', JSON.stringify(queryMatieresemestre)) |
|||
|
|||
XHR.open('POST', `${URL}/matiere_semestre`, true) |
|||
XHR.setRequestHeader('x-requested-with', 'xmlhttprequest') |
|||
XHR.send(data) |
|||
} |
|||
|
|||
/** |
|||
* send notes to server |
|||
*/ |
|||
const sendNotes = async () => { |
|||
const XHR = new XMLHttpRequest() |
|||
const queryNotes = database.prepare('SELECT * FROM notes').all() |
|||
|
|||
XHR.onreadystatechange = () => { |
|||
if (XHR.readyState === 4) { |
|||
if (XHR.status === 200) { |
|||
let response = XHR.responseText |
|||
|
|||
console.log(response) |
|||
} else { |
|||
console.log('impossible de contacter le serveur') |
|||
} |
|||
} |
|||
} |
|||
|
|||
const data = new FormData() |
|||
|
|||
data.append('Verification', JSON.stringify(queryNotes)) |
|||
|
|||
XHR.open('POST', `${URL}/notes`, true) |
|||
XHR.setRequestHeader('x-requested-with', 'xmlhttprequest') |
|||
XHR.send(data) |
|||
} |
|||
|
|||
/** |
|||
* send note repechage to server |
|||
*/ |
|||
const sendNotesRepech = async () => { |
|||
const XHR = new XMLHttpRequest() |
|||
const queryNotesRepech = database.prepare('SELECT * FROM notesrepech').all() |
|||
|
|||
XHR.onreadystatechange = () => { |
|||
if (XHR.readyState === 4) { |
|||
if (XHR.status === 200) { |
|||
let response = XHR.responseText |
|||
|
|||
console.log(response) |
|||
} else { |
|||
console.log('impossible de contacter le serveur') |
|||
} |
|||
} |
|||
} |
|||
|
|||
const data = new FormData() |
|||
|
|||
data.append('Verification', JSON.stringify(queryNotesRepech)) |
|||
|
|||
XHR.open('POST', `${URL}/notesrepech`, true) |
|||
XHR.setRequestHeader('x-requested-with', 'xmlhttprequest') |
|||
XHR.send(data) |
|||
} |
|||
|
|||
/** |
|||
* send noteSystem to server |
|||
*/ |
|||
const sendNoteSystem = async () => { |
|||
const XHR = new XMLHttpRequest() |
|||
const queryNoteSystem = database.prepare('SELECT * FROM notesystems').all() |
|||
|
|||
XHR.onreadystatechange = () => { |
|||
if (XHR.readyState === 4) { |
|||
if (XHR.status === 200) { |
|||
let response = XHR.responseText |
|||
|
|||
console.log(response) |
|||
} else { |
|||
console.log('impossible de contacter le serveur') |
|||
} |
|||
} |
|||
} |
|||
|
|||
const data = new FormData() |
|||
|
|||
data.append('Verification', JSON.stringify(queryNoteSystem)) |
|||
|
|||
XHR.open('POST', `${URL}/notesystems`, true) |
|||
XHR.setRequestHeader('x-requested-with', 'xmlhttprequest') |
|||
XHR.send(data) |
|||
} |
|||
|
|||
/** |
|||
* send annee scolaire to server |
|||
*/ |
|||
const sendAnnee = async () => { |
|||
const XHR = new XMLHttpRequest() |
|||
const queryAnnee = database.prepare('SELECT * FROM anneescolaire').all() |
|||
|
|||
XHR.onreadystatechange = () => { |
|||
if (XHR.readyState === 4) { |
|||
if (XHR.status === 200) { |
|||
let response = XHR.responseText |
|||
|
|||
console.log(response) |
|||
} else { |
|||
console.log('impossible de contacter le serveur') |
|||
} |
|||
} |
|||
} |
|||
|
|||
const data = new FormData() |
|||
|
|||
data.append('Verification', JSON.stringify(queryAnnee)) |
|||
|
|||
XHR.open('POST', `${URL}/anneescolaire`, true) |
|||
XHR.setRequestHeader('x-requested-with', 'xmlhttprequest') |
|||
XHR.send(data) |
|||
} |
|||
|
|||
/** |
|||
* send traitement system to server |
|||
*/ |
|||
const sendTraitmentSystem = async () => { |
|||
const XHR = new XMLHttpRequest() |
|||
const queryAnnee = database.prepare('SELECT * FROM traitmentsystem').all() |
|||
|
|||
XHR.onreadystatechange = () => { |
|||
if (XHR.readyState === 4) { |
|||
if (XHR.status === 200) { |
|||
let response = XHR.responseText |
|||
|
|||
console.log(response) |
|||
} else { |
|||
console.log('impossible de contacter le serveur') |
|||
} |
|||
} |
|||
} |
|||
|
|||
const data = new FormData() |
|||
|
|||
data.append('Verification', JSON.stringify(queryAnnee)) |
|||
|
|||
XHR.open('POST', `${URL}/traitmentsystem`, true) |
|||
XHR.setRequestHeader('x-requested-with', 'xmlhttprequest') |
|||
XHR.send(data) |
|||
} |
|||
|
|||
/** |
|||
* send all request to server |
|||
*/ |
|||
async function sendAll() { |
|||
try { |
|||
await sendEtudiants() |
|||
await sendMatieres() |
|||
await sendUsers() |
|||
await sendStatus() |
|||
await sendMentions() |
|||
await sendNiveaus() |
|||
await sendSemestres() |
|||
await sendMatiereMention() |
|||
await sendMatiereSemestre() |
|||
await sendNotes() |
|||
await sendNotesRepech() |
|||
await sendNoteSystem() |
|||
await sendAnnee() |
|||
await sendTraitmentSystem() |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
module.exports = { |
|||
sendAll |
|||
} |
|||
@ -0,0 +1,107 @@ |
|||
// here the data from the local and web server become one for etudiants table
|
|||
|
|||
/** |
|||
* our get and insert etudiants function, don't touch it |
|||
*/ |
|||
const { getAllEtudiants, insertEtudiant } = require('../Models/Etudiants') |
|||
|
|||
/** |
|||
* URL fro the server web, you can modify it like your Domain name |
|||
*/ |
|||
const { URL } = require('./Config') |
|||
|
|||
/** |
|||
* function to get the all etudiants |
|||
* |
|||
* @returns promise |
|||
*/ |
|||
async function getAllEtudiantsFetch() { |
|||
const etudiants = await getAllEtudiants() |
|||
|
|||
return etudiants |
|||
} |
|||
|
|||
async function verifyEtudiantTableWeb() { |
|||
/** |
|||
* class AJAX, don't touch it |
|||
*/ |
|||
const XHR = new XMLHttpRequest() |
|||
|
|||
let etudiants = await getAllEtudiantsFetch() |
|||
|
|||
XHR.onreadystatechange = () => { |
|||
if (XHR.readyState === 4) { |
|||
if (XHR.status === 200) { |
|||
// nothing here because the statement is in the server web
|
|||
} else { |
|||
console.log('impossible de contacter le server pour la syncronisation') |
|||
} |
|||
} |
|||
} |
|||
|
|||
const data = new FormData() |
|||
|
|||
data.append('Verification', JSON.stringify(etudiants)) |
|||
|
|||
XHR.open('POST', `${URL}/verifywebEtudiants`, true) |
|||
XHR.setRequestHeader('x-requested-with', 'xmlhttprequest') |
|||
XHR.send(data) |
|||
} |
|||
|
|||
async function verifyTableLocalEtudiants() { |
|||
/** |
|||
* class AJAX, don't touch it |
|||
*/ |
|||
const XHR = new XMLHttpRequest() |
|||
let etudiants = await getAllEtudiantsFetch() |
|||
|
|||
XHR.onreadystatechange = () => { |
|||
if (XHR.readyState === 4) { |
|||
if (XHR.status === 200) { |
|||
const etudiantFromWeb = JSON.parse(XHR.responseText) |
|||
|
|||
// set all email from base local in Array numInscArray
|
|||
let numInscArray = [] |
|||
for (let index = 0; index < etudiants.length; index++) { |
|||
numInscArray.push(etudiants[index]['num_inscription']) |
|||
} |
|||
|
|||
// search if the email from user from server is in local or not
|
|||
// if not, then insert it
|
|||
for (let index = 0; index < etudiantFromWeb.length; index++) { |
|||
if (numInscArray.includes(etudiantFromWeb[index]['num_inscription']) === false) { |
|||
insertEtudiant( |
|||
etudiantFromWeb[index]['nom'], |
|||
etudiantFromWeb[index]['prenom'], |
|||
etudiantFromWeb[index]['photos'], |
|||
etudiantFromWeb[index]['date_de_naissances'], |
|||
etudiantFromWeb[index]['niveau'], |
|||
etudiantFromWeb[index]['annee_scolaire'], |
|||
etudiantFromWeb[index]['num_inscription'] |
|||
) |
|||
} |
|||
} |
|||
} else { |
|||
console.log('impossible de contacter le server pour la syncronisation') |
|||
} |
|||
} |
|||
} |
|||
|
|||
XHR.open('GET', `${URL}/verifylocalEtudiants`, true) |
|||
XHR.setRequestHeader('x-requested-with', 'xmlhttprequest') |
|||
XHR.send() |
|||
} |
|||
|
|||
// Call both functions sequentially or in parallel as needed
|
|||
async function synchronizeDataEtudiants() { |
|||
try { |
|||
await verifyEtudiantTableWeb() |
|||
await verifyTableLocalEtudiants() |
|||
} catch (error) { |
|||
console.error('Error during synchronization:', error) |
|||
} |
|||
} |
|||
|
|||
module.exports = { |
|||
synchronizeDataEtudiants |
|||
} |
|||
@ -0,0 +1,108 @@ |
|||
// here the data from the local and web server become one for users table
|
|||
|
|||
/** |
|||
* our get and insert users function, don't touch it |
|||
*/ |
|||
const { getAllUsers, insertUser } = require('../Models/Users') |
|||
|
|||
/** |
|||
* URL fro the server web, you can modify it like your Domain name |
|||
*/ |
|||
const { URL } = require('./Config') |
|||
|
|||
/** |
|||
* function to get the all users |
|||
* |
|||
* @returns promise |
|||
*/ |
|||
async function getAllUsersFetch() { |
|||
const users = await getAllUsers() |
|||
|
|||
return users |
|||
} |
|||
|
|||
/** |
|||
* function to syncronise data from local to web server, |
|||
* it will be an async function to get the result of promise in getAllUsersFetch() function |
|||
*/ |
|||
async function verifyUserTableWeb() { |
|||
/** |
|||
* class AJAX, don't touch it |
|||
*/ |
|||
const XHR = new XMLHttpRequest() |
|||
let users = await getAllUsersFetch() |
|||
|
|||
XHR.onreadystatechange = () => { |
|||
if (XHR.readyState === 4) { |
|||
if (XHR.status === 200) { |
|||
// nothing here because the statement is in the server web
|
|||
} else { |
|||
console.log('impossible de contacter le server pour la syncronisation') |
|||
} |
|||
} |
|||
} |
|||
|
|||
const data = new FormData() |
|||
|
|||
data.append('Verification', JSON.stringify(users)) |
|||
|
|||
XHR.open('POST', `${URL}/verifyweb`, true) |
|||
XHR.setRequestHeader('x-requested-with', 'xmlhttprequest') |
|||
XHR.send(data) |
|||
} |
|||
|
|||
async function verifyUserTableLocal() { |
|||
/** |
|||
* class AJAX, don't touch it |
|||
*/ |
|||
const XHR = new XMLHttpRequest() |
|||
let users = await getAllUsersFetch() |
|||
|
|||
XHR.onreadystatechange = () => { |
|||
if (XHR.readyState === 4) { |
|||
if (XHR.status === 200) { |
|||
const usersFromWeb = JSON.parse(XHR.responseText) |
|||
|
|||
// set all email from base local in Array emailArray
|
|||
let emailArray = [] |
|||
for (let index = 0; index < users.length; index++) { |
|||
emailArray.push(users[index]['email']) |
|||
} |
|||
|
|||
// search if the email from user from server is in local or not
|
|||
// if not, then insert it
|
|||
for (let index = 0; index < usersFromWeb.length; index++) { |
|||
if (emailArray.includes(usersFromWeb[index]['email']) === false) { |
|||
insertUser( |
|||
usersFromWeb[index]['username'], |
|||
usersFromWeb[index]['email'], |
|||
usersFromWeb[index]['password'], |
|||
usersFromWeb[index]['photos'], |
|||
usersFromWeb[index]['roles'] |
|||
) |
|||
} |
|||
} |
|||
} else { |
|||
console.log('impossible de contacter le server pour la syncronisation') |
|||
} |
|||
} |
|||
} |
|||
|
|||
XHR.open('GET', `${URL}/verifylocal`, true) |
|||
XHR.setRequestHeader('x-requested-with', 'xmlhttprequest') |
|||
XHR.send() |
|||
} |
|||
|
|||
// Call both functions sequentially or in parallel as needed
|
|||
async function synchronizeData() { |
|||
try { |
|||
setTimeout(await verifyUserTableWeb(), 2000) |
|||
setTimeout(await verifyUserTableLocal(), 1000) |
|||
} catch (error) { |
|||
console.error('Error during synchronization:', error) |
|||
} |
|||
} |
|||
|
|||
module.exports = { |
|||
synchronizeData |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
const { app, dialog } = require('electron') |
|||
|
|||
const checkUpdate = () => {} |
|||
@ -0,0 +1,441 @@ |
|||
const sqlite = require('better-sqlite3') |
|||
const bcrypt = require('bcryptjs') |
|||
|
|||
|
|||
// Construct the database path using the detected IP
|
|||
let dbPath = `./base/data.db`; |
|||
|
|||
// Connect to SQLite database with the initial path
|
|||
let database = new sqlite(dbPath); |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
// Create the users table if it doesn't exist
|
|||
const createUserTableQuery = ` |
|||
CREATE TABLE IF NOT EXISTS users ( |
|||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, |
|||
username VARCHAR(200) NOT NULL, |
|||
email VARCHAR(250) NOT NULL UNIQUE, |
|||
password TEXT NOT NULL, |
|||
roles VARCHAR(250) NOT NULL, |
|||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
|||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP |
|||
); |
|||
` |
|||
database.prepare(createUserTableQuery).run() |
|||
|
|||
// Insert a default admin user if not exists
|
|||
const insertDefaultUserQuery = ` |
|||
INSERT INTO users (username, email, password, roles) |
|||
SELECT 'admin', 'admin@example.com', ?, 'admin' |
|||
WHERE NOT EXISTS (SELECT 1 FROM users WHERE username = 'admin'); |
|||
` |
|||
|
|||
// Hash the password '1234' before storing
|
|||
const hashedPassword = bcrypt.hashSync('123456789', 10) |
|||
database.prepare(insertDefaultUserQuery).run(hashedPassword) |
|||
|
|||
// create table for note status
|
|||
const createStatusTableQuery = ` |
|||
CREATE TABLE IF NOT EXISTS status ( |
|||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, |
|||
nom VARCHAR(200) NOT NULL, |
|||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
|||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP |
|||
); |
|||
` |
|||
database.prepare(createStatusTableQuery).run() |
|||
|
|||
// create table for mention
|
|||
const createMentionTableQuery = ` |
|||
CREATE TABLE IF NOT EXISTS mentions ( |
|||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, |
|||
nom VARCHAR(250) NOT NULL, |
|||
uniter VARCHAR(50) NOT NULL, -- Abréviation du nom |
|||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
|||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP |
|||
); |
|||
` |
|||
database.prepare(createMentionTableQuery).run() |
|||
|
|||
// Create the niveau table if it doesn't exist
|
|||
const createNiveauTableQuery = ` |
|||
CREATE TABLE IF NOT EXISTS niveaus ( |
|||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, |
|||
nom VARCHAR(50) NOT NULL, -- Exemple: L1, L2, L3, etc. |
|||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
|||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP |
|||
); |
|||
` |
|||
database.prepare(createNiveauTableQuery).run() |
|||
|
|||
// Create the etudiants table if it doesn't exist
|
|||
const createEtudiantsTableQuery = ` |
|||
CREATE TABLE IF NOT EXISTS etudiants ( |
|||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, |
|||
nom VARCHAR(250) DEFAULT NULL, |
|||
prenom VARCHAR(250) DEFAULT NULL, |
|||
photos TEXT NOT NULL, |
|||
date_de_naissances DATE NOT NULL, |
|||
niveau VARCHAR(250) NOT NULL, -- Clé étrangère vers niveaus |
|||
annee_scolaire VARCHAR(20) NOT NULL, |
|||
status INTEGER NOT NULL, |
|||
mention_id INTEGER NOT NULL, -- Clé étrangère vers mentions |
|||
num_inscription TEXT NOT NULL UNIQUE, |
|||
sexe VARCHAR(20) NOT NULL, |
|||
cin VARCHAR(250) DEFAULT NULL, |
|||
date_delivrence DEFAULT NULL, |
|||
nationalite DATE NOT NULL, |
|||
annee_bacc DATE NOT NULL, |
|||
serie VARCHAR(20) NOT NULL, |
|||
boursier BOOLEAN DEFAULT FALSE, |
|||
domaine VARCHAR(250) NOT NULL, |
|||
contact VARCHAR(20) NOT NULL, |
|||
parcours VARCHAR(250) DEFAULT NULL, |
|||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
|||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
|||
FOREIGN KEY (status) REFERENCES status(id), |
|||
FOREIGN KEY (mention_id) REFERENCES mentions(id) |
|||
); |
|||
` |
|||
database.prepare(createEtudiantsTableQuery).run() |
|||
|
|||
// Create the notes table if it doesn't exist
|
|||
const createMatiereTableQuery = ` |
|||
CREATE TABLE IF NOT EXISTS matieres ( |
|||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, |
|||
nom VARCHAR(250) UNIQUE NOT NULL, |
|||
unite_enseignement VARCHAR(250) NOT NULL, |
|||
credit INTEGER NOT NULL, |
|||
heure INTEGER NOT NULL, |
|||
ue VARCHAR(10) NOT NULL, |
|||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
|||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP |
|||
); |
|||
` |
|||
database.prepare(createMatiereTableQuery).run() |
|||
|
|||
// Create the semestre table if it doesn't exist
|
|||
const createSemestreTableQuery = ` |
|||
CREATE TABLE IF NOT EXISTS semestres ( |
|||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, |
|||
nom VARCHAR(30) NOT NULL, -- Exemple: S1, S2, S3, etc. |
|||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
|||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP |
|||
); |
|||
` |
|||
database.prepare(createSemestreTableQuery).run() |
|||
|
|||
// Create the semestre table if it doesn't exist
|
|||
const createMatiere_mentionTableQuery = ` |
|||
CREATE TABLE IF NOT EXISTS matiere_mention ( |
|||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, |
|||
matiere_id INTEGER NOT NULL, -- Clé étrangère vers matieres |
|||
mention_id INTEGER NOT NULL, -- Clé étrangère vers mentions |
|||
FOREIGN KEY (matiere_id) REFERENCES matieres(id), |
|||
FOREIGN KEY (mention_id) REFERENCES mentions(id) |
|||
); |
|||
` |
|||
database.prepare(createMatiere_mentionTableQuery).run() |
|||
|
|||
const createMatiere_semestreTableQuery = ` |
|||
CREATE TABLE IF NOT EXISTS matiere_semestre ( |
|||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, |
|||
matiere_id INTEGER NOT NULL, -- Clé étrangère vers matieres |
|||
semestre_id INTEGER NOT NULL, -- Clé étrangère vers semestres |
|||
mention_id INTEGER NOT NULL, -- Clé étrangère vers niveaus |
|||
FOREIGN KEY (matiere_id) REFERENCES matieres(id), |
|||
FOREIGN KEY (semestre_id) REFERENCES semestres(id), |
|||
FOREIGN KEY (mention_id) REFERENCES mentions(id) |
|||
); |
|||
` |
|||
database.prepare(createMatiere_semestreTableQuery).run() |
|||
|
|||
// Create the notes table if it doesn't exist
|
|||
const createNoteTableQuery = ` |
|||
CREATE TABLE IF NOT EXISTS notes ( |
|||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, |
|||
etudiant_id INTEGER NOT NULL, -- Clé étrangère vers etudiants |
|||
matiere_id INTEGER NOT NULL, -- Clé étrangère vers matieres |
|||
etudiant_niveau VARCHAR(50) NOT NULL, |
|||
mention_id INTEGER NOT NULL, |
|||
note FLOAT DEFAULT NULL, |
|||
annee_scolaire VARCHAR(50) NOT NULL, |
|||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
|||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
|||
FOREIGN KEY (etudiant_id) REFERENCES etudiants(id), |
|||
FOREIGN KEY (matiere_id) REFERENCES matieres(id) |
|||
FOREIGN KEY (mention_id) REFERENCES mentions(id) |
|||
); |
|||
` |
|||
database.prepare(createNoteTableQuery).run() |
|||
|
|||
// Create the notes second session table if it doesn't exist
|
|||
const createNoteRepechTableQuery = ` |
|||
CREATE TABLE IF NOT EXISTS notesrepech ( |
|||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, |
|||
etudiant_id INTEGER NOT NULL, -- Clé étrangère vers etudiants |
|||
matiere_id INTEGER NOT NULL, -- Clé étrangère vers matieres |
|||
etudiant_niveau VARCHAR(50) NOT NULL, |
|||
mention_id INTEGER NOT NULL, |
|||
note FLOAT DEFAULT NULL, |
|||
annee_scolaire VARCHAR(50) NOT NULL, |
|||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
|||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
|||
FOREIGN KEY (etudiant_id) REFERENCES etudiants(id), |
|||
FOREIGN KEY (matiere_id) REFERENCES matieres(id) |
|||
FOREIGN KEY (mention_id) REFERENCES mentions(id) |
|||
); |
|||
` |
|||
database.prepare(createNoteRepechTableQuery).run() |
|||
|
|||
// create table for note système
|
|||
const createNoteSystemeTableQuery = ` |
|||
CREATE TABLE IF NOT EXISTS notesystems ( |
|||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, |
|||
admis FLOAT NOT NULL DEFAULT 10, |
|||
redouble FLOAT NOT NULL DEFAULT 9.99, |
|||
renvoyer FLOAT NOT NULL DEFAULT 7.99, |
|||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
|||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP |
|||
); |
|||
` |
|||
database.prepare(createNoteSystemeTableQuery).run() |
|||
|
|||
// create table année scolaire
|
|||
const createAnneeScolaireTableQuery = ` |
|||
CREATE TABLE IF NOT EXISTS anneescolaire ( |
|||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, |
|||
code VARCHAR(30) NOT NULL, |
|||
debut DATE NOT NULL, |
|||
fin DATE NOT NULL, |
|||
is_current INTEGER DEFAULT 0, |
|||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
|||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP |
|||
); |
|||
` |
|||
database.prepare(createAnneeScolaireTableQuery).run() |
|||
|
|||
// create traitement systeme
|
|||
const createTraitementSystemQuery = ` |
|||
CREATE TABLE IF NOT EXISTS traitmentsystem ( |
|||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, |
|||
code VARCHAR(30) NOT NULL, |
|||
debut DATE NOT NULL, |
|||
fin DATE NOT NULL, |
|||
is_finished INTEGER DEFAULT 0, |
|||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
|||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP |
|||
); |
|||
` |
|||
database.prepare(createTraitementSystemQuery).run() |
|||
|
|||
const createNecessaryParameterTableQuery = ` |
|||
CREATE TABLE IF NOT EXISTS nessesaryTable ( |
|||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, |
|||
uniter_heure INTEGER NOT NULL, |
|||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
|||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP |
|||
); |
|||
` |
|||
database.prepare(createNecessaryParameterTableQuery).run() |
|||
|
|||
const createMatiereEnseignantTableQuery = ` |
|||
CREATE TABLE IF NOT EXISTS matiereEnseignants ( |
|||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, |
|||
matiere_id INTEGER NOT NULL, |
|||
nom_enseignant VARCHAR(250) NOT NULL, |
|||
prenom_enseignant VARCHAR(250) NOT NULL, |
|||
contact VARCHAR(11) NOT NULL, |
|||
date DATE NOT NULL, |
|||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
|||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
|||
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 |
|||
); |
|||
` |
|||
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 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 { |
|||
let arraySemestre = [ |
|||
'S1', |
|||
'S2', |
|||
'S3', |
|||
'S4', |
|||
'S5', |
|||
'S6', |
|||
'S7', |
|||
'S8', |
|||
'S9', |
|||
'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) { |
|||
console.log(error) |
|||
} |
|||
} |
|||
|
|||
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
|
|||
createNecessaryParameterTable() |
|||
|
|||
semestreCreate() |
|||
|
|||
// Function to get the IP from the database
|
|||
function getIP() { |
|||
const data = database.prepare("SELECT * FROM ipconfig WHERE id = 1").get(); |
|||
|
|||
if (data) { |
|||
return data.ipname; |
|||
} else { |
|||
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 = { |
|||
database |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
const fs = require('fs') |
|||
const { PDFDocument } = require('pdf-lib') |
|||
const path = require('path') |
|||
|
|||
async function modifyPDF(filepath) { |
|||
// Load the existing PDF
|
|||
const existingPdfBytes = fs.readFileSync(path.join(__dirname, '/../../src/renderer/', filepath)) |
|||
|
|||
// Load the PDF document
|
|||
const pdfDoc = await PDFDocument.load(existingPdfBytes) |
|||
|
|||
// Embed the font for text replacement
|
|||
const pages = pdfDoc.getPages() |
|||
const firstPage = pages[0] |
|||
|
|||
// Replace text based on your data object
|
|||
const data = { f1: 'Nom', f2: 'Prénom', f3: 23 } |
|||
|
|||
// Example of replacing placeholders
|
|||
firstPage.drawText(data.f1, { x: 120, y: 700, size: 12 }) |
|||
firstPage.drawText(data.f2, { x: 120, y: 680, size: 12 }) |
|||
firstPage.drawText(String(data.f3), { x: 120, y: 660, size: 12 }) |
|||
|
|||
// Save the modified PDF
|
|||
const pdfBytes = await pdfDoc.save() |
|||
fs.writeFileSync('releves_modified.pdf', pdfBytes) |
|||
|
|||
console.log('PDF modified successfully!') |
|||
} |
|||
|
|||
module.exports = { |
|||
modifyPDF |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
function getCompressedDefaultImage() { |
|||
return ` |
|||
data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/4gHYSUNDX1BST0ZJTEUAAQEAAAHIAAAAAAQwAABtbnRyUkdCIFhZWiAH4AABAAEAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAACRyWFlaAAABFAAAABRnWFlaAAABKAAAABRiWFlaAAABPAAAABR3dHB0AAABUAAAABRyVFJDAAABZAAAAChnVFJDAAABZAAAAChiVFJDAAABZAAAAChjcHJ0AAABjAAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAAgAAAAcAHMAUgBHAEJYWVogAAAAAAAAb6IAADj1AAADkFhZWiAAAAAAAABimQAAt4UAABjaWFlaIAAAAAAAACSgAAAPhAAAts9YWVogAAAAAAAA9tYAAQAAAADTLXBhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABtbHVjAAAAAAAAAAEAAAAMZW5VUwAAACAAAAAcAEcAbwBvAGcAbABlACAASQBuAGMALgAgADIAMAAxADb/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCAD6APoDASIAAhEBAxEB/8QAHAABAAIDAQEBAAAAAAAAAAAAAAYHAwQFAggB/8QAQRAAAgEDAgIHBQUFBQkAAAAAAAECAwQFBhESMQcTIUFRcYEUImGhwUJSkbHRFRYXMnIjM0NTsjRUYnSCkqLS4f/EABQBAQAAAAAAAAAAAAAAAAAAAAD/xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwD7LAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATPo1wFplbu5vb+hGtStoqMISW6c33+iXzJpldC6eylJx9jjbVNvdqUVwtenJgUwDs6j0rktOV+G5j1lCT2p14r3Zefg/gcYAAAAAAA2sZi77L3UbPH0JVakvDlFeLfcizsB0cYnHU41cpFXly+1p/3cX4Jd/mwKnBaOv9L4yOCnkLGypUK1rKMm6cduKDezT/AB39CrgAAAAAAAAAAAAAAAAAAAAAAAAAAAtPorpKGDuKu3bUuH8kkTUiXRittNb+Nef0JaBgvbK1yFtUs7yjGrRqLaUZFRap0be4O/jC0pVLi2rv+xlGO8t/uvbvLkAFMWWgdU3sVNY7qYvvrTUPlz+R0P4Wai4d/abHfw6yX/qWuAKavOj7VNmnP2BV4rvozUvlz+Rzcfp/KZHJQxdO0qU60n73WRceBd7e5e5+cMeLj4Vxbbb7duwHL09p2x07ZK2tI8VSXbVqte9N/p8DqgAczUtJV8BkKTW/Fbz/ACKKL9y64sVeJ99Cf+llBAAAAAAAAAAAAAAAAAAAAAAAAAAABbfRi99NJeFef0JaQ/ov4v3dnvFpdfLZ7c+xEwAAAAAAAAAAADUy72xd43/kT/0soIvnPS4MJfT8Lef5FDAAAAAAAAAAAAAAAAAAAAAAAAADJb0Kt1cU7ahHiqVZqEV4tvZGMknR9Zq81PbOS3jQUqvql2fmBbGJxtHEY23x1D+WjBRb+8+9+rNwAAAAAAAAAAAAMF7a0760rWdX+StBwl5NFC39nUx97Xsqy2nQqSpv0Z9AlR9JljG11I7iC2V1RjUf9S91/kgImAAAAAAAAAAAAAAAAAAAAAAAATXoqinm7mT5xt3t/wByIUTHotqqGfq02+2pbyS9GmBa4AAAAAAAAAAAAAVr0tRSvMdLvdOon+KLKKx6WKqlkrGjv2woyl+Mv/gEFAAAAAAAAAAAAAAAAAAAAAAAAO3ou+WP1LZVpy2hOfVSfwl2fnscQJuLUotprtTQH0QDj6UzcM9hqF25J1orq6y8Jrm/XmdgAAAAAAAAAAABTOv8hHIanueCW8LdRoRf9PP/AMmy1dQZelhMTXyFWSThHamvvTfJFFVas61Wdao95zk5Sfi2B5AAAAAAAAAAAAAAAAAAAAAAAAAAHd0jqetpvIdY952tbaNamvDukvii5LO8tchbU7uzrRq0qi3jKLPn46+n9UZTTtfjs6inSk/foz7YS/R/EC8QRjDdIWByijC4rexVnzjWfu7/AAly/IksJwqwVSnOM4yW6lF7pgegAAAPyUowi5TkopdrbeyQH6Yrm5oWlCdzdVY0qVNcUpyeySOBmNfafxUZRp3Ku6y5QoviW/xlyK21Fq3K6jqbXE+qt094UIP3V5+LAz6z1VPUd6oUHKNlQbVKL7OJ/eZHQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbNnlMljnvY31eh3tU6jSfmjWNuyxGUyUuGwx9xX8XCm2l5vkgOtQ19qqikv2k6m334Rf0Nj+JWqdtuvoefUo82/Rxqmuk52lKjv/AJlVfTc2l0W6g27bi0T8ON/oBoVukDVVZbftHq/6KcV9DkXuXymR/wBuyFxXXhOo2vw5EgrdGepqS3hC3q/CNXt+exx7/TOfxicrzE3EIrnNQ4or/qW6A5gDTXYwAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3sPhMjnbtWmPoOcn/NJ9kYLxbA0Um3slu33EpwXR5mctw1rpexW77eKpHebXwj+uxOtNaGxeBUbirGN1eL/ABZrsi/+Fd3nzJKBHcToTTuKUZeye01V9uv73b5ciQQhCnFQpxUYrsSS2SPQAAAAAAOTk9LYHLp+2Y6lxv8AxILhl+KIPnei+8tuKvhLj2mnz6mp2TXk+T+RZwA+e7i2uLStK3uqM6VSD2lGa2aMZemc05itQUOqv7dOaXuVY9k4eT+hVWptHZHTlTrJLr7ST92tFcvhJdzA4AAAAAAAAAAAAAAAAAAAAAAAdTTuAutQ5GFlbpxgveq1NuyEfH9AM2mNL3upLvq6P9nb02utrNdkV4LxZcOJw9hhLSNnYUVCC5v7Un4t97PWLxdnh7KnYWNJQpU16yfe34s2wAAAAAAAAAAAAAAeK1GlcUpUK9ONSnNbSjJbpo9gCqdaaGqYhzyeLi52Te84c3S/WJDT6GnCFSEqdSKlGS2aa3TRUuutIPBXHt9jBuxrS5c+ql4eXgBEwAAAAAAAAAAAAAAAAAB7oUKtzXp29CDnUqyUIRXNt8kXZpXT1HTuLhaxSdefv15r7UvDyRDui/AKtWqZ64hvGk3Tobr7Xe/Tl6llAAAAAAAAAAAAAAAAAAAAMF7Z2+QtatndU1OlWi4yi/AzgCitR4Ovp/KVbCsm4r3qU/vwfJ/T0OYXBr/ALMYaVzRhvc2adSGy7XH7S/Dt9CnwAAAAAAAAAAAAAAZLehUua9O3pLedWShFfFsxkn6Osb7fqSlVnHenaQdd+fKPze/oBauIx1LE4y2x1FJRoU1Hzfe/V7s3AAAAAAAAAAAAAAAAAAAAAAAAUjrDDrC564tacOGjN9bSXcoy7dvTkXcQDpXxvHa2eVhHtpzdCb+DW6+af4gVsAAAAAAAAAAAAAFk9E1qo2t/etds6kaSfwS3+pWxa/Rcl+79T/mJfkgJiAAAAAAAAAAAAAAAAAAAAAAAAcLW9qrvS9/T23cKaqrzi0/od00M8k8JfJ/7vP8AIChgAAAAAAAf/9k= |
|||
` |
|||
} |
|||
|
|||
module.exports = { |
|||
getCompressedDefaultImage |
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
const { database } = require('../database') |
|||
|
|||
const getStatusMention = (menstionText) => { |
|||
const query = database.prepare('SELECT * FROM status') |
|||
|
|||
let response = query.all() |
|||
let statutCode |
|||
for (let index = 0; index < response.length; index++) { |
|||
let nom = response[index].nom |
|||
let nomLower = nom.toLowerCase() // Correct method
|
|||
let find1 = menstionText.slice(0, 1) |
|||
let find2 = menstionText.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 |
|||
} |
|||
} |
|||
|
|||
return statutCode |
|||
} |
|||
|
|||
module.exports = { |
|||
getStatusMention |
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
/** |
|||
* function to convert array to string and string to array |
|||
* @param {*} input |
|||
* @param {String} separator |
|||
* @returns {*} |
|||
*/ |
|||
function convertArrayAndString(input, separator = ', ') { |
|||
// If the separator is just a comma without a space, change it to ", "
|
|||
if (separator === ',') { |
|||
separator = ', ' |
|||
} |
|||
|
|||
if (Array.isArray(input)) { |
|||
// Convert array to string with the correct separator
|
|||
return input.join(separator) |
|||
} else if (typeof input === 'string') { |
|||
// Convert string to array using the separator
|
|||
return input.split(separator) |
|||
} else { |
|||
throw new Error('Input must be either an array or a string.') |
|||
} |
|||
} |
|||
|
|||
module.exports = { |
|||
convertArrayAndString |
|||
} |
|||
@ -0,0 +1,332 @@ |
|||
const { database } = require('../database') |
|||
const dayjs = require('dayjs') |
|||
|
|||
async function updateCurrentYears() { |
|||
const fullDate = dayjs().format('YYYY-MM-DD') |
|||
|
|||
// Clear current year flag
|
|||
const clearCurrent = database.prepare('UPDATE anneescolaire SET is_Current = 0 WHERE id > 0') |
|||
clearCurrent.run() |
|||
|
|||
// Set the new current year
|
|||
const updateCurrent = database.prepare(` |
|||
UPDATE anneescolaire |
|||
SET is_Current = 1 |
|||
WHERE ? >= debut AND ? <= fin |
|||
`)
|
|||
// console.log();
|
|||
updateCurrent.run(fullDate, fullDate) |
|||
|
|||
// Check if the update was successful
|
|||
const check = database |
|||
.prepare( |
|||
` |
|||
SELECT * FROM anneescolaire |
|||
WHERE ? >= debut AND ? <= fin |
|||
` |
|||
) |
|||
.get(fullDate, fullDate) |
|||
|
|||
// Insert into traitmentsystem if a current year exists
|
|||
if (check) { |
|||
let search = database.prepare('SELECT * FROM traitmentsystem WHERE code = ?').get(check.code) |
|||
console.log(search) |
|||
if (!search) { |
|||
const insertQuery = database.prepare(` |
|||
INSERT INTO traitmentsystem (code, debut, fin) |
|||
VALUES (?, ?, ?) |
|||
`)
|
|||
insertQuery.run(check.code, check.debut, check.fin) |
|||
} |
|||
} else { |
|||
console.log('No active school year found for the current date.') |
|||
} |
|||
} |
|||
|
|||
async function updateStudents() { |
|||
const getInfinishedYears = database |
|||
.prepare('SELECT * FROM traitmentsystem WHERE is_finished = 0 ORDER BY id ASC') |
|||
.get() |
|||
|
|||
const allEtudiants = database |
|||
.prepare('SELECT * FROM etudiants WHERE annee_scolaire = ?') |
|||
.all(getInfinishedYears.code) |
|||
|
|||
function checkNull(params) { |
|||
if (params == null || params == undefined) { |
|||
return null |
|||
} |
|||
return params |
|||
} |
|||
|
|||
function compareSessionNotes(session1, session2) { |
|||
let notes |
|||
if (session2) { |
|||
if (session1 < session2.note) { |
|||
notes = session2.note |
|||
} else { |
|||
notes = session1 |
|||
} |
|||
} else { |
|||
notes = session1 |
|||
} |
|||
return notes |
|||
} |
|||
|
|||
database.transaction(() => { |
|||
// get all note of student
|
|||
const queryNotes = database.prepare( |
|||
`SELECT DISTINCT etudiant_id FROM notes WHERE etudiant_niveau = ? AND annee_scolaire = ?` |
|||
) |
|||
let allEtudiantWithNotes = [] |
|||
let etudiantWithNotes = [] |
|||
let dataToMap = [] |
|||
let allEtudiantWithNotesRepech = [] |
|||
let etudiantWithNotesRepech = [] |
|||
|
|||
for (const etudiant of allEtudiants) { |
|||
const results = queryNotes.all(etudiant.niveau, etudiant.annee_scolaire) |
|||
etudiantWithNotes.push(...results) // Avoid nested arrays
|
|||
} |
|||
|
|||
const uniqueId = etudiantWithNotes.filter( |
|||
(item, index, self) => index === self.findIndex((t) => t.etudiant_id === item.etudiant_id) |
|||
) |
|||
|
|||
const query2 = database.prepare( |
|||
'SELECT notes.*, etudiants.*, matieres.id, matieres.nom AS nomMat, matieres.credit FROM notes LEFT JOIN etudiants ON (notes.etudiant_id = etudiants.id) LEFT JOIN matieres ON (notes.matiere_id = matieres.id) WHERE notes.etudiant_id = ?' |
|||
) |
|||
|
|||
for (let j = 0; j < uniqueId.length; j++) { |
|||
allEtudiantWithNotes.push(query2.all(uniqueId[j].etudiant_id)) |
|||
} |
|||
|
|||
const query = database.prepare( |
|||
`SELECT DISTINCT etudiant_id FROM notesrepech WHERE etudiant_niveau = ? AND annee_scolaire = ?` |
|||
) |
|||
|
|||
for (const etudiant of allEtudiants) { |
|||
const results = query.all(etudiant.niveau, etudiant.annee_scolaire) |
|||
etudiantWithNotesRepech.push(...results) // Avoid nested arrays
|
|||
} |
|||
|
|||
const uniqueIdRepech = etudiantWithNotes.filter( |
|||
(item, index, self) => index === self.findIndex((t) => t.etudiant_id === item.etudiant_id) |
|||
) |
|||
|
|||
const query2Repech = database.prepare( |
|||
'SELECT notesrepech.*, etudiants.*, matieres.id, matieres.nom AS nomMat, matieres.credit FROM notesrepech INNER JOIN etudiants ON (notesrepech.etudiant_id = etudiants.id) INNER JOIN matieres ON (notesrepech.matiere_id = matieres.id) WHERE notesrepech.etudiant_id = ?' |
|||
) |
|||
|
|||
for (let j = 0; j < uniqueIdRepech.length; j++) { |
|||
allEtudiantWithNotesRepech.push(query2Repech.all(uniqueIdRepech[j].etudiant_id)) |
|||
} |
|||
|
|||
for (let index = 0; index < allEtudiantWithNotes.length; index++) { |
|||
let total = 0 |
|||
let note = 0 |
|||
let totalCredit = 0 |
|||
|
|||
// Create a new object for each student
|
|||
let modelJson = { |
|||
id: '', |
|||
nom: '', |
|||
prenom: '', |
|||
photos: '', |
|||
moyenne: '', |
|||
mention: '', |
|||
niveau: '', |
|||
annee_scolaire: '' |
|||
} |
|||
|
|||
for (let j = 0; j < allEtudiantWithNotes[index].length; j++) { |
|||
modelJson.id = allEtudiantWithNotes[index][j].etudiant_id |
|||
modelJson.nom = allEtudiantWithNotes[index][j].nom |
|||
modelJson.prenom = allEtudiantWithNotes[index][j].prenom |
|||
modelJson.photos = allEtudiantWithNotes[index][j].photos |
|||
modelJson.mention = allEtudiantWithNotes[index][j].mention_id |
|||
modelJson.niveau = allEtudiantWithNotes[index][j].niveau |
|||
modelJson.annee_scolaire = allEtudiantWithNotes[index][j].annee_scolaire |
|||
|
|||
// console.log(checkNull(session[index][j]));
|
|||
if (allEtudiantWithNotesRepech[index]) { |
|||
note += |
|||
compareSessionNotes( |
|||
allEtudiantWithNotes[index][j].note, |
|||
checkNull(allEtudiantWithNotesRepech[index][j]) |
|||
) * allEtudiantWithNotes[index][j].credit |
|||
} else { |
|||
note += allEtudiantWithNotes[index][j].note * allEtudiantWithNotes[index][j].credit |
|||
} |
|||
totalCredit += allEtudiantWithNotes[index][j].credit |
|||
} |
|||
|
|||
total = note / totalCredit |
|||
modelJson.moyenne = total.toFixed(2) |
|||
|
|||
// Add the new object to the array
|
|||
dataToMap.push(modelJson) |
|||
} |
|||
|
|||
// update all etudiant
|
|||
let updated = false |
|||
if (dataToMap.length != 0) { |
|||
let noteSystem = database.prepare('SELECT * FROM notesystems').get() |
|||
for (let index = 0; index < dataToMap.length; index++) { |
|||
if (dataToMap[index].moyenne >= noteSystem.admis) { |
|||
let updateQuery = database.prepare( |
|||
'UPDATE etudiants SET niveau = ?, annee_scolaire = ?, status = ? WHERE id = ?' |
|||
) |
|||
updateQuery.run( |
|||
nextLevel(dataToMap[index].niveau), |
|||
updateSchoolYear(dataToMap[index].annee_scolaire), |
|||
2, |
|||
dataToMap[index].id |
|||
) |
|||
updated = true |
|||
} else if ( |
|||
dataToMap[index].moyenne < noteSystem.admis && |
|||
dataToMap[index].moyenne >= noteSystem.redouble |
|||
) { |
|||
let updateQuery = database.prepare( |
|||
'UPDATE etudiants SET niveau = ?, annee_scolaire = ? status = ? WHERE id = ?' |
|||
) |
|||
updateQuery.run( |
|||
dataToMap[index].niveau, |
|||
updateSchoolYear(dataToMap[index].annee_scolaire), |
|||
3, |
|||
dataToMap[index].id |
|||
) |
|||
updated = true |
|||
} else { |
|||
let updateQuery = database.prepare( |
|||
'UPDATE etudiants SET niveau = ?, annee_scolaire = ? status = ? WHERE id = ?' |
|||
) |
|||
updateQuery.run( |
|||
dataToMap[index].niveau, |
|||
dataToMap[index].annee_scolaire, |
|||
4, |
|||
dataToMap[index].id |
|||
) |
|||
updated = true |
|||
} |
|||
} |
|||
} |
|||
|
|||
if (updated) { |
|||
const updateInfinishedYears = database.prepare( |
|||
'UPDATE traitmentsystem SET is_finished = 1 WHERE id = ?' |
|||
) |
|||
|
|||
updateInfinishedYears.run(getInfinishedYears.id) |
|||
} |
|||
})() |
|||
} |
|||
|
|||
function nextLevel(niveau) { |
|||
if (niveau == 'L1') { |
|||
return 'L2' |
|||
} else if (niveau == 'L2') { |
|||
return 'L3' |
|||
} else if (niveau == 'L3') { |
|||
return 'M1' |
|||
} else if (niveau == 'M1') { |
|||
return 'M2' |
|||
} else if (niveau == 'M2') { |
|||
return 'D1' |
|||
} else if (niveau == 'D1') { |
|||
return 'D2' |
|||
} else if (niveau == 'D2') { |
|||
return 'D3' |
|||
} else if (niveau == 'D3') { |
|||
return 'PHD' |
|||
} |
|||
} |
|||
|
|||
function updateSchoolYear(year) { |
|||
// Split the year into two parts
|
|||
const [startYear, endYear] = year.split('-').map(Number) |
|||
|
|||
// Increment both the start and end year by 1
|
|||
const newStartYear = startYear + 1 |
|||
const newEndYear = endYear + 1 |
|||
|
|||
// Join the new years with a hyphen
|
|||
const newYear = `${newStartYear}-${newEndYear}` |
|||
|
|||
return newYear |
|||
} |
|||
|
|||
async function matiereSysteme(etudiant_niveau) { |
|||
let systeme |
|||
if (etudiant_niveau == 'L1') { |
|||
systeme = ['S1', 'S2'] |
|||
} else if (etudiant_niveau == 'L2') { |
|||
systeme = ['S3', 'S4'] |
|||
} else if (etudiant_niveau == 'L3') { |
|||
systeme = ['S5', 'S6'] |
|||
} else if (etudiant_niveau == 'M1') { |
|||
systeme = ['S7', 'S8'] |
|||
} else if (etudiant_niveau == 'M2') { |
|||
systeme = ['S9', 'S10'] |
|||
} else if (etudiant_niveau == 'D1') { |
|||
systeme = ['S11', 'S12'] |
|||
} else if (etudiant_niveau == 'D2') { |
|||
systeme = ['S13', 'S14'] |
|||
} else if (etudiant_niveau == 'D3') { |
|||
systeme = ['S15', 'S16'] |
|||
} |
|||
|
|||
return systeme |
|||
} |
|||
|
|||
async function matiereSystemReverse(semestre) { |
|||
if (semestre == 'S1' || semestre == 'S2') { |
|||
return 'L1' |
|||
} else if (semestre == 'S3' || semestre == 'S4') { |
|||
return 'L2' |
|||
} else if (semestre == 'S5' || semestre == 'S6') { |
|||
return 'L3' |
|||
} else if (semestre == 'S7' || semestre == 'S8') { |
|||
return 'M1' |
|||
} else if (semestre == 'S9' || semestre == 'S10') { |
|||
return 'M2' |
|||
} else if (semestre == 'S11' || semestre == 'S12') { |
|||
return 'D1' |
|||
} else if (semestre == 'S13' || semestre == 'S14') { |
|||
return 'D2' |
|||
} else if (semestre == 'S15' || semestre == 'S16') { |
|||
return 'D3' |
|||
} |
|||
} |
|||
|
|||
async function getNessesarytable() { |
|||
try { |
|||
const query = await database.prepare('SELECT * FROM nessesaryTable').get() |
|||
|
|||
return query |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
async function updateNessesaryTable(id, multiplicateur) { |
|||
const query = database.prepare('UPDATE nessesaryTable SET uniter_heure = ? WHERE id = ?') |
|||
|
|||
try { |
|||
let update = query.run(multiplicateur, id) |
|||
|
|||
return update |
|||
} catch (error) { |
|||
return error |
|||
} |
|||
} |
|||
|
|||
module.exports = { |
|||
matiereSysteme, |
|||
updateCurrentYears, |
|||
updateStudents, |
|||
getNessesarytable, |
|||
updateNessesaryTable, |
|||
matiereSystemReverse |
|||
} |
|||
@ -0,0 +1,210 @@ |
|||
const fs = require('fs') |
|||
const path = require('path') |
|||
const XLSX = require('xlsx') |
|||
const { getCompressedDefaultImage } = require('../function/GetImageDefaault') |
|||
const { parse } = require('csv-parse/sync') |
|||
const { insertEtudiant } = require('../Models/Etudiants') |
|||
const { database } = require('../database') |
|||
const { getMentions } = require('../Models/Mentions') |
|||
const dayjs = require('dayjs') |
|||
const { getStatusMention } = require('../function/Helper') |
|||
const customParseFormat = require('dayjs/plugin/customParseFormat') |
|||
dayjs.extend(customParseFormat) |
|||
|
|||
// Function to convert any date format to 'YYYY-MM-DD'
|
|||
function convertToISODate(input) { |
|||
// Try parsing the date with different formats
|
|||
const formats = [ |
|||
'DD/MM/YYYY', |
|||
'MM/DD/YYYY', |
|||
'YYYY-MM-DD', |
|||
'DD-MM-YYYY', |
|||
'MM-DD-YYYY', |
|||
'DD/MM/YY', |
|||
'MM/DD/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') |
|||
} |
|||
|
|||
function excelDateToJSDate(serial) { |
|||
const utc_days = Math.floor(serial - 25569); // days from Jan 1, 1970
|
|||
const utc_value = utc_days * 86400; // seconds in a day
|
|||
return new Date(utc_value * 1000); // JS Date uses milliseconds
|
|||
} |
|||
|
|||
let jsDate = excelDateToJSDate(input); |
|||
|
|||
// If the input is not a valid date, return 'Invalid Date'
|
|||
return jsDate |
|||
} |
|||
|
|||
async function MentionList() { |
|||
let response = await getMentions() |
|||
return response |
|||
} |
|||
|
|||
let ListMention |
|||
|
|||
/** |
|||
* 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) { |
|||
const fileExtension = path.extname(filePath).toLowerCase() |
|||
|
|||
// Determine the file type and parse accordingly
|
|||
let records |
|||
if (fileExtension === '.xlsx') { |
|||
// Read and parse XLSX file
|
|||
const workbook = XLSX.readFile(filePath) |
|||
const worksheet = workbook.Sheets[workbook.SheetNames[0]] // Assuming data is in the first sheet
|
|||
records = XLSX.utils.sheet_to_json(worksheet, { defval: '', raw: false }) |
|||
} else if (fileExtension === '.csv') { |
|||
// Read and parse CSV file
|
|||
const fileContent = fs.readFileSync(filePath, 'utf8') |
|||
records = parse(fileContent, { |
|||
columns: true, |
|||
skip_empty_lines: true |
|||
}) |
|||
} else { |
|||
console.error('Unsupported file format. Only .xlsx and .csv are allowed.') |
|||
return |
|||
} |
|||
|
|||
try { |
|||
let error = true |
|||
let message = '' |
|||
|
|||
// Vérifier les données en une seule boucle
|
|||
for (const row of records) { |
|||
console.log(convertToISODate(row.date_naissance)) |
|||
if ( |
|||
!row.nom || |
|||
// !row.prenom ||
|
|||
!row.date_naissance || |
|||
!row.niveau || |
|||
!row.annee_scolaire || |
|||
!row.mention || |
|||
!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 |
|||
} |
|||
} |
|||
|
|||
async function fetchMentions() { |
|||
try { |
|||
// Fetch the mentions
|
|||
ListMention = await MentionList() |
|||
|
|||
// Assuming 'ListMention' is an array of objects like the ones you mentioned
|
|||
// Si aucune erreur, insérer les données en batch
|
|||
if (error !== false) { |
|||
// Utiliser transaction pour éviter une latence si l'insertion dépasse 100
|
|||
database.transaction(() => { |
|||
for (const row of records) { |
|||
// Convert row.mention to uppercase and compare with ListMention.nom and ListMention.uniter (also converted to uppercase)
|
|||
const matchedMention = ListMention.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 |
|||
} |
|||
// Insert the student data with the updated mention ID
|
|||
insertEtudiant( |
|||
row.nom, |
|||
row.prenom, |
|||
getCompressedDefaultImage(), |
|||
convertToISODate(row.date_naissance), |
|||
row.niveau, |
|||
row.annee_scolaire, |
|||
getStatusMention(row.code_redoublement), |
|||
row.num_inscription, |
|||
row.mention, |
|||
row.sexe, |
|||
row.nationaliter, |
|||
row.cin, |
|||
row.date_de_livraison, |
|||
row.annee_baccalaureat, |
|||
row.serie, |
|||
row.boursier, |
|||
row.domaine, |
|||
row.contact |
|||
) |
|||
} |
|||
})() |
|||
} |
|||
} catch (error) { |
|||
console.error('Error:', error) // Handle any errors
|
|||
} |
|||
} |
|||
|
|||
fetchMentions() |
|||
|
|||
return { error, message } |
|||
} catch (error) { |
|||
console.error('Error inserting record:', error) |
|||
return { error: 'error' } |
|||
} |
|||
} |
|||
|
|||
module.exports = { |
|||
importFileToDatabase |
|||
} |
|||
@ -0,0 +1,69 @@ |
|||
const fs = require('fs') |
|||
const path = require('path') |
|||
const XLSX = require('xlsx') |
|||
const { parse } = require('csv-parse/sync') |
|||
const { createMatiere } = require('../Models/Matieres') |
|||
const { database } = require('../database') |
|||
|
|||
/** |
|||
* Function to import data from the first column of an XLSX or CSV file into SQLite database |
|||
* @param {string} filePath - Path to the file (either .xlsx or .csv) |
|||
*/ |
|||
async function importFileToDatabaseMatiere(filePath) { |
|||
const fileExtension = path.extname(filePath).toLowerCase() |
|||
|
|||
// Determine the file type and parse accordingly
|
|||
let records |
|||
if (fileExtension === '.xlsx') { |
|||
// Read and parse XLSX file
|
|||
const workbook = XLSX.readFile(filePath) |
|||
const worksheet = workbook.Sheets[workbook.SheetNames[0]] // Assuming data is in the first sheet
|
|||
records = XLSX.utils.sheet_to_json(worksheet, { defval: '' }) |
|||
} else if (fileExtension === '.csv') { |
|||
// Read and parse CSV file
|
|||
const fileContent = fs.readFileSync(filePath, 'utf8') |
|||
records = parse(fileContent, { |
|||
columns: true, |
|||
skip_empty_lines: true |
|||
}) |
|||
} else { |
|||
console.error('Unsupported file format. Only .xlsx and .csv are allowed.') |
|||
return |
|||
} |
|||
|
|||
try { |
|||
let message = '' |
|||
let error = true |
|||
for (const row of records) { |
|||
if (!row.nom || !row.credit || !row.uniter || !row.ue) { |
|||
if (!row.nom) { |
|||
message = "Le champ 'nom' est inconnu" |
|||
} else if (!row.credit) { |
|||
message = "Le champ 'credit' est inconnu" |
|||
} else if (!row.uniter) { |
|||
message = "Le champ 'uniter' est inconnu" |
|||
} else if (!row.ue) { |
|||
message = "Le champ 'UE' est inconnu" |
|||
} |
|||
error = false |
|||
break |
|||
} |
|||
} |
|||
|
|||
if (error !== false) { |
|||
database.transaction(() => { |
|||
for (const row of records) { |
|||
createMatiere(row.nom, row.credit, row.uniter, row.ue) |
|||
} |
|||
})() |
|||
} |
|||
|
|||
return { error, message } |
|||
} catch (error) { |
|||
console.error('Error inserting record:', error) |
|||
} |
|||
} |
|||
|
|||
module.exports = { |
|||
importFileToDatabaseMatiere |
|||
} |
|||
@ -0,0 +1,52 @@ |
|||
const fs = require('fs') |
|||
const path = require('path') |
|||
const XLSX = require('xlsx') |
|||
const { parse } = require('csv-parse/sync') |
|||
const { insertNiveau } = require('../Models/Niveau') |
|||
|
|||
async function importNiveau(filePath) { |
|||
const fileExtension = path.extname(filePath).toLowerCase() |
|||
|
|||
// Determine the file type and parse accordingly
|
|||
let records |
|||
if (fileExtension === '.xlsx') { |
|||
// Read and parse XLSX file
|
|||
const workbook = XLSX.readFile(filePath) |
|||
const worksheet = workbook.Sheets[workbook.SheetNames[0]] // Assuming data is in the first sheet
|
|||
records = XLSX.utils.sheet_to_json(worksheet, { defval: '' }) |
|||
} else if (fileExtension === '.csv') { |
|||
// Read and parse CSV file
|
|||
const fileContent = fs.readFileSync(filePath, 'utf8') |
|||
records = parse(fileContent, { |
|||
columns: true, |
|||
skip_empty_lines: true |
|||
}) |
|||
} else { |
|||
console.error('Unsupported file format. Only .xlsx and .csv are allowed.') |
|||
return |
|||
} |
|||
|
|||
try { |
|||
// Get the first column key dynamically
|
|||
const firstColumnKey = Object.keys(records[0])[0] |
|||
console.log(`Detected first column key: ${firstColumnKey}`) |
|||
|
|||
for (const row of records) { |
|||
const firstColumnValue = row[firstColumnKey] || 'null pour le moment' |
|||
|
|||
// Insert into the database
|
|||
await insertNiveau(firstColumnValue) |
|||
console.log(`Inserted value from first column: '${firstColumnValue}'`) |
|||
} |
|||
console.log( |
|||
`First column values successfully imported from ${fileExtension.toUpperCase()} file` |
|||
) |
|||
return { success: 'success' } |
|||
} catch (error) { |
|||
console.error('Error inserting record:', error) |
|||
} |
|||
} |
|||
|
|||
module.exports = { |
|||
importNiveau |
|||
} |
|||
@ -0,0 +1,45 @@ |
|||
appId: com.electron.app |
|||
productName: CUniversity |
|||
directories: |
|||
buildResources: build |
|||
files: |
|||
- '!**/.vscode/*' |
|||
- '!src/*' |
|||
- '!electron.vite.config.{js,ts,mjs,cjs}' |
|||
- '!{.eslintignore,.eslintrc.cjs,.prettierignore,.prettierrc.yaml,dev-app-update.yml,CHANGELOG.md,README.md}' |
|||
- '!{.env,.env.*,.npmrc,pnpm-lock.yaml}' |
|||
asarUnpack: |
|||
- resources/** |
|||
win: |
|||
executableName: CUniversity |
|||
nsis: |
|||
artifactName: ${name}-${version}-setup.${ext} |
|||
shortcutName: ${productName} |
|||
uninstallDisplayName: ${productName} |
|||
createDesktopShortcut: always |
|||
mac: |
|||
entitlementsInherit: build/entitlements.mac.plist |
|||
extendInfo: |
|||
- NSCameraUsageDescription: Application requests access to the device's camera. |
|||
- NSMicrophoneUsageDescription: Application requests access to the device's microphone. |
|||
- NSDocumentsFolderUsageDescription: Application requests access to the user's Documents folder. |
|||
- NSDownloadsFolderUsageDescription: Application requests access to the user's Downloads folder. |
|||
notarize: false |
|||
dmg: |
|||
artifactName: ${name}-${version}.${ext} |
|||
linux: |
|||
target: |
|||
- AppImage |
|||
- snap |
|||
- deb |
|||
maintainer: electronjs.org |
|||
category: Utility |
|||
appImage: |
|||
artifactName: ${name}-${version}.${ext} |
|||
npmRebuild: false |
|||
publish: |
|||
provider: generic |
|||
url: https://api.polytechnique.c4m.mg/latest |
|||
channel: latest |
|||
useMultipleRangeRequest: false |
|||
|
|||
@ -0,0 +1,25 @@ |
|||
// 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 } |
|||
@ -0,0 +1,25 @@ |
|||
// 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 } |
|||
@ -0,0 +1,23 @@ |
|||
import { resolve } from 'path' |
|||
import { defineConfig, externalizeDepsPlugin } from 'electron-vite' |
|||
import react from '@vitejs/plugin-react' |
|||
|
|||
export 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')
|
|||
} |
|||
}) |
|||
@ -0,0 +1,85 @@ |
|||
{ |
|||
"name": "c-university", |
|||
"version": "4.1.0", |
|||
"description": "An Electron application with React", |
|||
"main": "./out/main/index.js", |
|||
"author": "CPAY COMPANY FOR MADACASCAR", |
|||
"homepage": "https://electron-vite.org", |
|||
"scripts": { |
|||
"format": "prettier --write .", |
|||
"lint": "eslint . --ext .js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix", |
|||
"start": "electron-vite preview", |
|||
"dev": "electron-vite dev", |
|||
"build": "electron-vite build", |
|||
"postinstall": "electron-builder install-app-deps", |
|||
"build:unpack": "npm run build && electron-builder --dir", |
|||
"build:win": "npm run build && electron-builder --win", |
|||
"build:mac": "npm run build && electron-builder --mac", |
|||
"build:linux": "npm run build && electron-builder --linux" |
|||
}, |
|||
"build": { |
|||
"appId": "com.myapp", |
|||
"win": { |
|||
"target": "nsis", |
|||
"publish": [ |
|||
{ |
|||
"provider": "generic", |
|||
"url": "https://api.polytechnique.c4m.mg/latest" |
|||
} |
|||
] |
|||
} |
|||
}, |
|||
"dependencies": { |
|||
"@electron-toolkit/preload": "^3.0.1", |
|||
"@electron-toolkit/utils": "^3.0.0", |
|||
"@emotion/react": "^11.13.3", |
|||
"@emotion/styled": "^11.13.0", |
|||
"@mui/material": "^6.1.1", |
|||
"@mui/x-data-grid": "^7.18.0", |
|||
"ag-psd": "^22.0.2", |
|||
"axios": "^1.9.0", |
|||
"bcryptjs": "^2.4.3", |
|||
"better-sqlite3": "^11.3.0", |
|||
"bootstrap": "^5.3.3", |
|||
"chart.js": "^4.4.4", |
|||
"cors": "^2.8.5", |
|||
"csv-parse": "^5.5.6", |
|||
"dayjs": "^1.11.13", |
|||
"electron-log": "^5.2.0", |
|||
"electron-updater": "^6.3.9", |
|||
"express": "^4.21.2", |
|||
"file-saver": "^2.0.5", |
|||
"html2canvas": "^1.4.1", |
|||
"jspdf": "^2.5.2", |
|||
"jspdf-autotable": "^5.0.2", |
|||
"papaparse": "^5.4.1", |
|||
"pdf-lib": "^1.17.1", |
|||
"qrcode": "^1.5.4", |
|||
"react-bootstrap": "^2.10.4", |
|||
"react-chartjs-2": "^5.2.0", |
|||
"react-icons": "^5.3.0", |
|||
"react-pdf": "^6.2.2", |
|||
"react-router-dom": "^6.26.2", |
|||
"react-spinners": "^0.14.1", |
|||
"react-tooltip": "^5.28.0", |
|||
"reselect": "^5.1.1", |
|||
"update-electron-app": "^3.0.0", |
|||
"xlsx": "^0.18.5", |
|||
"xlsx-populate": "^1.21.0" |
|||
}, |
|||
"devDependencies": { |
|||
"@electron-toolkit/eslint-config": "^1.0.2", |
|||
"@electron-toolkit/eslint-config-prettier": "^2.0.0", |
|||
"@vitejs/plugin-react": "^4.3.1", |
|||
"electron": "^31.0.2", |
|||
"electron-builder": "^24.13.3", |
|||
"electron-vite": "^2.3.0", |
|||
"eslint": "^8.57.0", |
|||
"eslint-plugin-react": "^7.34.3", |
|||
"npm": "^10.9.2", |
|||
"prettier": "^3.3.2", |
|||
"react": "^18.3.1", |
|||
"react-dom": "^18.3.1", |
|||
"vite": "^5.3.1" |
|||
} |
|||
} |
|||
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 43 KiB |
@ -0,0 +1,103 @@ |
|||
validation addmatiere |
|||
update annee scolaire |
|||
when delete matiere, delete also matiere_mention and matiere_semestre |
|||
|
|||
SELECT * |
|||
FROM table_name |
|||
WHERE NOW() BETWEEN debut AND fin; |
|||
|
|||
// End date (example) |
|||
const endDate = new Date("2025-03-20"); // Replace with your actual end date |
|||
|
|||
// Calculate the date 3 months before the end date |
|||
const threeMonthsBefore = new Date(endDate); |
|||
threeMonthsBefore.setMonth(threeMonthsBefore.getMonth() - 3); |
|||
|
|||
// Get the current date |
|||
const currentDate = new Date(); |
|||
|
|||
// Check if the current date is between threeMonthsBefore and endDate |
|||
if (currentDate >= threeMonthsBefore && currentDate <= endDate) { |
|||
console.log("The current date is within 3 months before the end date."); |
|||
} else { |
|||
console.log("The current date is outside the range."); |
|||
} |
|||
|
|||
Since you have an **Ethernet network** (but no Wi-Fi or router), you can share the SQLite database (`data.db`) over the network by sharing a folder. Here's how you can do it: |
|||
|
|||
--- |
|||
|
|||
### **Step 1: Share the Database Folder Over the Network** |
|||
#### **On PC 1 (Hosting the Database)** |
|||
1. **Locate the folder** |
|||
- Your database is at: |
|||
``` |
|||
C:\electron\database\data.db |
|||
``` |
|||
- Open **File Explorer** and go to `C:\electron\database\`. |
|||
|
|||
2. **Right-click on the `database` folder → Click 'Properties'** |
|||
- Go to the **'Sharing'** tab. |
|||
- Click **'Advanced Sharing'**. |
|||
- Check **'Share this folder'**. |
|||
|
|||
3. **Set Permissions** |
|||
- Click **'Permissions'**. |
|||
- Select **'Everyone'** and give **Full Control** (or at least Read/Write if both PCs need to modify the database). |
|||
- Click **OK** and **Apply**. |
|||
|
|||
4. **Note the Network Path** |
|||
- Open **Command Prompt** (`Win + R` → `cmd` → Enter). |
|||
- Type: |
|||
```sh |
|||
ipconfig |
|||
``` |
|||
- Look for your **Ethernet Adapter IPv4 Address** (e.g., `192.168.1.100`). |
|||
|
|||
The shared path will be: |
|||
``` |
|||
\\192.168.1.100\database |
|||
``` |
|||
|
|||
--- |
|||
|
|||
### **Step 2: Access the Database from PC 2** |
|||
#### **On PC 2 (Client PC)** |
|||
1. **Map the Network Drive** |
|||
- Open **File Explorer**. |
|||
- Click **'This PC' → 'Map Network Drive'**. |
|||
- Choose a drive letter (e.g., `Z:`). |
|||
- Enter the **Network Path** from Step 1 (e.g., `\\192.168.1.100\database`). |
|||
- Click **Finish**. |
|||
|
|||
2. **Modify SQLite Connection in Electron** |
|||
In your Electron app on PC 2, change: |
|||
```javascript |
|||
const sqlite = require('better-sqlite3'); |
|||
const database = new sqlite('//192.168.1.100/database/data.db'); |
|||
``` |
|||
OR, if you mapped it to `Z:\`: |
|||
```javascript |
|||
const database = new sqlite('Z:/data.db'); |
|||
``` |
|||
|
|||
--- |
|||
|
|||
### **Step 3: Test the Connection** |
|||
1. **Run the Electron app on PC 2** and check if it can read/write to `data.db`. |
|||
2. If there's an error, check: |
|||
- **Folder permissions** (PC 1 should allow read/write access). |
|||
- **Windows Firewall** (Allow File Sharing for `Private Networks`). |
|||
- **Network Discovery** (Enable it in **Control Panel → Network & Sharing Center**). |
|||
|
|||
--- |
|||
|
|||
### **Important Notes** |
|||
- **Concurrency Issues:** SQLite locks the file when writing, so only one PC should write at a time. If you need multiple write operations, consider using a **server-based approach** (like Node.js with Express). |
|||
- **Performance:** Network latency may cause slow database operations. |
|||
- **Auto-Reconnection:** If PC 1 reboots, PC 2 might lose connection. You can remap the drive automatically on startup. |
|||
|
|||
--- |
|||
|
|||
**✅ Done!** Now both PCs can access `data.db` over Ethernet. 🚀 |
|||
Let me know if you need further help! |
|||
@ -0,0 +1,255 @@ |
|||
import { app, shell, BrowserWindow, ipcMain, Tray } from 'electron' |
|||
import { join } from 'path' |
|||
import { electronApp, optimizer, is } from '@electron-toolkit/utils' |
|||
import icon from '../../resources/icon.png?asset' |
|||
const { loginUser, forgotPassword, insertUser, updateUser } = require('../../database/Models/Users') |
|||
const { |
|||
insertEtudiant, |
|||
getSingleEtudiant, |
|||
FilterDataByNiveau, |
|||
updateEtudiant |
|||
} = require('../../database/Models/Etudiants') |
|||
const { insertNiveau } = require('../../database/Models/Niveau') |
|||
const { insertNote } = require('../../database/Models/Notes') |
|||
|
|||
// declare mainWindow in the global scope
|
|||
let mainWindow |
|||
let tray = null |
|||
|
|||
function createWindow() { |
|||
// Create the browser window.
|
|||
mainWindow = new BrowserWindow({ |
|||
width: 1000, |
|||
minWidth: 1000, |
|||
height: 670, |
|||
minHeight: 670, |
|||
show: false, |
|||
autoHideMenuBar: true, |
|||
fullscreen: true, // This will make the window fullscreen when opened
|
|||
...(process.platform === 'linux' ? { icon } : {}), |
|||
webPreferences: { |
|||
preload: join(__dirname, '../preload/index.js'), |
|||
nodeIntegration: true, |
|||
contextIsolation: true, |
|||
sandbox: false |
|||
} |
|||
}) |
|||
|
|||
mainWindow.on('ready-to-show', () => { |
|||
mainWindow.show() |
|||
}) |
|||
|
|||
mainWindow.webContents.setWindowOpenHandler((details) => { |
|||
shell.openExternal(details.url) |
|||
return { action: 'deny' } |
|||
}) |
|||
|
|||
// HMR for renderer base on electron-vite cli.
|
|||
// Load the remote URL for development or the local html file for production.
|
|||
if (is.dev && process.env['ELECTRON_RENDERER_URL']) { |
|||
mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL']) |
|||
} else { |
|||
mainWindow.loadFile(join(__dirname, '../renderer/index.html')) |
|||
} |
|||
} |
|||
|
|||
// This method will be called when Electron has finished
|
|||
// initialization and is ready to create browser windows.
|
|||
// Some APIs can only be used after this event occurs.
|
|||
app.whenReady().then(() => { |
|||
// Set app user model id for windows
|
|||
electronApp.setAppUserModelId('com.electron') |
|||
|
|||
// Default open or close DevTools by F12 in development
|
|||
// and ignore CommandOrControl + R in production.
|
|||
// see https://github.com/alex8088/electron-toolkit/tree/master/packages/utils
|
|||
app.on('browser-window-created', (_, window) => { |
|||
optimizer.watchWindowShortcuts(window) |
|||
}) |
|||
|
|||
// IPC test
|
|||
ipcMain.on('pingpong', () => console.log('pongsss')) |
|||
|
|||
createWindow() |
|||
|
|||
app.on('activate', function () { |
|||
// On macOS it's common to re-create a window in the app when the
|
|||
// dock icon is clicked and there are no other windows open.
|
|||
if (BrowserWindow.getAllWindows().length === 0) createWindow() |
|||
}) |
|||
}) |
|||
|
|||
// Quit when all windows are closed, except on macOS. There, it's common
|
|||
// for applications and their menu bar to stay active until the user quits
|
|||
// explicitly with Cmd + Q.
|
|||
app.on('window-all-closed', () => { |
|||
if (process.platform !== 'darwin') { |
|||
app.quit() |
|||
} |
|||
}) |
|||
|
|||
// In this file you can include the rest of your app"s specific main process
|
|||
// code. You can also put them in separate files and require them here.
|
|||
|
|||
// Event for handling login
|
|||
ipcMain.handle('login', async (event, credentials) => { |
|||
const { username, password } = credentials |
|||
|
|||
const users = await loginUser(username, password) |
|||
|
|||
if (users) { |
|||
return { success: true, user: users } |
|||
} else { |
|||
return { success: false } |
|||
} |
|||
}) |
|||
|
|||
// Event for handling insert other user
|
|||
ipcMain.handle('insertUser', async (event, credentials) => { |
|||
const { username, email, password, roles } = credentials |
|||
|
|||
const users = await insertUser(username, email, password, roles) |
|||
|
|||
return users |
|||
}) |
|||
|
|||
// event for handlign forgot password
|
|||
ipcMain.handle('forgotPassword', async (event, credentials) => { |
|||
const { email, password, passwordConfirmation } = credentials |
|||
|
|||
const updated = await forgotPassword(email, password, passwordConfirmation) |
|||
|
|||
if (updated) { |
|||
return updated |
|||
} |
|||
}) |
|||
|
|||
// event for updating users
|
|||
ipcMain.handle('updateUsers', async (event, credentials) => { |
|||
const { username, email, passwordVerif, password, id } = credentials |
|||
|
|||
const update = await updateUser(username, email, password, id) |
|||
|
|||
return update |
|||
}) |
|||
|
|||
// event for quit app
|
|||
ipcMain.handle('quit', async () => { |
|||
app.quit() |
|||
}) |
|||
|
|||
// event for minimizing the app
|
|||
ipcMain.handle('minimize', async () => { |
|||
if (mainWindow) { |
|||
mainWindow.minimize() |
|||
} |
|||
}) |
|||
|
|||
// event for insert etudiants
|
|||
ipcMain.handle('insertEtudiant', async (event, credentials) => { |
|||
const { nom, prenom, photos, date_de_naissances, niveau, annee_scolaire, num_inscription } = |
|||
credentials |
|||
|
|||
const insert = await insertEtudiant( |
|||
nom, |
|||
prenom, |
|||
photos, |
|||
date_de_naissances, |
|||
niveau, |
|||
annee_scolaire, |
|||
num_inscription |
|||
) |
|||
|
|||
return insert |
|||
}) |
|||
|
|||
// event for fetching single
|
|||
ipcMain.handle('getByNiveau', async (event, credentials) => { |
|||
const { niveau } = credentials |
|||
|
|||
const getSingle = await FilterDataByNiveau(niveau) |
|||
|
|||
return getSingle |
|||
}) |
|||
|
|||
// event for fetching single
|
|||
ipcMain.handle('single', async (event, credentials) => { |
|||
const { id } = credentials |
|||
|
|||
const getSingle = await getSingleEtudiant(id) |
|||
|
|||
return getSingle |
|||
}) |
|||
|
|||
// event for inserting niveau
|
|||
ipcMain.handle('insertNiveau', async (event, credentials) => { |
|||
const { nom } = credentials |
|||
|
|||
const insert = await insertNiveau(nom) |
|||
|
|||
return insert |
|||
}) |
|||
|
|||
// event for updating etudiants
|
|||
ipcMain.handle('updateETudiants', async (event, credentials) => { |
|||
const { nom, prenom, photos, date_de_naissances, niveau, annee_scolaire, num_inscription, id } = |
|||
credentials |
|||
|
|||
const updating = await updateEtudiant( |
|||
nom, |
|||
prenom, |
|||
photos, |
|||
date_de_naissances, |
|||
niveau, |
|||
annee_scolaire, |
|||
num_inscription, |
|||
id |
|||
) |
|||
|
|||
return updating |
|||
}) |
|||
|
|||
// event for adding notes
|
|||
ipcMain.handle('insertNote', async (event, credentials) => { |
|||
const { |
|||
etudiant_id, |
|||
Algebre, |
|||
Analyse, |
|||
Mecanique_Generale_I, |
|||
Resistance_Materiaux, |
|||
Electricite, |
|||
Chimie_Generale_1, |
|||
Algorithmique, |
|||
Thermodynamique_Physique, |
|||
Mecanique_Fluide, |
|||
Optique_Geometrique, |
|||
Calcul_Numerique, |
|||
Calcul_Vectoriel_Integral, |
|||
Francais, |
|||
Anglais, |
|||
Dessin_Technique, |
|||
Programmation |
|||
} = credentials |
|||
|
|||
const insert = await insertNote( |
|||
etudiant_id, |
|||
Algebre, |
|||
Analyse, |
|||
Mecanique_Generale_I, |
|||
Resistance_Materiaux, |
|||
Electricite, |
|||
Chimie_Generale_1, |
|||
Algorithmique, |
|||
Thermodynamique_Physique, |
|||
Mecanique_Fluide, |
|||
Optique_Geometrique, |
|||
Calcul_Numerique, |
|||
Calcul_Vectoriel_Integral, |
|||
Francais, |
|||
Anglais, |
|||
Dessin_Technique, |
|||
Programmation |
|||
) |
|||
|
|||
return insert |
|||
}) |
|||
@ -0,0 +1,908 @@ |
|||
import { app, shell, BrowserWindow, ipcMain, Tray, Menu, screen } from 'electron' |
|||
import { join } from 'path' |
|||
const path = require('path') |
|||
import { electronApp, optimizer, is } from '@electron-toolkit/utils' |
|||
import icon from '../../resources/logo.ico?asset' // Your tray icon file
|
|||
const { createConfigIp, updateIPConfig } = require('../../database/Models/IpConfig') |
|||
const { importFileToDatabase } = require('../../database/import/Etudiants') |
|||
const { loginUser, forgotPassword, insertUser, updateUser } = require('../../database/Models/Users') |
|||
const { |
|||
insertEtudiant, |
|||
getSingleEtudiant, |
|||
FilterDataByNiveau, |
|||
updateEtudiant, |
|||
changePDP, |
|||
updateParcours, |
|||
createTranche, |
|||
getTranche, |
|||
updateTranche, |
|||
deleteTranche, |
|||
getSingleTranche |
|||
} = require('../../database/Models/Etudiants') |
|||
const { |
|||
insertNiveau, |
|||
updateNiveau, |
|||
getSingleNiveau, |
|||
deleteNiveau |
|||
} = require('../../database/Models/Niveau') |
|||
const { |
|||
insertNote, |
|||
getNote, |
|||
updateNote, |
|||
showMoyen, |
|||
getMatiereAndNote, |
|||
getNotesWithRepechToDisplay |
|||
} = require('../../database/Models/Notes') |
|||
const { |
|||
createMatiere, |
|||
getSingleMatiere, |
|||
updateMatiere, |
|||
displayMatiereFromForm, |
|||
deleteMatiere, |
|||
asygnationToMention, |
|||
getMentionMatiere, |
|||
getMentionMatiereChecked, |
|||
getSemestreMatiere, |
|||
insertUpdateMentionSemestre, |
|||
insertNewProf, |
|||
getSIngleProf, |
|||
updateProf |
|||
} = require('../../database/Models/Matieres') |
|||
const { importFileToDatabaseMatiere } = require('../../database/import/Matieres') |
|||
const { importNiveau } = require('../../database/import/Niveau') |
|||
const { updateSysteme } = require('../../database/Models/NoteSysrem') |
|||
const { |
|||
createAnneeScolaire, |
|||
deleteAnneeScolaire, |
|||
getSingleAnneScolaire, |
|||
updateAnneeScolaire, |
|||
setCurrent |
|||
} = require('../../database/Models/AnneeScolaire') |
|||
const { |
|||
createMention, |
|||
deleteMention, |
|||
getSingleMention, |
|||
updateMention |
|||
} = require('../../database/Models/Mentions') |
|||
const { modifyPDF } = require('../../database/function/DownloadReleverNote') |
|||
const log = require('electron-log') |
|||
const { |
|||
getNoteRepech, |
|||
updateNoteRepech, |
|||
showMoyenRepech |
|||
} = require('../../database/Models/NoteRepechage') |
|||
const { |
|||
updateCurrentYears, |
|||
updateStudents, |
|||
updateNessesaryTable |
|||
} = require('../../database/function/System') |
|||
const { autoUpdater } = require('electron-updater') |
|||
const { URL } = require('../../database/api/Config') |
|||
const { |
|||
insertParcour, |
|||
getSingleParcours, |
|||
deletes, |
|||
updateparcour, |
|||
parcourMatiere, |
|||
extractFiche, |
|||
getParcourMatiere |
|||
} = require('../../database/Models/Parcours') |
|||
const express = require('express'); |
|||
|
|||
// Declare mainWindow and tray in the global scope
|
|||
let mainWindow |
|||
let tray = null |
|||
updateCurrentYears() |
|||
updateStudents() |
|||
|
|||
autoUpdater.setFeedURL({ |
|||
provider: 'generic', |
|||
url: `${URL}/latest` // Ensure this points to the folder containing latest.yml
|
|||
}) |
|||
|
|||
|
|||
function createWindow() { |
|||
// Create the browser window.
|
|||
mainWindow = new BrowserWindow({ |
|||
width: 1375, |
|||
minWidth: 1375, |
|||
height: 740, |
|||
minHeight: 740, |
|||
show: false, |
|||
autoHideMenuBar: true, |
|||
fullscreen: false, |
|||
icon: path.join(__dirname, 'resources', 'logo.ico'), // Path to your icon,
|
|||
...(process.platform === 'linux' ? { icon } : {}), |
|||
webPreferences: { |
|||
preload: join(__dirname, '../preload/index.js'), |
|||
nodeIntegration: true, |
|||
contextIsolation: true, |
|||
sandbox: false |
|||
} |
|||
}) |
|||
|
|||
// Désactiver les raccourcis clavier
|
|||
mainWindow.webContents.on('before-input-event', (event, input) => { |
|||
if (input.control || input.meta || input.alt || input.key === 'F11') { |
|||
event.preventDefault() |
|||
} |
|||
}) |
|||
|
|||
mainWindow.on('ready-to-show', () => { |
|||
|
|||
mainWindow.maximize() // Maximiser la fenêtre
|
|||
mainWindow.show() |
|||
}) |
|||
|
|||
mainWindow.webContents.setWindowOpenHandler((details) => { |
|||
shell.openExternal(details.url) |
|||
return { action: 'deny' } |
|||
}) |
|||
|
|||
// Load the appropriate URL based on environment
|
|||
if (is.dev && process.env['ELECTRON_RENDERER_URL']) { |
|||
mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL']) |
|||
} else { |
|||
mainWindow.loadFile(join(__dirname, '../renderer/index.html')) |
|||
} |
|||
|
|||
// Handle window close (hide instead of closing)
|
|||
mainWindow.on('close', (event) => { |
|||
if (!app.isQuiting) { |
|||
event.preventDefault() |
|||
mainWindow.hide() // Minimize to tray instead of closing
|
|||
} else { |
|||
// Destroy the tray when quitting
|
|||
if (tray) tray.destroy() |
|||
} |
|||
}) |
|||
} |
|||
|
|||
// Function to create the system tray
|
|||
function createTray() { |
|||
const iconPath = icon // Use your icon path here
|
|||
tray = new Tray(iconPath) |
|||
|
|||
// Create a context menu for the tray
|
|||
const contextMenu = Menu.buildFromTemplate([ |
|||
{ |
|||
label: 'Ouvrir', |
|||
click: () => { |
|||
mainWindow.show() |
|||
mainWindow.webContents.send('navigateToRoute', '#/') // Send the route as a string
|
|||
} |
|||
}, |
|||
{ |
|||
label: 'A Propos', |
|||
click: () => { |
|||
mainWindow.show() |
|||
mainWindow.webContents.send('navigateToRoute', '#/apropos') // Send the route as a string
|
|||
} |
|||
}, |
|||
{ |
|||
label: 'Quit', |
|||
click: () => { |
|||
// Clear localStorage in the renderer process
|
|||
mainWindow.webContents |
|||
.executeJavaScript('localStorage.removeItem("ACCESS_TOKEN");') |
|||
.then(() => { |
|||
console.log('localStorage cleared.') |
|||
// Ensure the app quits entirely
|
|||
if (tray) { |
|||
app.quit() |
|||
tray.destroy() |
|||
// if (app.quit()) {
|
|||
// tray.destroy()
|
|||
// }
|
|||
} // Quit the app
|
|||
}) |
|||
.catch((err) => { |
|||
console.error('Error clearing localStorage:', err) |
|||
// Quit the app even if clearing fails
|
|||
if (tray) { |
|||
app.quit() |
|||
tray.destroy() |
|||
// if (app.quit()) {
|
|||
// tray.destroy()
|
|||
// }
|
|||
} |
|||
|
|||
}) |
|||
} |
|||
} |
|||
]) |
|||
|
|||
tray.setToolTip('My Electron App') |
|||
tray.setContextMenu(contextMenu) |
|||
|
|||
// Show the app when the tray icon is clicked
|
|||
tray.on('click', () => { |
|||
mainWindow.show() |
|||
}) |
|||
} |
|||
|
|||
app.whenReady().then(() => { |
|||
electronApp.setAppUserModelId('com.electron') |
|||
autoUpdater.checkForUpdatesAndNotify(); |
|||
|
|||
app.on('browser-window-created', (_, window) => { |
|||
optimizer.watchWindowShortcuts(window) |
|||
}) |
|||
|
|||
createWindow() |
|||
createTray() // Create the tray icon
|
|||
|
|||
app.on('activate', function () { |
|||
if (BrowserWindow.getAllWindows().length === 0) createWindow() |
|||
}) |
|||
}) |
|||
|
|||
// When an update is available
|
|||
autoUpdater.on('update-available', () => { |
|||
dialog.showMessageBox({ |
|||
type: 'info', |
|||
title: 'Mise à jour disponible', |
|||
message: 'Une nouvelle version est disponible. Téléchargement en cours...', |
|||
}); |
|||
}); |
|||
|
|||
// When the update is downloaded
|
|||
autoUpdater.on('update-downloaded', (info) => { |
|||
dialog.showMessageBox({ |
|||
type: 'info', |
|||
title: 'Mise à jour prête', |
|||
message: `La version ${info.version} a été téléchargée. Redémarrer maintenant ?`, |
|||
buttons: ['Redémarrer', 'Plus tard'], |
|||
}).then((result) => { |
|||
if (result.response === 0) { |
|||
autoUpdater.quitAndInstall(); |
|||
} |
|||
}); |
|||
}); |
|||
|
|||
// If an error occurs
|
|||
autoUpdater.on('error', (error) => { |
|||
dialog.showErrorBox('Update Error', error == null ? 'Unknown' : error.message); |
|||
}); |
|||
|
|||
// Quit the app when all windows are closed, except on macOS
|
|||
app.on('window-all-closed', () => { |
|||
if (process.platform !== 'darwin') { |
|||
app.quit() |
|||
} |
|||
}) |
|||
|
|||
// In this file you can include the rest of your app"s specific main process
|
|||
// code. You can also put them in separate files and require them here.
|
|||
|
|||
// Event for handling login
|
|||
ipcMain.handle('login', async (event, credentials) => { |
|||
const { username, password } = credentials |
|||
|
|||
const users = await loginUser(username, password) |
|||
|
|||
if (users) { |
|||
return { success: true, user: users } |
|||
} else { |
|||
return { success: false } |
|||
} |
|||
}) |
|||
|
|||
// Event for handling insert other user
|
|||
ipcMain.handle('insertUser', async (event, credentials) => { |
|||
const { username, email, password, roles } = credentials |
|||
|
|||
const users = await insertUser(username, email, password, roles) |
|||
|
|||
return users |
|||
}) |
|||
|
|||
// event for handlign forgot password
|
|||
ipcMain.handle('forgotPassword', async (event, credentials) => { |
|||
const { email, password, passwordConfirmation } = credentials |
|||
|
|||
const updated = await forgotPassword(email, password, passwordConfirmation) |
|||
|
|||
if (updated) { |
|||
return updated |
|||
} |
|||
}) |
|||
|
|||
// event for updating users
|
|||
ipcMain.handle('updateUsers', async (event, credentials) => { |
|||
const { username, newUsername, email, newEmail, passwordVerif, password, id } = credentials |
|||
|
|||
const update = await updateUser(newUsername, newEmail, password, id) |
|||
|
|||
return update |
|||
}) |
|||
|
|||
// event for quit app
|
|||
ipcMain.handle('quit', async () => { |
|||
app.quit() |
|||
}) |
|||
|
|||
// event for minimizing the app
|
|||
ipcMain.handle('minimize', async () => { |
|||
if (mainWindow) { |
|||
mainWindow.minimize() |
|||
} |
|||
}) |
|||
|
|||
// event for insert etudiants
|
|||
ipcMain.handle('insertEtudiant', async (event, credentials) => { |
|||
const { |
|||
nom, |
|||
prenom, |
|||
photos, |
|||
date_de_naissances, |
|||
niveau, |
|||
annee_scolaire, |
|||
status, |
|||
num_inscription, |
|||
mention_id, |
|||
sexe, |
|||
nationaliter, |
|||
cin, |
|||
date_delivrence, |
|||
annee_bacc, |
|||
serie, |
|||
boursier, |
|||
domaine, |
|||
contact, |
|||
parcours |
|||
} = credentials |
|||
|
|||
const insert = await insertEtudiant( |
|||
nom, |
|||
prenom, |
|||
photos, |
|||
date_de_naissances, |
|||
niveau, |
|||
annee_scolaire, |
|||
status, |
|||
num_inscription, |
|||
mention_id, |
|||
sexe, |
|||
nationaliter, |
|||
cin, |
|||
date_delivrence, |
|||
annee_bacc, |
|||
serie, |
|||
boursier, |
|||
domaine, |
|||
contact, |
|||
parcours |
|||
) |
|||
|
|||
return insert |
|||
}) |
|||
|
|||
// event for fetching single
|
|||
ipcMain.handle('getByNiveau', async (event, credentials) => { |
|||
const { niveau } = credentials |
|||
|
|||
const getSingle = await FilterDataByNiveau(niveau) |
|||
|
|||
return getSingle |
|||
}) |
|||
|
|||
// event for fetching single
|
|||
ipcMain.handle('single', async (event, credentials) => { |
|||
const { id } = credentials |
|||
|
|||
const getSingle = await getSingleEtudiant(id) |
|||
|
|||
return getSingle |
|||
}) |
|||
|
|||
// event for inserting niveau
|
|||
ipcMain.handle('insertNiveau', async (event, credentials) => { |
|||
const { nom } = credentials |
|||
|
|||
const insert = await insertNiveau(nom) |
|||
|
|||
return insert |
|||
}) |
|||
|
|||
// event for updating etudiants
|
|||
ipcMain.handle('updateETudiants', async (event, credentials) => { |
|||
const { |
|||
nom, |
|||
prenom, |
|||
photos, |
|||
date_de_naissances, |
|||
niveau, |
|||
annee_scolaire, |
|||
status, |
|||
mention_id, |
|||
num_inscription, |
|||
id, |
|||
sexe, |
|||
nationalite, |
|||
cin, |
|||
date_delivrence, |
|||
annee_bacc, |
|||
serie, |
|||
boursier, |
|||
domaine, |
|||
contact, |
|||
parcours |
|||
} = credentials |
|||
|
|||
const updating = await updateEtudiant( |
|||
nom, |
|||
prenom, |
|||
photos, |
|||
date_de_naissances, |
|||
niveau, |
|||
annee_scolaire, |
|||
status, |
|||
mention_id, |
|||
num_inscription, |
|||
id, |
|||
sexe, |
|||
nationalite, |
|||
cin, |
|||
date_delivrence, |
|||
annee_bacc, |
|||
serie, |
|||
boursier, |
|||
domaine, |
|||
contact, |
|||
parcours |
|||
) |
|||
|
|||
return updating |
|||
}) |
|||
|
|||
// event for updating etudiants pdp
|
|||
ipcMain.handle('updateETudiantsPDP', async (event, credentials) => { |
|||
const { pdp, id } = credentials |
|||
|
|||
const updating = await changePDP(pdp, id) |
|||
|
|||
return updating |
|||
}) |
|||
|
|||
// event for adding notes
|
|||
ipcMain.handle('insertNote', async (event, credentials) => { |
|||
const { etudiant_id, etudiant_niveau, mention_id, formData, annee_scolaire } = credentials |
|||
|
|||
const insert = await insertNote( |
|||
etudiant_id, |
|||
etudiant_niveau, |
|||
mention_id, |
|||
formData, |
|||
annee_scolaire |
|||
) |
|||
|
|||
return insert |
|||
}) |
|||
|
|||
// event for get single note
|
|||
ipcMain.handle('getSingleNote', async (event, credentials) => { |
|||
const { id, niveau, mention_id } = credentials |
|||
|
|||
const get = await getNote(id, niveau, mention_id) |
|||
|
|||
return get |
|||
}) |
|||
|
|||
// event for get single note repech
|
|||
ipcMain.handle('getNotesRepech', async (event, credentials) => { |
|||
const { id, niveau, mention_id } = credentials |
|||
|
|||
const get = await getNoteRepech(id, niveau, mention_id) |
|||
|
|||
return get |
|||
}) |
|||
|
|||
// event for updating note
|
|||
ipcMain.handle('updatetNote', async (event, credentials) => { |
|||
const { formData, niveau, id, mention_id, annee_scolaire } = credentials |
|||
|
|||
const update = await updateNote(formData, niveau, id, mention_id, annee_scolaire) |
|||
|
|||
return update |
|||
}) |
|||
|
|||
// event for updating note repech
|
|||
ipcMain.handle('updatetNoteRepech', async (event, credentials) => { |
|||
const { formData2, niveau, id } = credentials |
|||
|
|||
const update = await updateNoteRepech(formData2, niveau, id) |
|||
|
|||
return update |
|||
}) |
|||
|
|||
// event to get single matiere
|
|||
ipcMain.handle('getMatiereByID', async (event, credentials) => { |
|||
const { id } = credentials |
|||
|
|||
const matiere = await getSingleMatiere(id) |
|||
|
|||
return matiere |
|||
}) |
|||
|
|||
// event for updating matiere
|
|||
ipcMain.handle('updateMatiere', async (event, credentials) => { |
|||
const { nom, credit, uniter, ue, id } = credentials |
|||
|
|||
const update = await updateMatiere(nom, id, credit, uniter, ue) |
|||
|
|||
return update |
|||
}) |
|||
// event for importExcel
|
|||
ipcMain.handle('importexcel', async (event, credentials) => { |
|||
const files = credentials |
|||
console.log(files) |
|||
const insert = await importFileToDatabase(files) |
|||
|
|||
return insert |
|||
}) |
|||
|
|||
// event for udatign a single niveau
|
|||
ipcMain.handle('updateSingleNiveau', async (event, credentials) => { |
|||
const { nom, id } = credentials |
|||
|
|||
const update = updateNiveau(nom, id) |
|||
|
|||
return update |
|||
}) |
|||
|
|||
// event to get single niveau
|
|||
ipcMain.handle('singleNiveau', async (event, credentials) => { |
|||
const { id } = credentials |
|||
|
|||
const update = getSingleNiveau(id) |
|||
|
|||
return update |
|||
}) |
|||
|
|||
// event for creating matiere
|
|||
ipcMain.handle('createMatiere', async (event, credentials) => { |
|||
const { nom, credit, uniter, ue } = credentials |
|||
|
|||
const create = createMatiere(nom, credit, uniter, ue) |
|||
|
|||
return create |
|||
}) |
|||
|
|||
// event for import excel matiere
|
|||
ipcMain.handle('importExcelMatiere', async (event, credentials) => { |
|||
const files = credentials |
|||
console.log(files) |
|||
const insert = await importFileToDatabaseMatiere(files) |
|||
|
|||
return insert |
|||
}) |
|||
|
|||
// event for import excel niveau
|
|||
ipcMain.handle('importNiveau', async (event, credentials) => { |
|||
const files = credentials |
|||
console.log(files) |
|||
const insert = await importNiveau(files) |
|||
|
|||
return insert |
|||
}) |
|||
|
|||
// event for updating note systeme
|
|||
ipcMain.handle('updateNoteSysteme', async (event, credentials) => { |
|||
const { id, admis, redouble, renvoyer } = credentials |
|||
|
|||
const update = updateSysteme(id, admis, redouble, renvoyer) |
|||
return update |
|||
}) |
|||
|
|||
// event for updating note systeme
|
|||
ipcMain.handle('createAnneeScolaire', async (event, credentials) => { |
|||
const { code, debut, fin } = credentials |
|||
|
|||
const create = createAnneeScolaire(code, debut, fin) |
|||
return create |
|||
}) |
|||
|
|||
ipcMain.handle('getMoyene', async (event, credentials) => { |
|||
const { niveau, scolaire } = credentials |
|||
console.log('index.js', niveau, scolaire) |
|||
|
|||
const create = showMoyen(niveau, scolaire) |
|||
return create |
|||
}) |
|||
|
|||
ipcMain.handle('getMoyenneRepech', async (event, credentials) => { |
|||
const { niveau, scolaire } = credentials |
|||
console.log('index.js', niveau, scolaire) |
|||
|
|||
const create = showMoyenRepech(niveau, scolaire) |
|||
return create |
|||
}) |
|||
|
|||
ipcMain.handle('noteMatiere', async (event, credentials) => { |
|||
const { id, niveau, annee_scolaire } = credentials |
|||
|
|||
const get = getMatiereAndNote(id, niveau, annee_scolaire) |
|||
return get |
|||
}) |
|||
|
|||
ipcMain.handle('displayMatiereFromForm', async (event, credentials) => { |
|||
const { niveau, mention_id, parcours } = credentials |
|||
|
|||
const get = displayMatiereFromForm(niveau, mention_id, parcours) |
|||
return get |
|||
}) |
|||
|
|||
ipcMain.handle('createMention', async (event, credentials) => { |
|||
const { nom, uniter } = credentials |
|||
|
|||
const get = createMention(nom, uniter) |
|||
return get |
|||
}) |
|||
|
|||
ipcMain.handle('getSingleMention', async (event, credentials) => { |
|||
const { id } = credentials |
|||
|
|||
const get = getSingleMention(id) |
|||
return get |
|||
}) |
|||
|
|||
ipcMain.handle('updateMention', async (event, credentials) => { |
|||
const { nom, uniter, id } = credentials |
|||
|
|||
const get = updateMention(nom, uniter, id) |
|||
return get |
|||
}) |
|||
|
|||
ipcMain.handle('deleteMention', async (event, credentials) => { |
|||
const { id } = credentials |
|||
|
|||
const get = deleteMention(id) |
|||
return get |
|||
}) |
|||
|
|||
ipcMain.handle('deleteNiveaus', async (event, credentials) => { |
|||
const { id } = credentials |
|||
|
|||
const get = deleteNiveau(id) |
|||
return get |
|||
}) |
|||
|
|||
ipcMain.handle('deleteMatiere', async (event, credentials) => { |
|||
const { id } = credentials |
|||
|
|||
const get = deleteMatiere(id) |
|||
return get |
|||
}) |
|||
|
|||
ipcMain.handle('asign', async (event, credentials) => { |
|||
const { formData, id } = credentials |
|||
// console.log(formData, id);
|
|||
const get = asygnationToMention(formData, id) |
|||
|
|||
return get |
|||
}) |
|||
|
|||
ipcMain.handle('asignSemestre', async (event, credentials) => { |
|||
const { id } = credentials |
|||
|
|||
const get = getMentionMatiereChecked(id) |
|||
|
|||
return get |
|||
}) |
|||
|
|||
ipcMain.handle('getAsign', async (event, credentials) => { |
|||
const { id } = credentials |
|||
// console.log(formData, id);
|
|||
const get = getMentionMatiere(id) |
|||
|
|||
return get |
|||
}) |
|||
|
|||
ipcMain.handle('deleteAnneeScolaire', async (event, credentials) => { |
|||
const { id } = credentials |
|||
// console.log(formData, id);
|
|||
const get = deleteAnneeScolaire(id) |
|||
|
|||
return get |
|||
}) |
|||
|
|||
ipcMain.handle('getSemestreMatiere', async (event, credentials) => { |
|||
const { id } = credentials |
|||
// console.log(formData, id);
|
|||
const get = getSemestreMatiere(id) |
|||
|
|||
return get |
|||
}) |
|||
|
|||
ipcMain.handle('insertUpdateMentionSemestre', async (event, credentials) => { |
|||
const { id, selectedSemestres } = credentials |
|||
// console.log(formData, id);
|
|||
const get = insertUpdateMentionSemestre(id, selectedSemestres) |
|||
|
|||
return get |
|||
}) |
|||
|
|||
ipcMain.handle('getSingleAnneeScolaire', async (event, credentials) => { |
|||
const { id } = credentials |
|||
// console.log(formData, id);
|
|||
const get = getSingleAnneScolaire(id) |
|||
|
|||
return get |
|||
}) |
|||
|
|||
ipcMain.handle('updateAnneeScolaire', async (event, credentials) => { |
|||
const { code, debut, fin, id } = credentials |
|||
// console.log(formData, id);
|
|||
const get = updateAnneeScolaire(id, code, debut, fin) |
|||
|
|||
return get |
|||
}) |
|||
|
|||
ipcMain.handle('setCurrent', async (event, credentials) => { |
|||
const { id } = credentials |
|||
// console.log(formData, id);
|
|||
const get = setCurrent(id) |
|||
|
|||
return get |
|||
}) |
|||
|
|||
ipcMain.handle('noteRelerer', async (event, credentials) => { |
|||
const { id, anneescolaire, niveau } = credentials |
|||
// console.log(formData, id);
|
|||
const get = getNotesWithRepechToDisplay(id, anneescolaire, niveau) |
|||
|
|||
return get |
|||
}) |
|||
|
|||
ipcMain.handle('updateNessesary', async (event, credentials) => { |
|||
const { id, multiplicateur } = credentials |
|||
// console.log(formData, id);
|
|||
const get = updateNessesaryTable(id, multiplicateur) |
|||
|
|||
return get |
|||
}) |
|||
|
|||
ipcMain.handle('insertProf', async (event, credentials) => { |
|||
const { nom_enseignant, prenom_enseignant, contact, date, matiere_id } = credentials |
|||
// console.log(formData, id);
|
|||
const get = insertNewProf(matiere_id, nom_enseignant, prenom_enseignant, contact, date) |
|||
|
|||
return get |
|||
}) |
|||
|
|||
ipcMain.handle('insertParcours', async (event, credentials) => { |
|||
const { nom, uniter, mention_id } = credentials |
|||
// console.log(formData, id);
|
|||
const get = insertParcour(nom, uniter, mention_id) |
|||
|
|||
return get |
|||
}) |
|||
|
|||
ipcMain.handle('getSingleParcours', async (event, credentials) => { |
|||
const { id } = credentials |
|||
// console.log(formData, id);
|
|||
const get = getSingleParcours(id) |
|||
|
|||
return get |
|||
}) |
|||
|
|||
ipcMain.handle('deleteParcours', async (event, credentials) => { |
|||
const { id } = credentials |
|||
// console.log(formData, id);
|
|||
const get = deletes(id) |
|||
|
|||
return get |
|||
}) |
|||
|
|||
ipcMain.handle('updateParcours', async (event, credentials) => { |
|||
const { nom, uniter, mention_id, id } = credentials |
|||
// console.log(formData, id);
|
|||
const get = updateparcour(id, nom, uniter, mention_id) |
|||
|
|||
return get |
|||
}) |
|||
|
|||
ipcMain.handle('parcourMatiere', async (event, credentials) => { |
|||
const { matiere_id, parcour_id } = credentials |
|||
// console.log(formData, id);
|
|||
const get = parcourMatiere(matiere_id, parcour_id) |
|||
|
|||
return get |
|||
}) |
|||
|
|||
ipcMain.handle('getSingleProf', async (event, credentials) => { |
|||
const { id } = credentials |
|||
// console.log(formData, id);
|
|||
const get = getSIngleProf(id) |
|||
|
|||
return get |
|||
}) |
|||
|
|||
ipcMain.handle('updateProf', async (event, credentials) => { |
|||
const { nom_enseignant, prenom_enseignant, contact, date, matiere_id } = credentials |
|||
// console.log(formData, id);
|
|||
const get = updateProf(matiere_id, nom_enseignant, prenom_enseignant, contact, date) |
|||
|
|||
return get |
|||
}) |
|||
|
|||
ipcMain.handle('extractFiches', async (event, credentials) => { |
|||
const { matiere_id } = credentials |
|||
// console.log(formData, id);
|
|||
const get = extractFiche(matiere_id) |
|||
|
|||
return get |
|||
}) |
|||
|
|||
ipcMain.handle('getParcourMatiere', async (event, credentials) => { |
|||
const { matiere_id } = credentials |
|||
// console.log(formData, id);
|
|||
const get = getParcourMatiere(matiere_id) |
|||
|
|||
return get |
|||
}) |
|||
|
|||
ipcMain.handle('changeParcours', async (event, credentials) => { |
|||
const { parcours, user_id } = credentials |
|||
// console.log(formData, id);
|
|||
const get = updateParcours(parcours, user_id) |
|||
|
|||
return get |
|||
}) |
|||
|
|||
ipcMain.handle('createTranche', async (event, credentials) => { |
|||
const { etudiant_id, tranchename, montant } = credentials |
|||
// console.log(formData, id);
|
|||
const get = createTranche(etudiant_id, tranchename, montant) |
|||
|
|||
return get |
|||
}) |
|||
|
|||
ipcMain.handle('getTranche', async (event, credentials) => { |
|||
const { id } = credentials |
|||
// console.log(formData, id);
|
|||
const get = getTranche(id) |
|||
|
|||
return get |
|||
}) |
|||
|
|||
ipcMain.handle('updateTranche', async (event, credentials) => { |
|||
const { id, tranchename, montant } = credentials |
|||
// console.log(formData, id);
|
|||
const get = updateTranche(id, tranchename, montant) |
|||
|
|||
return get |
|||
}) |
|||
|
|||
ipcMain.handle('deleteTranche', async (event, credentials) => { |
|||
const { id } = credentials |
|||
console.log(id) |
|||
const get = deleteTranche(id) |
|||
|
|||
return get |
|||
}) |
|||
|
|||
ipcMain.handle('getSingleTranche', async (event, credentials) => { |
|||
const { id } = credentials |
|||
// console.log(formData, id);
|
|||
const get = getSingleTranche(id) |
|||
|
|||
return get |
|||
}) |
|||
|
|||
ipcMain.handle('createIPConfig', async (event, credentials) => { |
|||
const { ipname } = credentials |
|||
// console.log(formData, id);
|
|||
const get = createConfigIp(ipname) |
|||
|
|||
return get |
|||
}) |
|||
|
|||
ipcMain.handle('updateIPConfig', async (event, credentials) => { |
|||
const { id, ipname } = credentials |
|||
// console.log(formData, id);
|
|||
const get = updateIPConfig(id, ipname); |
|||
|
|||
return get |
|||
}) |
|||
@ -0,0 +1,135 @@ |
|||
import { app, shell, BrowserWindow, ipcMain } from 'electron' |
|||
import { join } from 'path' |
|||
import { electronApp, optimizer, is } from '@electron-toolkit/utils' |
|||
import icon from '../../resources/icon.png?asset' |
|||
const { loginUser, forgotPassword } = require('../../database/Models/Users') |
|||
|
|||
let splashWindow |
|||
let mainWindow |
|||
|
|||
// Create splash window
|
|||
function createSplashScreen() { |
|||
splashWindow = new BrowserWindow({ |
|||
width: 400, |
|||
height: 300, |
|||
frame: false, |
|||
alwaysOnTop: true, |
|||
transparent: true, |
|||
resizable: false, |
|||
webPreferences: { |
|||
nodeIntegration: true, |
|||
contextIsolation: false |
|||
} |
|||
}) |
|||
|
|||
splashWindow.loadFile(join(__dirname, '../renderer/splash.html')) |
|||
|
|||
splashWindow.on('closed', () => { |
|||
splashWindow = null |
|||
}) |
|||
} |
|||
|
|||
// Create main application window
|
|||
function createWindow() { |
|||
mainWindow = new BrowserWindow({ |
|||
width: 1000, |
|||
minWidth: 1000, |
|||
height: 670, |
|||
minHeight: 670, |
|||
show: false, |
|||
autoHideMenuBar: true, |
|||
fullscreen: true, |
|||
...(process.platform === 'linux' ? { icon } : {}), |
|||
webPreferences: { |
|||
preload: join(__dirname, '../preload/index.js'), |
|||
nodeIntegration: true, |
|||
contextIsolation: true, |
|||
sandbox: false |
|||
} |
|||
}) |
|||
|
|||
mainWindow.on('ready-to-show', () => { |
|||
if (splashWindow) { |
|||
splashWindow.close() // Close splash screen when main window is ready
|
|||
} |
|||
mainWindow.show() |
|||
}) |
|||
|
|||
mainWindow.webContents.setWindowOpenHandler((details) => { |
|||
shell.openExternal(details.url) |
|||
return { action: 'deny' } |
|||
}) |
|||
|
|||
// Load the initial content
|
|||
if (is.dev && process.env['ELECTRON_RENDERER_URL']) { |
|||
mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL']) |
|||
} else { |
|||
mainWindow.loadFile(join(__dirname, '../renderer/index.html')) |
|||
} |
|||
} |
|||
|
|||
// Function to load new content and show the splash screen
|
|||
function loadNewContent(contentPath) { |
|||
createSplashScreen() // Show splash screen before loading new content
|
|||
|
|||
mainWindow.loadFile(contentPath).then(() => { |
|||
if (splashWindow) { |
|||
splashWindow.close() // Close splash screen after loading content
|
|||
} |
|||
mainWindow.show() // Show main window
|
|||
}) |
|||
} |
|||
|
|||
// This method will be called when Electron has finished initialization
|
|||
app.whenReady().then(() => { |
|||
// Set app user model id for Windows
|
|||
electronApp.setAppUserModelId('com.electron') |
|||
|
|||
// Default open or close DevTools by F12 in development
|
|||
app.on('browser-window-created', (_, window) => { |
|||
optimizer.watchWindowShortcuts(window) |
|||
}) |
|||
|
|||
// Create initial main window
|
|||
createWindow() |
|||
|
|||
// IPC for loading new content
|
|||
ipcMain.on('load-content', (event, contentPath) => { |
|||
loadNewContent(contentPath) |
|||
}) |
|||
|
|||
app.on('activate', function () { |
|||
if (BrowserWindow.getAllWindows().length === 0) createWindow() |
|||
}) |
|||
}) |
|||
|
|||
// Quit when all windows are closed, except on macOS
|
|||
app.on('window-all-closed', () => { |
|||
if (process.platform !== 'darwin') { |
|||
app.quit() |
|||
} |
|||
}) |
|||
|
|||
// Event for handling login
|
|||
ipcMain.handle('login', async (event, credentials) => { |
|||
const { username, password } = credentials |
|||
|
|||
const users = await loginUser(username, password) |
|||
|
|||
if (users) { |
|||
return { success: true, user: users } |
|||
} else { |
|||
return { success: false } |
|||
} |
|||
}) |
|||
|
|||
// Event for handling forgot password
|
|||
ipcMain.handle('forgotPassword', async (event, credentials) => { |
|||
const { email, password, passwordConfirmation } = credentials |
|||
|
|||
const updated = await forgotPassword(email, password, passwordConfirmation) |
|||
|
|||
if (updated) { |
|||
return updated |
|||
} |
|||
}) |
|||
@ -0,0 +1,210 @@ |
|||
import { contextBridge, ipcRenderer } from 'electron' |
|||
import { electronAPI } from '@electron-toolkit/preload' |
|||
const { getNessesarytable } = require('../../database/function/System') |
|||
const { getNiveau } = require('../../database/Models/Niveau') |
|||
const { getAllUsers } = require('../../database/Models/Users') |
|||
const { getAllEtudiants, getDataToDashboard } = require('../../database/Models/Etudiants') |
|||
const { verifyEtudiantIfHeHasNotes, blockShowMoyene } = require('../../database/Models/Notes') |
|||
|
|||
const { synchronizeData } = require('../../database/api/SyncronisationDataUsers') |
|||
const { synchronizeDataEtudiants } = require('../../database/api/SyncronisationDataEtudiants') |
|||
const { synchronizeDataNotes } = require('../../database/api/CheckUpdateNote') |
|||
const { getMatiere, getSemestre, getEnseignants } = require('../../database/Models/Matieres') |
|||
const { getSysteme } = require('../../database/Models/NoteSysrem') |
|||
const { getStatus } = require('../../database/Models/Status') |
|||
const { getAnneeScolaire, getInterval } = require('../../database/Models/AnneeScolaire') |
|||
const { getMentions } = require('../../database/Models/Mentions') |
|||
const { getAll } = require('../../database/api/Get') |
|||
const { getParcours } = require('../../database/Models/Parcours') |
|||
const { getIPConfig } = require('../../database/Models/IpConfig') |
|||
|
|||
// Custom APIs for renderer
|
|||
const api = {} |
|||
|
|||
// Use `contextBridge` APIs to expose Electron APIs to
|
|||
// renderer only if context isolation is enabled, otherwise
|
|||
// just add to the DOM global.
|
|||
if (process.contextIsolated) { |
|||
try { |
|||
contextBridge.exposeInMainWorld('electron', electronAPI) |
|||
contextBridge.exposeInMainWorld('api', api) |
|||
|
|||
/** |
|||
* contextBridge for Tray |
|||
*/ |
|||
contextBridge.exposeInMainWorld('Tray', { |
|||
onNavigate: (callback) => { |
|||
ipcRenderer.on('navigateToRoute', (event, route) => { |
|||
callback(route) // Pass the route to the renderer callback
|
|||
}) |
|||
} |
|||
}) |
|||
|
|||
/** |
|||
* contextBridge for users |
|||
*/ |
|||
contextBridge.exposeInMainWorld('allUser', { |
|||
users: () => getAllUsers(), |
|||
login: (credentials) => ipcRenderer.invoke('login', credentials), |
|||
insertUsers: (credentials) => ipcRenderer.invoke('insertUser', credentials), |
|||
forgotPassword: (credentials) => ipcRenderer.invoke('forgotPassword', credentials), |
|||
quit: () => ipcRenderer.invoke('quit'), |
|||
minimize: () => ipcRenderer.invoke('minimize'), |
|||
updateUsers: (credentials) => ipcRenderer.invoke('updateUsers', credentials) |
|||
}) |
|||
|
|||
contextBridge.exposeInMainWorld('syncro', { |
|||
getall: () => getAll() |
|||
}) |
|||
|
|||
// syncronisation des donner
|
|||
window.addEventListener('online', async () => { |
|||
if (navigator.onLine) { |
|||
// synchronizeData()
|
|||
// synchronizeDataEtudiants()
|
|||
// synchronizeDataNotes()
|
|||
await getAll() |
|||
} |
|||
}) |
|||
// send data
|
|||
getAll() |
|||
|
|||
/** |
|||
* contextBridge for etudiants |
|||
*/ |
|||
contextBridge.exposeInMainWorld('etudiants', { |
|||
insertEtudiant: (credentials) => ipcRenderer.invoke('insertEtudiant', credentials), |
|||
getEtudiants: () => getAllEtudiants(), |
|||
FilterDataByNiveau: (credential) => ipcRenderer.invoke('getByNiveau', credential), |
|||
getSingle: (credential) => ipcRenderer.invoke('single', credential), |
|||
updateEtudiants: (credentials) => ipcRenderer.invoke('updateETudiants', credentials), |
|||
getDataToDashboards: () => getDataToDashboard(), |
|||
updateEtudiantsPDP: (credentials) => ipcRenderer.invoke('updateETudiantsPDP', credentials), |
|||
importExcel: (credentials) => ipcRenderer.invoke('importexcel', credentials), |
|||
changeParcours: (credentials) => ipcRenderer.invoke('changeParcours', credentials), |
|||
createTranche: (credentials) => ipcRenderer.invoke('createTranche', credentials), |
|||
getTranche: (credentials) => ipcRenderer.invoke('getTranche', credentials), |
|||
updateTranche: (credentials) => ipcRenderer.invoke('updateTranche', credentials), |
|||
deleteTranche: (credentials) => ipcRenderer.invoke('deleteTranche', credentials), |
|||
getSingleTranche: (credentials) => ipcRenderer.invoke('getSingleTranche', credentials) |
|||
}) |
|||
|
|||
/** |
|||
* cobtextBridge for niveaus |
|||
*/ |
|||
contextBridge.exposeInMainWorld('niveaus', { |
|||
getNiveau: () => getNiveau(), |
|||
getSingleNiveau: (credential) => ipcRenderer.invoke('singleNiveau', credential), |
|||
insertNiveau: (credentials) => ipcRenderer.invoke('insertNiveau', credentials), |
|||
updateSingleNiveau: (credentials) => ipcRenderer.invoke('updateSingleNiveau', credentials), |
|||
importNiveau: (credentials) => ipcRenderer.invoke('importNiveau', credentials), |
|||
deleteNiveaus: (credentials) => ipcRenderer.invoke('deleteNiveaus', credentials) |
|||
}) |
|||
|
|||
/** |
|||
* contextBridge for notes |
|||
*/ |
|||
contextBridge.exposeInMainWorld('notes', { |
|||
getNotes: (credentials) => ipcRenderer.invoke('getSingleNote', credentials), |
|||
insertNote: (credentials) => ipcRenderer.invoke('insertNote', credentials), |
|||
updateNote: (credentials) => ipcRenderer.invoke('updatetNote', credentials), |
|||
getMoyenne: (credentials) => ipcRenderer.invoke('getMoyene', credentials), |
|||
noteMatiere: (credentials) => ipcRenderer.invoke('noteMatiere', credentials), |
|||
noteRelerer: (credentials) => ipcRenderer.invoke('noteRelerer', credentials), |
|||
getMoyenneVerify: () => verifyEtudiantIfHeHasNotes(), |
|||
getblockNote: () => blockShowMoyene() |
|||
}) |
|||
|
|||
/** |
|||
* contextbridge for note repechage |
|||
*/ |
|||
contextBridge.exposeInMainWorld('noteRepech', { |
|||
getNotesRepech: (credentials) => ipcRenderer.invoke('getNotesRepech', credentials), |
|||
updateNoteRepech: (credentials) => ipcRenderer.invoke('updatetNoteRepech', credentials), |
|||
getMoyenneRepech: (credentials) => ipcRenderer.invoke('getMoyenneRepech', credentials) |
|||
}) |
|||
|
|||
/** |
|||
* contextBridge for matieres |
|||
*/ |
|||
contextBridge.exposeInMainWorld('matieres', { |
|||
getMatiere: () => getMatiere(), |
|||
createMatiere: (credentials) => ipcRenderer.invoke('createMatiere', credentials), |
|||
getMatiereByID: (credentials) => ipcRenderer.invoke('getMatiereByID', credentials), |
|||
updateMatiere: (credentials) => ipcRenderer.invoke('updateMatiere', credentials), |
|||
importExcel: (credentials) => ipcRenderer.invoke('importExcelMatiere', credentials), |
|||
displayMatiereFromForm: (credentials) => |
|||
ipcRenderer.invoke('displayMatiereFromForm', credentials), |
|||
deleteMatiere: (credentials) => ipcRenderer.invoke('deleteMatiere', credentials), |
|||
asign: (credentials) => ipcRenderer.invoke('asign', credentials), |
|||
getAsign: (credentials) => ipcRenderer.invoke('getAsign', credentials), |
|||
asignSemestre: (credentials) => ipcRenderer.invoke('asignSemestre', credentials), |
|||
getSemestreMatiere: (credentials) => ipcRenderer.invoke('getSemestreMatiere', credentials), |
|||
getSemestre: () => getSemestre(), |
|||
getNessesary: () => getNessesarytable(), |
|||
getENseignant: () => getEnseignants(), |
|||
insertUpdateMentionSemestre: (credentials) => |
|||
ipcRenderer.invoke('insertUpdateMentionSemestre', credentials), |
|||
updateNessesary: (credentials) => ipcRenderer.invoke('updateNessesary', credentials), |
|||
insertProf: (credentials) => ipcRenderer.invoke('insertProf', credentials), |
|||
getSingleProf: (credentials) => ipcRenderer.invoke('getSingleProf', credentials), |
|||
updateProf: (credentials) => ipcRenderer.invoke('updateProf', credentials) |
|||
}) |
|||
|
|||
/** |
|||
* contextBridge for note systeme |
|||
*/ |
|||
contextBridge.exposeInMainWorld('notesysteme', { |
|||
getSyteme: () => getSysteme(), |
|||
updateNoteSysteme: (credentials) => ipcRenderer.invoke('updateNoteSysteme', credentials), |
|||
insertParcours: (credentials) => ipcRenderer.invoke('insertParcours', credentials), |
|||
getSingleParcours: (credentials) => ipcRenderer.invoke('getSingleParcours', credentials), |
|||
deleteParcours: (credentials) => ipcRenderer.invoke('deleteParcours', credentials), |
|||
updateParcours: (credentials) => ipcRenderer.invoke('updateParcours', credentials), |
|||
parcourMatiere: (credentials) => ipcRenderer.invoke('parcourMatiere', credentials), |
|||
getParcours: () => getParcours(), |
|||
extractFiches: (credentials) => ipcRenderer.invoke('extractFiches', credentials), |
|||
getParcourMatiere: (credentials) => ipcRenderer.invoke('getParcourMatiere', credentials), |
|||
createIPConfig: (credentials) => ipcRenderer.invoke('createIPConfig', credentials), |
|||
getIPConfig: () => getIPConfig(), |
|||
updateIPConfig: (credentials) => ipcRenderer.invoke('updateIPConfig', credentials) |
|||
}) |
|||
|
|||
/** |
|||
* contextbridge for status |
|||
*/ |
|||
contextBridge.exposeInMainWorld('statuss', { |
|||
getStatus: () => getStatus() |
|||
}) |
|||
|
|||
/** |
|||
* contextbridge for annee scolaire |
|||
*/ |
|||
contextBridge.exposeInMainWorld('anneescolaire', { |
|||
getAnneeScolaire: () => getAnneeScolaire(), |
|||
getInterval: () => getInterval(), |
|||
createAnneeScolaire: (credentials) => ipcRenderer.invoke('createAnneeScolaire', credentials), |
|||
deleteAnneeScolaire: (credentials) => ipcRenderer.invoke('deleteAnneeScolaire', credentials), |
|||
getSingleAnneeScolaire: (credentials) => |
|||
ipcRenderer.invoke('getSingleAnneeScolaire', credentials), |
|||
updateAnneeScolaire: (credentials) => ipcRenderer.invoke('updateAnneeScolaire', credentials), |
|||
setCurrent: (credentials) => ipcRenderer.invoke('setCurrent', credentials) |
|||
}) |
|||
|
|||
/** |
|||
* contextbridge for mention |
|||
*/ |
|||
contextBridge.exposeInMainWorld('mention', { |
|||
createMention: (credentials) => ipcRenderer.invoke('createMention', credentials), |
|||
getMention: () => getMentions(), |
|||
getSingleMention: (credentials) => ipcRenderer.invoke('getSingleMention', credentials), |
|||
updateMention: (credentials) => ipcRenderer.invoke('updateMention', credentials), |
|||
deleteMention: (credentials) => ipcRenderer.invoke('deleteMention', credentials) |
|||
}) |
|||
} catch (error) { |
|||
console.error(error) |
|||
} |
|||
} else { |
|||
window.electron = electronAPI |
|||
window.api = api |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
<!doctype html> |
|||
<html> |
|||
<head> |
|||
<meta charset="UTF-8" /> |
|||
<title>Université de Toamasina</title> |
|||
<link rel="shortcut icon" href="src/assets/logo.ico" type="image/x-icon" /> |
|||
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP --> |
|||
<meta |
|||
http-equiv="Content-Security-Policy" |
|||
content="default-src 'self'; connect-src 'self' https://api.polytechnique.c4m.mg; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data:" |
|||
/> |
|||
</head> |
|||
|
|||
<body> |
|||
<div id="root"></div> |
|||
<script type="module" src="/src/main.jsx"></script> |
|||
</body> |
|||
</html> |
|||
@ -0,0 +1,63 @@ |
|||
import React, { useEffect, useState } from 'react' |
|||
import { RouterProvider } from 'react-router-dom' |
|||
import Router from './Routes/Routes' |
|||
import { AuthContextProvider, useAuthContext } from './contexts/AuthContext' |
|||
import { ClipLoader } from 'react-spinners' // Import the loader |
|||
import preloader from './assets/preloader.jpg' |
|||
import { DataProvider } from './contexts/MoyenneDeClasseContext' |
|||
|
|||
const App = () => { |
|||
const [loading, setLoading] = useState(true) |
|||
const { setToken } = useAuthContext() |
|||
|
|||
// Simulate loading (e.g., fetching some initial data or assets) |
|||
useEffect(() => { |
|||
const timer = setTimeout(() => { |
|||
setLoading(false) // Set loading to false after the simulated loading time |
|||
}, 3000) // 3 seconds delay to simulate loading |
|||
|
|||
return () => clearTimeout(timer) // Cleanup the timer |
|||
}, []) |
|||
|
|||
// Show Preloader while loading, else show your content |
|||
if (loading) { |
|||
return ( |
|||
<div |
|||
className="preloader-container" |
|||
style={{ |
|||
display: 'flex', |
|||
justifyContent: 'center', |
|||
alignItems: 'center', |
|||
height: '100vh', |
|||
backgroundImage: `url("${preloader}")`, |
|||
backgroundSize: 'cover', |
|||
backgroundPosition: 'center', |
|||
minHeight: '100vh' |
|||
}} |
|||
> |
|||
<ClipLoader color="blue" loading={loading} size={50} /> |
|||
</div> |
|||
) |
|||
} |
|||
|
|||
/** |
|||
* condition usign with the Tray icon on the bottom |
|||
*/ |
|||
if (window.Tray && typeof window.Tray.onNavigate === 'function') { |
|||
window.Tray.onNavigate((route) => { |
|||
if (route) { |
|||
window.location.hash = route // Navigate by updating the hash |
|||
} |
|||
}) |
|||
} |
|||
|
|||
return ( |
|||
<AuthContextProvider> |
|||
<DataProvider> |
|||
<RouterProvider router={Router} /> |
|||
</DataProvider> |
|||
</AuthContextProvider> |
|||
) |
|||
} |
|||
|
|||
export default App |
|||
@ -0,0 +1,207 @@ |
|||
import { createHashRouter } from 'react-router-dom' |
|||
import DefaultLayout from '../layouts/DefaultLayout' |
|||
import Login from '../components/Login' |
|||
import LoginLayout from '../layouts/LoginLayout' |
|||
import NotFound from '../components/NotFound' |
|||
import ForgotPassword from '../components/ForgotPassword' |
|||
import Home from '../components/Home' |
|||
import Student from '../components/Student' |
|||
import Notes from '../components/Notes' |
|||
import AddStudent from '../components/AddStudent' |
|||
import SingleEtudiant from '../components/SingleEtudiant' |
|||
import AddNotes from '../components/AddNotes' |
|||
import Apropos from '../components/Apropos' |
|||
import Niveau from '../components/Niveau' |
|||
import AddNiveau from '../components/AddNiveau' |
|||
import Admin from '../components/Addadmin' |
|||
import Setting from '../components/Param' |
|||
import SingleNotes from '../components/SingleNotes' |
|||
import ExportEtudiants from '../components/ExportEtudiants' |
|||
import SingleNiveau from '../components/singleNiveau' |
|||
import Matieres from '../components/Matieres' |
|||
import AddMatiere from '../components/AddMatiere' |
|||
import ImportMatiere from '../components/ImportMatiere' |
|||
import SingleMatiere from '../components/SingleMatiere' |
|||
import ImportNiveau from '../components/ImportNiveau' |
|||
import SystemeNote from '../components/SystemeNote' |
|||
import AnneeScolaire from '../components/AnneeScolaire' |
|||
import AddAnneeScolaire from '../components/AddAnneeScolaire' |
|||
import Noteclasse from '../components/Noteclasse' |
|||
import TesteDatagrid from '../components/TesteDatagrid' |
|||
import Manuel from '../components/Manuel' |
|||
import Mentions from '../components/Mentions' |
|||
import AddMention from '../components/AddMention' |
|||
import SinleMention from '../components/SinleMention' |
|||
import AssignMatiereToMention from '../components/AssignMatiereToMention' |
|||
import AssingMatiereToSemestre from '../components/AssingMatiereToSemestre' |
|||
import SingleAnneeScolaire from '../components/SingleAnneeScolaire' |
|||
import Parcours from '../components/Parcours' |
|||
import ModalExportFichr from '../components/ModalExportFichr' |
|||
import Resultat from '../components/Resultat' |
|||
import TrancheEcolage from '../components/TrancheEcolage' |
|||
|
|||
// Use createHashRouter instead of createBrowserRouter because the desktop app is in local machine |
|||
const Router = createHashRouter([ |
|||
{ |
|||
path: '/', |
|||
element: <DefaultLayout />, |
|||
children: [ |
|||
{ |
|||
path: '/', // This will now be accessed as #/ |
|||
element: <Home /> |
|||
}, |
|||
{ |
|||
path: '/student', |
|||
element: <Student /> |
|||
}, |
|||
{ |
|||
path: '/notes', |
|||
element: <Notes /> |
|||
}, |
|||
{ |
|||
path: '/addstudent', |
|||
element: <AddStudent /> |
|||
}, |
|||
{ |
|||
path: '/single/:id', |
|||
element: <SingleEtudiant /> |
|||
}, |
|||
{ |
|||
path: '/addnotes/:id/:niveau/:mention_id/:parcours', |
|||
element: <AddNotes /> |
|||
}, |
|||
{ |
|||
path: '/anneescolaire/:id', |
|||
element: <SingleAnneeScolaire /> |
|||
}, |
|||
{ |
|||
path: '/asignmatiere/:id', |
|||
element: <AssignMatiereToMention /> |
|||
}, |
|||
{ |
|||
path: '/asignmatieresemestre/:id', |
|||
element: <AssingMatiereToSemestre /> |
|||
}, |
|||
{ |
|||
path: '/manual', |
|||
element: <Manuel /> |
|||
}, |
|||
{ |
|||
path: '/mention', |
|||
element: <Mentions /> |
|||
}, |
|||
{ |
|||
path: '/addmention', |
|||
element: <AddMention /> |
|||
}, |
|||
{ |
|||
path: '/singlemention/:id', |
|||
element: <SinleMention /> |
|||
}, |
|||
{ |
|||
path: '/apropos', |
|||
element: <Apropos /> |
|||
}, |
|||
{ |
|||
path: '/niveau', |
|||
element: <Niveau /> |
|||
}, |
|||
{ |
|||
path: '/addniveau', |
|||
element: <AddNiveau /> |
|||
}, |
|||
{ |
|||
path: '/para', |
|||
element: <Setting /> |
|||
}, |
|||
{ |
|||
path: '/admin', |
|||
element: <Admin /> |
|||
}, |
|||
{ |
|||
path: '/single/notes/:id/:niveau/:scolaire', |
|||
element: <SingleNotes /> |
|||
}, |
|||
{ |
|||
path: '/exportetudiant', |
|||
element: <ExportEtudiants /> |
|||
}, |
|||
{ |
|||
path: '/single/niveau/:id', |
|||
element: <SingleNiveau /> |
|||
}, |
|||
{ |
|||
path: '/matiere', |
|||
element: <Matieres /> |
|||
}, |
|||
{ |
|||
path: '/addmatiere', |
|||
element: <AddMatiere /> |
|||
}, |
|||
{ |
|||
path: '/addmatiere/import', |
|||
element: <ImportMatiere /> |
|||
}, |
|||
{ |
|||
path: '/singlematiere/:id', |
|||
element: <SingleMatiere /> |
|||
}, |
|||
{ |
|||
path: '/importniveau', |
|||
element: <ImportNiveau /> |
|||
}, |
|||
{ |
|||
path: '/systemenote', |
|||
element: <SystemeNote /> |
|||
}, |
|||
{ |
|||
path: '/anneescolaire', |
|||
element: <AnneeScolaire /> |
|||
}, |
|||
{ |
|||
path: '/addanneescolaire', |
|||
element: <AddAnneeScolaire /> |
|||
}, |
|||
{ |
|||
path: '/noteclass/:niveau/:scolaire', |
|||
element: <Noteclasse /> |
|||
}, |
|||
{ |
|||
path: '/parcours', |
|||
element: <Parcours /> |
|||
}, |
|||
{ |
|||
path: '/fiche/:matiere_id/:nom', |
|||
element: <ModalExportFichr /> |
|||
}, |
|||
{ |
|||
path: '/resultat/:niveau/:scolaire', |
|||
element: <Resultat /> |
|||
}, |
|||
{ |
|||
path: '/tranche/:id', |
|||
element: <TrancheEcolage /> |
|||
} |
|||
] |
|||
}, |
|||
{ |
|||
path: '/', |
|||
element: <LoginLayout />, |
|||
children: [ |
|||
{ |
|||
path: '/login', |
|||
element: <Login /> |
|||
}, |
|||
{ |
|||
path: '/forgotpassword', |
|||
element: <ForgotPassword /> |
|||
} |
|||
] |
|||
}, |
|||
{ |
|||
path: '/*', |
|||
element: <NotFound /> |
|||
} |
|||
]) |
|||
|
|||
export default Router |
|||
@ -0,0 +1,12 @@ |
|||
.blockTitle h1 { |
|||
font-size: 10px; |
|||
font-weight: bold; |
|||
color: white; |
|||
display: flex; |
|||
align-items: center; |
|||
gap: 10px; |
|||
} |
|||
.boxEtudiantsCard { |
|||
width: 10%; |
|||
padding: 1%; |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
.blockTitle h1 { |
|||
font-size: 20px; |
|||
font-weight: bold; |
|||
color: white; |
|||
display: flex; |
|||
align-items: center; |
|||
gap: 10px; |
|||
} |
|||
.boxEtudiantsCard { |
|||
width: 100%; |
|||
padding: 1%; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
.h1style { |
|||
text-transform: uppercase; |
|||
font-weight: 900; |
|||
/* 6636af4a 6636af ffae01 */ |
|||
border-left: 10px solid #ffff; |
|||
padding-left: 10px; |
|||
margin-bottom: 30px; |
|||
background: linear-gradient(to right, #ffaf01b4, transparent); |
|||
color: white; |
|||
width: 100%; |
|||
padding-left: 45px; |
|||
font-size: 25px; |
|||
} |
|||
.mainHome { |
|||
padding: 1% 0 0 0; |
|||
width: 100%; |
|||
} |
|||
|
After Width: | Height: | Size: 8.9 KiB |
@ -0,0 +1,86 @@ |
|||
body { |
|||
margin: 0; |
|||
padding: 0; |
|||
} |
|||
.container { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
height: 100vh; |
|||
gap: 20px; |
|||
} |
|||
.cart { |
|||
width: 33%; |
|||
/* height: 35%; */ |
|||
border: solid 1px rgba(0, 0, 0, 0.315); |
|||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.8); /* Adds a soft shadow */ |
|||
/* border-radius: 10px; */ |
|||
padding: 1px; |
|||
background-color: #ffded4; |
|||
position: relative; |
|||
} |
|||
.cart-footer { |
|||
position: absolute; |
|||
height: 40px; |
|||
width: 100%; |
|||
bottom: 0; |
|||
left: 0; |
|||
border-bottom-left-radius: 10px; |
|||
border-bottom-right-radius: 10px; |
|||
background-color: #ff5a27; |
|||
} |
|||
.title { |
|||
margin: 0; |
|||
padding: 0; |
|||
text-align: center; |
|||
text-transform: uppercase; |
|||
z-index: 1; |
|||
} |
|||
.title h1, |
|||
p { |
|||
margin: 0; |
|||
font-size: 15px; |
|||
} |
|||
.content { |
|||
z-index: 1; |
|||
height: 70%; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
} |
|||
.cart_photos { |
|||
width: 30%; |
|||
text-align: center; |
|||
} |
|||
.cart_photos img { |
|||
border-radius: 50px; |
|||
border: solid 2px #ff5a27; |
|||
width: 95px; |
|||
height: 100px; |
|||
object-fit: cover; |
|||
} |
|||
.cart_info { |
|||
width: 60%; |
|||
padding-left: 1%; |
|||
} |
|||
.cart_info p { |
|||
font-size: 16px; |
|||
} |
|||
.qrContent { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-around; |
|||
padding: 2%; |
|||
} |
|||
.gauche h1, |
|||
.droite h1 { |
|||
font-size: 17px; |
|||
text-align: center; |
|||
} |
|||
.gauche img, |
|||
.droite img { |
|||
width: 150px; |
|||
} |
|||
.droite .qrcodeDroite { |
|||
width: 150px; |
|||
} |
|||
@ -0,0 +1,4 @@ |
|||
.display { |
|||
background-color: rgba(255, 255, 255, 0.9); |
|||
/* margin-bottom: 2%; */ |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
html, |
|||
body { |
|||
height: 100%; |
|||
margin: 0; |
|||
padding: 0; |
|||
} |
|||
|
|||
/* DefaultLayout.css */ |
|||
.default_layout { |
|||
/* height: 100%; Use full viewport height */ |
|||
min-height: 100vh; |
|||
overflow-y: auto; |
|||
background: url('../assets/background2.jpg') no-repeat center/cover; |
|||
/* background-color: #aad4e571; */ |
|||
} |
|||
.outlet { |
|||
padding-left: 55px; |
|||
margin-top: 0; |
|||
height: 100%; |
|||
} |
|||
@ -0,0 +1,78 @@ |
|||
.header { |
|||
width: 100%; |
|||
display: flex; |
|||
align-items: start; |
|||
justify-content: space-between; |
|||
} |
|||
.headerCenter { |
|||
text-align: center; |
|||
color: black; |
|||
line-height: 15px; |
|||
width: 60%; |
|||
} |
|||
.headerCenter h5 { |
|||
text-transform: uppercase; |
|||
line-height: 12px; |
|||
font-size: 14px; |
|||
} |
|||
.headerCenter p { |
|||
font-style: italic; |
|||
font-weight: 400; |
|||
font-size: 14px; |
|||
} |
|||
.transition { |
|||
border: solid 1px gray; |
|||
width: 100%; |
|||
padding: 1% 2%; |
|||
font-weight: bold; |
|||
} |
|||
.transition h6 { |
|||
font-size: 12px; |
|||
} |
|||
|
|||
/* content */ |
|||
.content { |
|||
text-align: center; |
|||
} |
|||
.contentHeader { |
|||
color: black; |
|||
flex-direction: column; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
font-size: 13px; |
|||
} |
|||
.contentHeader h1 { |
|||
font-size: 28px; |
|||
} |
|||
.contentHeaderList { |
|||
font-weight: bold; |
|||
font-size: 13px; |
|||
} |
|||
.contentHeaderList p { |
|||
font-size: 13px; |
|||
display: flex; |
|||
gap: 30px; |
|||
} |
|||
.ContentTable { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
} |
|||
.ContentTable table { |
|||
border-color: black !important; |
|||
font-size: 13px; |
|||
margin: 0; |
|||
} |
|||
.contentFooter { |
|||
display: flex; |
|||
align-items: end; |
|||
flex-direction: column; |
|||
margin-top: 5px; |
|||
} |
|||
.signature { |
|||
width: 50%; |
|||
display: flex; |
|||
flex-direction: column; |
|||
gap: 30px; |
|||
} |
|||
@ -0,0 +1,78 @@ |
|||
.boxEtudiantsCard { |
|||
width: 100%; |
|||
padding: 1%; |
|||
/* margin-top: 12%; */ |
|||
} |
|||
.cards { |
|||
/* width: 30%; */ |
|||
justify-content: space-between; |
|||
align-items: center; |
|||
padding: 0 1%; |
|||
} |
|||
.nomEtudiants { |
|||
font-weight: bold; |
|||
} |
|||
.header { |
|||
color: white; |
|||
/* backdrop-filter: blur(5px); */ |
|||
/* position: fixed; */ |
|||
width: 100%; |
|||
z-index: 9; |
|||
} |
|||
.container { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
padding: 1% 2%; |
|||
background: linear-gradient(to left, #ffaf01b4, transparent); |
|||
} |
|||
.blockTitle { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
padding: 0 3%; |
|||
} |
|||
.blockTitle h1 { |
|||
font-size: 20px; |
|||
font-weight: bold; |
|||
/* text-transform: uppercase; */ |
|||
color: white; |
|||
} |
|||
.blockTitle button { |
|||
font-size: 12px; |
|||
display: inline-flex; |
|||
gap: 10px; |
|||
} |
|||
.boxImg { |
|||
padding: 2%; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
} |
|||
.imagePDP { |
|||
object-fit: cover; |
|||
border: solid 2px rgb(156, 39, 176); |
|||
} |
|||
.mainHome { |
|||
border: solid 1px red; |
|||
} |
|||
.select:hover { |
|||
border-color: rgb(156, 39, 176) !important; |
|||
} |
|||
.details { |
|||
background-color: rgba(128, 128, 128, 0.4); |
|||
border-radius: 8px; |
|||
padding: 3% 1% 3% 4%; |
|||
text-align: left; |
|||
} |
|||
.details span { |
|||
display: block; |
|||
line-height: 25px; |
|||
} |
|||
.cardOverflow { |
|||
height: 450px; |
|||
transition: 1s ease; |
|||
} |
|||
.cardOverflow:hover { |
|||
transform: scale(1.03); |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
/* .container{ |
|||
background: url(bg2.jpg) no-repeat fixed center/cover; |
|||
background-color: #08000e; |
|||
} */ |
|||
.cards { |
|||
background-color: #06000aa4 !important; |
|||
color: white !important; |
|||
box-shadow: 0px 4px 10px rgba(255, 255, 255, 0.2) !important; /* Light white shadow */ |
|||
border: solid 1px rgba(245, 245, 245, 0.692); |
|||
} |
|||
.formulaireLogin { |
|||
color: white !important; |
|||
} |
|||
.formulaireLogin label { |
|||
color: white; |
|||
font-size: 17px; |
|||
} |
|||
.formulaireLogin input { |
|||
color: white; |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
.navnar { |
|||
color: rgba(0, 0, 0, 0.7); |
|||
background-color: #2d2d2d; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
padding: 2px 15px; |
|||
position: fixed; |
|||
width: 100%; |
|||
top: 0; |
|||
border-bottom: solid 1px white; |
|||
color: white; |
|||
z-index: 99999; |
|||
} |
|||
.gauche { |
|||
width: 30%; |
|||
display: flex; |
|||
align-items: center; |
|||
} |
|||
.droite { |
|||
width: 4%; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
} |
|||
@ -0,0 +1,51 @@ |
|||
.navbar { |
|||
background-color: #2d2d2d; |
|||
border-top: solid 1px white; |
|||
color: white; |
|||
width: 50px; |
|||
/* top: 28px; */ |
|||
position: fixed; |
|||
height: 100%; |
|||
/* bottom: 0; */ |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
flex-direction: column; |
|||
padding: 0 0 5% 0; |
|||
margin: 0; |
|||
border-right: solid 1px white; |
|||
z-index: 99; |
|||
} |
|||
.liste1, |
|||
.liste2 { |
|||
list-style: none; |
|||
padding: 0; |
|||
margin: 0; |
|||
display: flex; |
|||
flex-direction: column; |
|||
gap: 20px; |
|||
} |
|||
.liste1 li, |
|||
.liste2 li { |
|||
font-size: 25px; |
|||
cursor: pointer; |
|||
} |
|||
.nav_link { |
|||
color: white; |
|||
position: relative; |
|||
transition: 0.8s ease; |
|||
} |
|||
.icon_label { |
|||
position: absolute; |
|||
top: 0; /* Below the icon */ |
|||
left: 60px; |
|||
transform: translateX(-50%); |
|||
background-color: black; |
|||
color: white; |
|||
padding: 5px; |
|||
border-radius: 4px; |
|||
white-space: nowrap; /* Keep the label on one line */ |
|||
font-size: 12px; |
|||
margin-top: 5px; /* Slight gap between icon and label */ |
|||
z-index: 1; |
|||
} |
|||
|
After Width: | Height: | Size: 7.4 KiB |
|
After Width: | Height: | Size: 290 KiB |
|
After Width: | Height: | Size: 14 MiB |
@ -0,0 +1,97 @@ |
|||
/* :root { |
|||
--ev-c-white: #ffffff; |
|||
--ev-c-white-soft: #f8f8f8; |
|||
--ev-c-white-mute: #f2f2f2; |
|||
|
|||
--ev-c-black: #1b1b1f; |
|||
--ev-c-black-soft: #222222; |
|||
--ev-c-black-mute: #282828; |
|||
|
|||
--ev-c-gray-1: #515c67; |
|||
--ev-c-gray-2: #414853; |
|||
--ev-c-gray-3: #32363f; |
|||
|
|||
--ev-c-text-1: rgba(255, 255, 245, 0.86); |
|||
--ev-c-text-2: rgba(235, 235, 245, 0.6); |
|||
--ev-c-text-3: rgba(235, 235, 245, 0.38); |
|||
|
|||
--ev-button-alt-border: transparent; |
|||
--ev-button-alt-text: var(--ev-c-text-1); |
|||
--ev-button-alt-bg: var(--ev-c-gray-3); |
|||
--ev-button-alt-hover-border: transparent; |
|||
--ev-button-alt-hover-text: var(--ev-c-text-1); |
|||
--ev-button-alt-hover-bg: var(--ev-c-gray-2); |
|||
} |
|||
|
|||
:root { |
|||
--color-background: var(--ev-c-black); |
|||
--color-background-soft: var(--ev-c-black-soft); |
|||
--color-background-mute: var(--ev-c-black-mute); |
|||
|
|||
--color-text: var(--ev-c-text-1); |
|||
} |
|||
|
|||
*, |
|||
*::before, |
|||
*::after { |
|||
box-sizing: border-box; |
|||
margin: 0; |
|||
font-weight: normal; |
|||
} |
|||
|
|||
ul { |
|||
list-style: none; |
|||
} |
|||
|
|||
body { |
|||
min-height: 100vh; |
|||
color: var(--color-text); |
|||
background: var(--color-background); |
|||
line-height: 1.6; |
|||
font-family: |
|||
Inter, |
|||
-apple-system, |
|||
BlinkMacSystemFont, |
|||
'Segoe UI', |
|||
Roboto, |
|||
Oxygen, |
|||
Ubuntu, |
|||
Cantarell, |
|||
'Fira Sans', |
|||
'Droid Sans', |
|||
'Helvetica Neue', |
|||
sans-serif; |
|||
text-rendering: optimizeLegibility; |
|||
-webkit-font-smoothing: antialiased; |
|||
-moz-osx-font-smoothing: grayscale; |
|||
} */ |
|||
.form-control:focus { |
|||
outline: none; |
|||
box-shadow: none; |
|||
border-color: initial; /* Optional: restore the default border color */ |
|||
} |
|||
table { |
|||
border-collapse: collapse; /* Ensure there is no space between table cells */ |
|||
width: 100%; /* Adjust width as needed */ |
|||
margin: 0; |
|||
padding: 0; |
|||
} |
|||
|
|||
td, |
|||
th { |
|||
padding: 0; /* Remove padding from table cells */ |
|||
margin: 0; /* Ensure no margin inside cells */ |
|||
border: 1px solid black; /* Optional: Add border if needed */ |
|||
text-align: center; /* Center text horizontally */ |
|||
vertical-align: middle; /* Center text vertically */ |
|||
} |
|||
|
|||
tr { |
|||
margin: 0; |
|||
padding: 0; |
|||
} |
|||
|
|||
tbody { |
|||
margin: 0; |
|||
padding: 0; |
|||
} |
|||
|
After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 7.9 MiB |
|
After Width: | Height: | Size: 2.6 MiB |
|
After Width: | Height: | Size: 24 MiB |
|
After Width: | Height: | Size: 5.7 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 863 B |
|
After Width: | Height: | Size: 156 KiB |
|
After Width: | Height: | Size: 69 KiB |
|
After Width: | Height: | Size: 7.2 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 9.8 KiB |