From dae6d25e337946efbc7c0ddc4f0e0a9b1748c25c Mon Sep 17 00:00:00 2001 From: PedroMartinSteenstrup <24451974+PedroMartinSteenstrup@users.noreply.github.com> Date: Mon, 22 Apr 2024 00:52:04 +0200 Subject: [PATCH] chore(parametrized SQL and CSS) --- portfolio/docker-compose.yml | 2 +- portfolio/public/index.html | 43 ---------------- portfolio/scripts/build-db.sql | 54 +++++++++++++++++++- portfolio/src/db.js | 36 ++++++++++++++ portfolio/src/index.js | 21 +++----- portfolio/src/package-lock.json | 40 ++++++++++++++- portfolio/src/package.json | 9 ++-- portfolio/src/routes/courses.js | 23 +-------- portfolio/src/routes/experiences.js | 24 +-------- portfolio/src/routes/realisations.js | 34 +++++++++++++ portfolio/src/views/courses.ejs | 3 ++ portfolio/src/views/experiences.ejs | 1 + portfolio/src/views/index.ejs | 3 ++ portfolio/src/views/realisation_view.ejs | 18 +++++++ portfolio/src/views/realisations.ejs | 32 ++++++++++++ portfolio/src/views/styles.ejs | 63 ++++++++++++++++++++++++ 16 files changed, 299 insertions(+), 107 deletions(-) delete mode 100644 portfolio/public/index.html create mode 100644 portfolio/src/db.js create mode 100644 portfolio/src/routes/realisations.js create mode 100644 portfolio/src/views/realisation_view.ejs create mode 100644 portfolio/src/views/realisations.ejs create mode 100644 portfolio/src/views/styles.ejs diff --git a/portfolio/docker-compose.yml b/portfolio/docker-compose.yml index 112807b..80fe2ba 100644 --- a/portfolio/docker-compose.yml +++ b/portfolio/docker-compose.yml @@ -48,7 +48,7 @@ services: context: ./nginx dockerfile: Dockerfile ports: - - 8005:${NGINX_PORT} + - 80:${NGINX_PORT} # volumes: # - certbot-etc:/etc/letsencrypt # - certbot-var:/var/lib/letsencrypt diff --git a/portfolio/public/index.html b/portfolio/public/index.html deleted file mode 100644 index aa069f2..0000000 --- a/portfolio/public/index.html +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - - React App - - - -
- - - diff --git a/portfolio/scripts/build-db.sql b/portfolio/scripts/build-db.sql index 0d7f2d9..293d948 100644 --- a/portfolio/scripts/build-db.sql +++ b/portfolio/scripts/build-db.sql @@ -1,5 +1,7 @@ -- autocommit is deactivated BEGIN TRANSACTION; +SET datestyle to SQL, + DMY; SET search_path TO public; CREATE TABLE IF NOT EXISTS settings ( id SERIAL PRIMARY KEY, @@ -58,4 +60,54 @@ VALUES ( 'Wise', 'Data Analyst', 'Mise en place d''indicateurs de performance, de solutions de visualisation et de scripts d''extraction de données' - ) \ No newline at end of file + ); +DROP TABLE IF EXISTS realisations; +CREATE TABLE IF NOT EXISTS realisations ( + id SERIAL PRIMARY KEY, + r_début DATE NOT NULL, + r_fin DATE NOT NULL, + r_intitule TEXT NOT NULL, + r_description TEXT NOT NULL, + est_gestion_patrimoine BOOLEAN, + est_response_incidents BOOLEAN, + est_presence_en_ligne BOOLEAN, + est_travail_mode_projet BOOLEAN, + est_deploiement_service BOOLEAN, + est_developpement_pro BOOLEAN +); +INSERT INTO realisations ( + r_début, + r_fin, + r_intitule, + r_description, + est_gestion_patrimoine, + est_response_incidents, + est_presence_en_ligne, + est_travail_mode_projet, + est_deploiement_service, + est_developpement_pro + ) +VALUES ( + '05-03-2024', + '30-04-2024', + 'Création d''un site portfolio dans le cadre de l''épreuve E4', + 'Express, nodejs, postgres, template, conteneurisé', + FALSE, + FALSE, + TRUE, + TRUE, + TRUE, + TRUE + ), + ( + '05-03-2024', + '30-04-2024', + 'Automatisation de la gestion du code, des resources (utilisation du paradigme dit IaC – Infrastructure as Code) ainsi que du déploiement', + 'Github Actions, Terraform, Ansible', + TRUE, + FALSE, + FALSE, + FALSE, + TRUE, + TRUE + ); \ No newline at end of file diff --git a/portfolio/src/db.js b/portfolio/src/db.js new file mode 100644 index 0000000..822b942 --- /dev/null +++ b/portfolio/src/db.js @@ -0,0 +1,36 @@ +// Items in the global namespace are accessible throught out the node application +// https://node-postgres.com/features/pooling +const Pool = require("pg").Pool; +// https://nodejs.org/en/learn/command-line/how-to-read-environment-variables-from-nodejs +const pool = new Pool({ + user: process.env.POSTGRES_USER, + host: process.env.POSTGRES_HOST, + database: process.env.POSTGRES_DB, + password: process.env.POSTGRES_PASSWORD, + port: process.env.POSTGRES_PORT, +}); + +//get all from our database +const getData = async (sql_query, values) => { + try { + return await new Promise(function (resolve, reject) { + pool.query(sql_query, values, (error, results) => { + if (error) { + reject(error); + } + if (results && results.rows) { + resolve(results.rows); + } else { + reject(new Error("No results found")); + } + }); + }); + } catch (err) { + console.error(err); + } +}; + + +module.exports = { + getData, +}; \ No newline at end of file diff --git a/portfolio/src/index.js b/portfolio/src/index.js index 5250996..c498f4e 100644 --- a/portfolio/src/index.js +++ b/portfolio/src/index.js @@ -1,26 +1,16 @@ const express = require('express') +const path = require('node:path'); const app = express() const port = process.env.NODE_PORT var bodyParser = require("body-parser"); app.use(bodyParser.urlencoded({ extended: true })); app.set('view engine', 'ejs'); // set the app to use ejs for rendering -app.use(express.static(__dirname + '/public')); // set location of static files +app.use(express.static(__dirname + '../public')); // set location of static files app.locals.title = "Portfolio de Pedro"; app.locals.author = "Pedro Martin"; - -// Items in the global namespace are accessible throught out the node application -// https://node-postgres.com/features/pooling -const Pool = require("pg").Pool; -// https://nodejs.org/en/learn/command-line/how-to-read-environment-variables-from-nodejs -global.pool = new Pool({ - user: process.env.POSTGRES_USER, - host: process.env.POSTGRES_HOST, - database: process.env.POSTGRES_DB, - password: process.env.POSTGRES_PASSWORD, - port: process.env.POSTGRES_PORT, -}); +app.use('/favicon.ico', express.static('favicon.ico')); app.use(express.json()) app.use(function (req, res, next) { @@ -30,8 +20,6 @@ app.use(function (req, res, next) { next(); }); -const defRoutes = require('./routes/courses') - // Add all the route handlers to the app const mainRoutes = require('./routes/main'); app.use(mainRoutes); @@ -42,6 +30,9 @@ app.use(coursesRoutes); const xpRoutes = require('./routes/experiences'); app.use(xpRoutes); +const reaRoutes = require('./routes/realisations'); +app.use(reaRoutes); + // Make the web application listen for HTTP requests app.listen(port, () => { console.log(`Server running at http://localhost:${port}`) diff --git a/portfolio/src/package-lock.json b/portfolio/src/package-lock.json index 86da7a4..9df906e 100644 --- a/portfolio/src/package-lock.json +++ b/portfolio/src/package-lock.json @@ -9,10 +9,12 @@ "version": "1.0.0", "license": "ISC", "dependencies": { + "dotenv": "^16.4.5", "ejs": "^3.1.10", "express": "^4.19.2", "express-validator": "^7.0.1", - "pg": "^8.11.5" + "pg": "^8.11.5", + "serve-favicon": "^2.5.0" } }, "node_modules/accepts": { @@ -223,6 +225,17 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -868,6 +881,31 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, + "node_modules/serve-favicon": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/serve-favicon/-/serve-favicon-2.5.0.tgz", + "integrity": "sha512-FMW2RvqNr03x+C0WxTyu6sOv21oOjkq5j8tjquWccwa6ScNyGFOGJVpuS1NmTVGBAHS07xnSKotgf2ehQmf9iA==", + "dependencies": { + "etag": "~1.8.1", + "fresh": "0.5.2", + "ms": "2.1.1", + "parseurl": "~1.3.2", + "safe-buffer": "5.1.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-favicon/node_modules/ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + }, + "node_modules/serve-favicon/node_modules/safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + }, "node_modules/serve-static": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", diff --git a/portfolio/src/package.json b/portfolio/src/package.json index 7afb8e4..f395123 100644 --- a/portfolio/src/package.json +++ b/portfolio/src/package.json @@ -1,15 +1,18 @@ { "dependencies": { + "dotenv": "^16.4.5", "ejs": "^3.1.10", "express": "^4.19.2", "express-validator": "^7.0.1", - "pg": "^8.11.5" + "pg": "^8.11.5", + "serve-favicon": "^2.5.0" }, "scripts": { + "start-local": "node -r dotenv/config index.js dotenv_config_path=./../../.env.local", "build-db": ". ../.env && PGPASSWORD=$POSTGRES_PASSWORD psql -e -h localhost -d $POSTGRES_DB -U $POSTGRES_USER -p 5433 -f ./scripts/build-db.sql", "clean-db": ". ../.env && PGPASSWORD=$POSTGRES_PASSWORD psql -e -h localhost -d $POSTGRES_DB -U $POSTGRES_USER -p 5433 -f ./scripts/clean-db.sql", - "build-db-local": ". ../.env.local && PGPASSWORD=$POSTGRES_PASSWORD psql -e -h localhost -d $POSTGRES_DB -U $POSTGRES_USER -p 5433 -f ../scripts/build-db.sql", - "clean-db-local": ". ../.env.local && PGPASSWORD=$POSTGRES_PASSWORD psql -e -h localhost -d $POSTGRES_DB -U $POSTGRES_USER -p 5433 -f ../scripts/clean-db.sql", + "build-db-local": ". ../../.env.local && PGPASSWORD=$POSTGRES_PASSWORD psql -e -h localhost -d $POSTGRES_DB -U $POSTGRES_USER -p 5433 -f ../scripts/build-db.sql", + "clean-db-local": ". ../../.env.local && PGPASSWORD=$POSTGRES_PASSWORD psql -e -h localhost -d $POSTGRES_DB -U $POSTGRES_USER -p 5433 -f ../scripts/clean-db.sql", "build-db-docker": ". ../.env && PGPASSWORD=$POSTGRES_PASSWORD psql -e -h localhost -d $POSTGRES_DB -U $POSTGRES_USER -p 5433 -f ../scripts/build-db.sql", "clean-db-docker": ". ../.env && PGPASSWORD=$POSTGRES_PASSWORD psql -e -h localhost -d $POSTGRES_DB -U $POSTGRES_USER -p 5433 -f ../scripts/clean-db.sql" }, diff --git a/portfolio/src/routes/courses.js b/portfolio/src/routes/courses.js index f87c363..41cfb79 100644 --- a/portfolio/src/routes/courses.js +++ b/portfolio/src/routes/courses.js @@ -1,26 +1,7 @@ const express = require("express"); const router = express.Router(); +const getData = require("../db").getData; -//get all from our database -const getData = async (sql_query) => { - try { - return await new Promise(function (resolve, reject) { - pool.query(sql_query, (error, results) => { - if (error) { - reject(error); - } - if (results && results.rows) { - resolve(results.rows); - } else { - reject(new Error("No results found")); - } - }); - }); - } catch (error_1) { - console.error(error_1); - throw new Error("Internal server error"); - } -}; /** * @desc Display all the users */ @@ -38,4 +19,4 @@ router.get("/list-courses", (req, res, next) => { }); // Export the router object so index.js can access it -module.exports = router; +module.exports = router; \ No newline at end of file diff --git a/portfolio/src/routes/experiences.js b/portfolio/src/routes/experiences.js index 625371b..9982c62 100644 --- a/portfolio/src/routes/experiences.js +++ b/portfolio/src/routes/experiences.js @@ -1,26 +1,6 @@ const express = require("express"); const router = express.Router(); - -//get all from our database -const getData = async (sql_query) => { - try { - return await new Promise(function (resolve, reject) { - pool.query(sql_query, (error, results) => { - if (error) { - reject(error); - } - if (results && results.rows) { - resolve(results.rows); - } else { - reject(new Error("No results found")); - } - }); - }); - } catch (error_1) { - console.error(error_1); - throw new Error("Internal server error"); - } -}; +const getData = require("../db").getData; /** * @desc Display all the users @@ -40,4 +20,4 @@ router.get("/experiences", (req, res, next) => { // Export the router object so index.js can access it -module.exports = router; +module.exports = router; \ No newline at end of file diff --git a/portfolio/src/routes/realisations.js b/portfolio/src/routes/realisations.js new file mode 100644 index 0000000..96085c8 --- /dev/null +++ b/portfolio/src/routes/realisations.js @@ -0,0 +1,34 @@ +const express = require("express"); +const router = express.Router(); +const getData = require("../db").getData; + +/** + * @desc Lister toutes les réalisations recensées + */ +router.get("/realisations", (req, res, next) => { + // Define the query + SQLquery = "SELECT * FROM realisations ORDER BY r_début DESC;" + getData(SQLquery) + .then((data) => { + res.render('realisations.ejs', + { realisations: data, title: req.app.locals.title }); + }); +}); + +/** + * @desc Voir le détail d'une réalisation + */ +router.get("/realisation/:id", (req, res, next) => { + var id = req.params.id; + // Define the query + SQLquery = `SELECT * FROM realisations WHERE id = $1::int;` + getData(SQLquery, [id]) + .then((data) => { + console.log(data[0]) + res.render('realisation_view.ejs', + { realisation: data[0], title: req.app.locals.title }); + }); +}); + +// Export the router object so index.js can access it +module.exports = router; \ No newline at end of file diff --git a/portfolio/src/views/courses.ejs b/portfolio/src/views/courses.ejs index d2560d9..2fdc3cb 100644 --- a/portfolio/src/views/courses.ejs +++ b/portfolio/src/views/courses.ejs @@ -1,6 +1,7 @@ + <%- include('styles'); %> The Main Courses Page @@ -8,6 +9,7 @@

List of courses

+
@@ -25,6 +27,7 @@ <% } %>
#ID
+

diff --git a/portfolio/src/views/experiences.ejs b/portfolio/src/views/experiences.ejs index e46b4e6..1bec6bf 100644 --- a/portfolio/src/views/experiences.ejs +++ b/portfolio/src/views/experiences.ejs @@ -1,6 +1,7 @@ + <%- include('styles'); %> The Main Experience Page diff --git a/portfolio/src/views/index.ejs b/portfolio/src/views/index.ejs index 46ff734..2a3f745 100644 --- a/portfolio/src/views/index.ejs +++ b/portfolio/src/views/index.ejs @@ -2,12 +2,15 @@ The Main Home Page +<%- include('styles'); %>

This is the Main Home Page

BTS SIO SISR Cours
Portfolio +
+Realisations

\ No newline at end of file diff --git a/portfolio/src/views/realisation_view.ejs b/portfolio/src/views/realisation_view.ejs new file mode 100644 index 0000000..9da733d --- /dev/null +++ b/portfolio/src/views/realisation_view.ejs @@ -0,0 +1,18 @@ + + + +The Main Realisations Page +<%- include('styles'); %> + + +

<%= title %>

+Accueil +
+

<%= realisation.r_intitule %>

+

+

<%= realisation.r_description %>

+ + + + + diff --git a/portfolio/src/views/realisations.ejs b/portfolio/src/views/realisations.ejs new file mode 100644 index 0000000..f78e66e --- /dev/null +++ b/portfolio/src/views/realisations.ejs @@ -0,0 +1,32 @@ + + + +The Main Realisations Page +<%- include('styles'); %> + + +

Liste des réalisations

+
+ + + + + + + + + <% for(var i=0; i < realisations.length; i++) { %> + <% start_date = realisations[i].r_début.toLocaleDateString() %> + <% end_date = realisations[i].r_fin.toLocaleDateString() %> + + + + + + + + <% } %> +
#IDPériodeTitreDescriptionAction
<%= (i+1) %><%= start_date +` - `+ end_date %><%= realisations[i].r_intitule %><%= realisations[i].r_description %>
+ + + diff --git a/portfolio/src/views/styles.ejs b/portfolio/src/views/styles.ejs new file mode 100644 index 0000000..96b6bf1 --- /dev/null +++ b/portfolio/src/views/styles.ejs @@ -0,0 +1,63 @@ + \ No newline at end of file