initialisation c-university
14
.devdbrc
Normal file
@ -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"
|
||||||
|
}
|
||||||
|
]
|
||||||
9
.editorconfig
Normal file
@ -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
|
||||||
4
.eslintignore
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
out
|
||||||
|
.gitignore
|
||||||
9
.eslintrc.cjs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
module.exports = {
|
||||||
|
extends: [
|
||||||
|
'eslint:recommended',
|
||||||
|
'plugin:react/recommended',
|
||||||
|
'plugin:react/jsx-runtime',
|
||||||
|
'@electron-toolkit',
|
||||||
|
'@electron-toolkit/eslint-config-prettier'
|
||||||
|
]
|
||||||
|
}
|
||||||
8
.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
out
|
||||||
|
fashion-street-style-horizontal-business-card-template.zip
|
||||||
|
.DS_Store
|
||||||
|
*.log*
|
||||||
|
data.db
|
||||||
|
package-lock.json
|
||||||
6
.prettierignore
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
out
|
||||||
|
dist
|
||||||
|
pnpm-lock.yaml
|
||||||
|
LICENSE.md
|
||||||
|
tsconfig.json
|
||||||
|
tsconfig.*.json
|
||||||
4
.prettierrc.yaml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
singleQuote: true
|
||||||
|
semi: false
|
||||||
|
printWidth: 100
|
||||||
|
trailingComma: none
|
||||||
3
.vscode/extensions.json
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"recommendations": ["dbaeumer.vscode-eslint"]
|
||||||
|
}
|
||||||
39
.vscode/launch.json
vendored
Normal file
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
12
.vscode/settings.json
vendored
Normal file
@ -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"
|
||||||
|
}
|
||||||
34
README.md
Normal file
@ -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
|
||||||
|
```
|
||||||
118
backup.js
Normal file
@ -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
|
||||||
|
}
|
||||||
|
})
|
||||||
12
build/entitlements.mac.plist
Normal file
@ -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>
|
||||||
BIN
build/icon.icns
Normal file
BIN
build/icon.ico
Normal file
|
After Width: | Height: | Size: 121 KiB |
BIN
build/icon.png
Normal file
|
After Width: | Height: | Size: 35 KiB |
113
database/Models/AnneeScolaire.js
Normal file
@ -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
|
||||||
|
}
|
||||||
305
database/Models/Etudiants.js
Normal file
@ -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
|
||||||
|
}
|
||||||
41
database/Models/IpConfig.js
Normal file
@ -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
|
||||||
|
}
|
||||||
354
database/Models/Matieres.js
Normal file
@ -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
|
||||||
|
}
|
||||||
69
database/Models/Mentions.js
Normal file
@ -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
|
||||||
|
}
|
||||||
106
database/Models/Niveau.js
Normal file
@ -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
|
||||||
|
}
|
||||||
222
database/Models/NoteRepechage.js
Normal file
@ -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
|
||||||
|
}
|
||||||
44
database/Models/NoteSysrem.js
Normal file
@ -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
|
||||||
|
}
|
||||||
317
database/Models/Notes.js
Normal file
@ -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
|
||||||
|
}
|
||||||
179
database/Models/Parcours.js
Normal file
@ -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
|
||||||
|
}
|
||||||
21
database/Models/Status.js
Normal file
@ -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
|
||||||
|
}
|
||||||
149
database/Models/Users.js
Normal file
@ -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
|
||||||
|
}
|
||||||
142
database/TableData.sql
Normal file
@ -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
|
||||||
|
);
|
||||||
151
database/api/CheckUpdateNote.js
Normal file
@ -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
|
||||||
|
}
|
||||||
5
database/api/Config.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
const URL = 'https://api.polytechnique.c4m.mg'
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
URL
|
||||||
|
}
|
||||||
75
database/api/Get.js
Normal file
@ -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
|
||||||
|
}
|
||||||
422
database/api/Send.js
Normal file
@ -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
|
||||||
|
}
|
||||||
107
database/api/SyncronisationDataEtudiants.js
Normal file
@ -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
|
||||||
|
}
|
||||||
108
database/api/SyncronisationDataUsers.js
Normal file
@ -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
|
||||||
|
}
|
||||||
3
database/api/Update.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
const { app, dialog } = require('electron')
|
||||||
|
|
||||||
|
const checkUpdate = () => {}
|
||||||
441
database/database.js
Normal file
@ -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
|
||||||
|
}
|
||||||
33
database/function/DownloadReleverNote.js
Normal file
@ -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
|
||||||
|
}
|
||||||
9
database/function/GetImageDefaault.js
Normal file
@ -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
|
||||||
|
}
|
||||||
26
database/function/Helper.js
Normal file
@ -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
|
||||||
|
}
|
||||||
26
database/function/StringArrayConvertion.js
Normal file
@ -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
|
||||||
|
}
|
||||||
332
database/function/System.js
Normal file
@ -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
|
||||||
|
}
|
||||||
210
database/import/Etudiants.js
Normal file
@ -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
|
||||||
|
}
|
||||||
69
database/import/Matieres.js
Normal file
@ -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
|
||||||
|
}
|
||||||
52
database/import/Niveau.js
Normal file
@ -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
|
||||||
|
}
|
||||||
45
electron-builder.yml
Normal file
@ -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
|
||||||
|
|
||||||
25
electron.vite.config.1737019603496.mjs
Normal file
@ -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 }
|
||||||
25
electron.vite.config.1737797462311.mjs
Normal file
@ -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 }
|
||||||
23
electron.vite.config.mjs
Normal file
@ -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')
|
||||||
|
}
|
||||||
|
})
|
||||||
85
package.json
Normal file
@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
resources/icon.png
Normal file
|
After Width: | Height: | Size: 35 KiB |
BIN
resources/logo.ico
Normal file
|
After Width: | Height: | Size: 43 KiB |
103
reste.txt
Normal file
@ -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!
|
||||||
255
src/main/backup.js
Normal file
@ -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
|
||||||
|
})
|
||||||
908
src/main/index.js
Normal file
@ -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
|
||||||
|
})
|
||||||
135
src/main/test.js
Normal file
@ -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
|
||||||
|
}
|
||||||
|
})
|
||||||
210
src/preload/index.js
Normal file
@ -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
|
||||||
|
}
|
||||||
18
src/renderer/index.html
Normal file
@ -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>
|
||||||
63
src/renderer/src/App.jsx
Normal file
@ -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
|
||||||
207
src/renderer/src/Routes/Routes.jsx
Normal file
@ -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
|
||||||
12
src/renderer/src/assets/AddNotes.module.css
Normal file
@ -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%;
|
||||||
|
}
|
||||||
15
src/renderer/src/assets/AddStudent.module.css
Normal file
@ -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;
|
||||||
|
}
|
||||||
17
src/renderer/src/assets/AllStyleComponents.module.css
Normal file
@ -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%;
|
||||||
|
}
|
||||||
BIN
src/renderer/src/assets/Capture.PNG
Normal file
|
After Width: | Height: | Size: 8.9 KiB |
86
src/renderer/src/assets/CarteStudent.module.css
Normal file
@ -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;
|
||||||
|
}
|
||||||
4
src/renderer/src/assets/Dashboard.module.css
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
.display {
|
||||||
|
background-color: rgba(255, 255, 255, 0.9);
|
||||||
|
/* margin-bottom: 2%; */
|
||||||
|
}
|
||||||
20
src/renderer/src/assets/DefaultLayout.module.css
Normal file
@ -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%;
|
||||||
|
}
|
||||||
78
src/renderer/src/assets/ExportReleverNote.module.css
Normal file
@ -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;
|
||||||
|
}
|
||||||
78
src/renderer/src/assets/Home.module.css
Normal file
@ -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);
|
||||||
|
}
|
||||||
20
src/renderer/src/assets/Login.module.css
Normal file
@ -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;
|
||||||
|
}
|
||||||
25
src/renderer/src/assets/Navbar.module.css
Normal file
@ -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;
|
||||||
|
}
|
||||||
51
src/renderer/src/assets/Sidenav.module.css
Normal file
@ -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;
|
||||||
|
}
|
||||||
BIN
src/renderer/src/assets/Template carte arriere.pdf
Normal file
BIN
src/renderer/src/assets/Template carte frontal.pdf
Normal file
BIN
src/renderer/src/assets/admin.png
Normal file
|
After Width: | Height: | Size: 7.4 KiB |
BIN
src/renderer/src/assets/arriere.pdf
Normal file
BIN
src/renderer/src/assets/autorisationstage.pdf
Normal file
BIN
src/renderer/src/assets/background.jpg
Normal file
|
After Width: | Height: | Size: 290 KiB |
BIN
src/renderer/src/assets/background2.jpg
Normal file
|
After Width: | Height: | Size: 14 MiB |
97
src/renderer/src/assets/base.css
Normal file
@ -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;
|
||||||
|
}
|
||||||
BIN
src/renderer/src/assets/bg1-min.jpg
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
src/renderer/src/assets/bg1.jpg
Normal file
|
After Width: | Height: | Size: 7.9 MiB |
BIN
src/renderer/src/assets/bg2-min.jpg
Normal file
|
After Width: | Height: | Size: 2.6 MiB |
BIN
src/renderer/src/assets/bg2.jpg
Normal file
|
After Width: | Height: | Size: 24 MiB |
BIN
src/renderer/src/assets/business_card_template_001.pdf
Normal file
BIN
src/renderer/src/assets/business_card_template_001_form.pdf
Normal file
BIN
src/renderer/src/assets/business_card_template_002.pdf
Normal file
BIN
src/renderer/src/assets/carte_etudiant.odg
Normal file
BIN
src/renderer/src/assets/carte_etudiant.pdf
Normal file
BIN
src/renderer/src/assets/certificat scolariter.pdf
Normal file
10
src/renderer/src/assets/electron.svg
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<svg viewBox="0 0 128 128" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<circle cx="64" cy="64" r="64" fill="#2F3242"/>
|
||||||
|
<ellipse cx="63.9835" cy="23.2036" rx="4.48794" ry="4.495" stroke="#A2ECFB" stroke-width="3.6" stroke-linecap="round"/>
|
||||||
|
<path d="M51.3954 39.5028C52.3733 39.6812 53.3108 39.033 53.4892 38.055C53.6676 37.0771 53.0194 36.1396 52.0414 35.9612L51.3954 39.5028ZM28.6153 43.5751L30.1748 44.4741L30.1748 44.4741L28.6153 43.5751ZM28.9393 60.9358C29.4332 61.7985 30.5329 62.0976 31.3957 61.6037C32.2585 61.1098 32.5575 60.0101 32.0636 59.1473L28.9393 60.9358ZM37.6935 66.7457C37.025 66.01 35.8866 65.9554 35.1508 66.6239C34.415 67.2924 34.3605 68.4308 35.029 69.1666L37.6935 66.7457ZM53.7489 81.7014L52.8478 83.2597L53.7489 81.7014ZM96.9206 89.515C97.7416 88.9544 97.9526 87.8344 97.3919 87.0135C96.8313 86.1925 95.7113 85.9815 94.8904 86.5422L96.9206 89.515ZM52.0414 35.9612C46.4712 34.9451 41.2848 34.8966 36.9738 35.9376C32.6548 36.9806 29.0841 39.1576 27.0559 42.6762L30.1748 44.4741C31.5693 42.0549 34.1448 40.3243 37.8188 39.4371C41.5009 38.5479 46.1547 38.5468 51.3954 39.5028L52.0414 35.9612ZM27.0559 42.6762C24.043 47.9029 25.2781 54.5399 28.9393 60.9358L32.0636 59.1473C28.6579 53.1977 28.1088 48.0581 30.1748 44.4741L27.0559 42.6762ZM35.029 69.1666C39.6385 74.24 45.7158 79.1355 52.8478 83.2597L54.6499 80.1432C47.8081 76.1868 42.0298 71.5185 37.6935 66.7457L35.029 69.1666ZM52.8478 83.2597C61.344 88.1726 70.0465 91.2445 77.7351 92.3608C85.359 93.4677 92.2744 92.6881 96.9206 89.515L94.8904 86.5422C91.3255 88.9767 85.4902 89.849 78.2524 88.7982C71.0793 87.7567 62.809 84.8612 54.6499 80.1432L52.8478 83.2597ZM105.359 84.9077C105.359 81.4337 102.546 78.6127 99.071 78.6127V82.2127C100.553 82.2127 101.759 83.4166 101.759 84.9077H105.359ZM99.071 78.6127C95.5956 78.6127 92.7831 81.4337 92.7831 84.9077H96.3831C96.3831 83.4166 97.5892 82.2127 99.071 82.2127V78.6127ZM92.7831 84.9077C92.7831 88.3817 95.5956 91.2027 99.071 91.2027V87.6027C97.5892 87.6027 96.3831 86.3988 96.3831 84.9077H92.7831ZM99.071 91.2027C102.546 91.2027 105.359 88.3817 105.359 84.9077H101.759C101.759 86.3988 100.553 87.6027 99.071 87.6027V91.2027Z" fill="#A2ECFB"/>
|
||||||
|
<path d="M91.4873 65.382C90.8456 66.1412 90.9409 67.2769 91.7002 67.9186C92.4594 68.5603 93.5951 68.465 94.2368 67.7058L91.4873 65.382ZM99.3169 43.6354L97.7574 44.5344L99.3169 43.6354ZM84.507 35.2412C83.513 35.2282 82.6967 36.0236 82.6838 37.0176C82.6708 38.0116 83.4661 38.8279 84.4602 38.8409L84.507 35.2412ZM74.9407 39.8801C75.9127 39.6716 76.5315 38.7145 76.323 37.7425C76.1144 36.7706 75.1573 36.1517 74.1854 36.3603L74.9407 39.8801ZM53.7836 46.3728L54.6847 47.931L53.7836 46.3728ZM25.5491 80.9047C25.6932 81.8883 26.6074 82.5688 27.5911 82.4247C28.5747 82.2806 29.2552 81.3664 29.1111 80.3828L25.5491 80.9047ZM94.2368 67.7058C97.8838 63.3907 100.505 58.927 101.752 54.678C103.001 50.4213 102.9 46.2472 100.876 42.7365L97.7574 44.5344C99.1494 46.9491 99.3603 50.0419 98.2974 53.6644C97.2323 57.2945 94.9184 61.3223 91.4873 65.382L94.2368 67.7058ZM100.876 42.7365C97.9119 37.5938 91.7082 35.335 84.507 35.2412L84.4602 38.8409C91.1328 38.9278 95.7262 41.0106 97.7574 44.5344L100.876 42.7365ZM74.1854 36.3603C67.4362 37.8086 60.0878 40.648 52.8826 44.8146L54.6847 47.931C61.5972 43.9338 68.5948 41.2419 74.9407 39.8801L74.1854 36.3603ZM52.8826 44.8146C44.1366 49.872 36.9669 56.0954 32.1491 62.3927C27.3774 68.63 24.7148 75.2115 25.5491 80.9047L29.1111 80.3828C28.4839 76.1026 30.4747 70.5062 35.0084 64.5802C39.496 58.7143 46.2839 52.7889 54.6847 47.931L52.8826 44.8146Z" fill="#A2ECFB"/>
|
||||||
|
<path d="M49.0825 87.2295C48.7478 86.2934 47.7176 85.8059 46.7816 86.1406C45.8455 86.4753 45.358 87.5055 45.6927 88.4416L49.0825 87.2295ZM78.5635 96.4256C79.075 95.5732 78.7988 94.4675 77.9464 93.9559C77.0941 93.4443 75.9884 93.7205 75.4768 94.5729L78.5635 96.4256ZM79.5703 85.1795C79.2738 86.1284 79.8027 87.1379 80.7516 87.4344C81.7004 87.7308 82.71 87.2019 83.0064 86.2531L79.5703 85.1795ZM84.3832 64.0673H82.5832H84.3832ZM69.156 22.5301C68.2477 22.1261 67.1838 22.535 66.7799 23.4433C66.3759 24.3517 66.7848 25.4155 67.6931 25.8194L69.156 22.5301ZM45.6927 88.4416C47.5994 93.7741 50.1496 98.2905 53.2032 101.505C56.2623 104.724 59.9279 106.731 63.9835 106.731V103.131C61.1984 103.131 58.4165 101.765 55.8131 99.0249C53.2042 96.279 50.8768 92.2477 49.0825 87.2295L45.6927 88.4416ZM63.9835 106.731C69.8694 106.731 74.8921 102.542 78.5635 96.4256L75.4768 94.5729C72.0781 100.235 68.0122 103.131 63.9835 103.131V106.731ZM83.0064 86.2531C85.0269 79.7864 86.1832 72.1831 86.1832 64.0673H82.5832C82.5832 71.8536 81.4723 79.0919 79.5703 85.1795L83.0064 86.2531ZM86.1832 64.0673C86.1832 54.1144 84.4439 44.922 81.4961 37.6502C78.5748 30.4436 74.3436 24.8371 69.156 22.5301L67.6931 25.8194C71.6364 27.5731 75.3846 32.1564 78.1598 39.0026C80.9086 45.7836 82.5832 54.507 82.5832 64.0673H86.1832Z" fill="#A2ECFB"/>
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M103.559 84.9077C103.559 82.4252 101.55 80.4127 99.071 80.4127C96.5924 80.4127 94.5831 82.4252 94.5831 84.9077C94.5831 87.3902 96.5924 89.4027 99.071 89.4027C101.55 89.4027 103.559 87.3902 103.559 84.9077V84.9077Z" stroke="#A2ECFB" stroke-width="3.6" stroke-linecap="round"/>
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M28.8143 89.4027C31.2929 89.4027 33.3023 87.3902 33.3023 84.9077C33.3023 82.4252 31.2929 80.4127 28.8143 80.4127C26.3357 80.4127 24.3264 82.4252 24.3264 84.9077C24.3264 87.3902 26.3357 89.4027 28.8143 89.4027V89.4027V89.4027Z" stroke="#A2ECFB" stroke-width="3.6" stroke-linecap="round"/>
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M64.8501 68.0857C62.6341 68.5652 60.451 67.1547 59.9713 64.9353C59.4934 62.7159 60.9007 60.5293 63.1167 60.0489C65.3326 59.5693 67.5157 60.9798 67.9954 63.1992C68.4742 65.4186 67.066 67.6052 64.8501 68.0857Z" fill="#A2ECFB"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 5.7 KiB |
BIN
src/renderer/src/assets/enteterelever.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
52
src/renderer/src/assets/error.svg
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 52 52"
|
||||||
|
width="100"
|
||||||
|
height="100"
|
||||||
|
>
|
||||||
|
<circle
|
||||||
|
cx="26"
|
||||||
|
cy="26"
|
||||||
|
r="25"
|
||||||
|
fill="none"
|
||||||
|
stroke="#f44336"
|
||||||
|
stroke-width="2"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill="none"
|
||||||
|
stroke="#f44336"
|
||||||
|
stroke-width="5"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-dasharray="40"
|
||||||
|
stroke-dashoffset="40"
|
||||||
|
d="M16 16l20 20M16 36l20-20"
|
||||||
|
id="error-cross"
|
||||||
|
/>
|
||||||
|
<style>
|
||||||
|
@keyframes drawError {
|
||||||
|
0% {
|
||||||
|
stroke-dashoffset: 40;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
stroke-dashoffset: 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
stroke-dashoffset: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#error-cross {
|
||||||
|
animation: drawError 1s ease forwards infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes pulse {
|
||||||
|
0%, 100% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 863 B |
BIN
src/renderer/src/assets/exemplecarte.png
Normal file
|
After Width: | Height: | Size: 156 KiB |
BIN
src/renderer/src/assets/logo or.png
Normal file
|
After Width: | Height: | Size: 69 KiB |
BIN
src/renderer/src/assets/logo.PNG
Normal file
|
After Width: | Height: | Size: 7.2 KiB |
BIN
src/renderer/src/assets/logo.ico
Normal file
|
After Width: | Height: | Size: 43 KiB |
BIN
src/renderer/src/assets/logo.webp
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
src/renderer/src/assets/logo_uni-removebg-preview.webp
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
src/renderer/src/assets/logorelever.png
Normal file
|
After Width: | Height: | Size: 9.8 KiB |