@ -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 |