Compare commits
5 commits
features/i
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
144dfaf8c8 | ||
|
|
fbd10c6fd5 | ||
|
|
b04045ca8e | ||
|
|
b7e37108cd | ||
|
|
f7441c5560 |
15 changed files with 742 additions and 346 deletions
10
app.js
10
app.js
|
|
@ -1,11 +1,10 @@
|
||||||
const SESSION_SECRET = "your_session_secret";
|
const SESSION_SECRET = "your_session_secret";
|
||||||
|
|
||||||
// ...existing code...
|
|
||||||
|
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
const session = require('express-session');
|
const session = require('express-session');
|
||||||
const initDb = require('./db_init');
|
const initDb = require('./db_init');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
const expressLayouts = require('express-ejs-layouts');
|
||||||
|
|
||||||
const routes = require('./routes');
|
const routes = require('./routes');
|
||||||
|
|
||||||
|
|
@ -34,6 +33,13 @@ app.use(session({
|
||||||
app.set('view engine', 'ejs');
|
app.set('view engine', 'ejs');
|
||||||
app.set('views', path.join(__dirname, 'views'));
|
app.set('views', path.join(__dirname, 'views'));
|
||||||
|
|
||||||
|
// Express EJS Layouts
|
||||||
|
app.use(expressLayouts);
|
||||||
|
app.set('layout', 'layout'); // nom du fichier layout sans .ejs
|
||||||
|
|
||||||
|
// Static files
|
||||||
|
app.use(express.static(path.join(__dirname, 'public')));
|
||||||
|
|
||||||
// Routes
|
// Routes
|
||||||
app.use('/', routes);
|
app.use('/', routes);
|
||||||
|
|
||||||
|
|
|
||||||
BIN
database.sqlite
BIN
database.sqlite
Binary file not shown.
21
db_init.js
21
db_init.js
|
|
@ -22,25 +22,4 @@ function initDb(dbPath = './database.sqlite') {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function initDb (dbPath = './database.sqlite') {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const db = new sqlite3.Database(dbPath, (err) => {
|
|
||||||
if (err) {
|
|
||||||
reject(err);
|
|
||||||
} else {
|
|
||||||
db.run(`
|
|
||||||
CREATE TABLE IF NOT EXISTS restaurants (
|
|
||||||
id INTEGER PRIMARY KEY,
|
|
||||||
nom TEXT NOT NULL,
|
|
||||||
description TEXT,
|
|
||||||
adresse TEXT NOT NULL,
|
|
||||||
menu TEXT
|
|
||||||
);
|
|
||||||
`);
|
|
||||||
}
|
|
||||||
db.close();
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
module.exports = initDb;
|
module.exports = initDb;
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,14 @@
|
||||||
const axios = require("axios");
|
const axios = require("axios");
|
||||||
|
|
||||||
const { getUserByDId } = require('../users/getUsers');
|
const { getUserByGId } = require('../users/getUsers');
|
||||||
const { postUser } = require('../users/postUsers');
|
const { postUser } = require('../users/postUsers');
|
||||||
|
|
||||||
const CLIEN_ID = "71229835507-9413gbpdamv2qbcb2ov8oda2oqgcsk8q.apps.googleusercontent.com";
|
const CLIEN_ID = "71229835507-9413gbpdamv2qbcb2ov8oda2oqgcsk8q.apps.googleusercontent.com";
|
||||||
const GOOGLE_SECRET = "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";
|
const GOOGLE_SECRET = "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";
|
||||||
const REDIRECT_URI = "http://localhost:3000/auth/google/callback";
|
const GOOGLE_REDIRECT_URI = "http://localhost:3000/auth/google/callback";
|
||||||
|
|
||||||
exports.handleGoogleAuth = async (code, res) => {
|
exports.handleGoogleAuth = async (req, res) => {
|
||||||
|
const code = req.query.code;
|
||||||
if (!code) return res.status(400).json({ error: "Code de validation manquant" });
|
if (!code) return res.status(400).json({ error: "Code de validation manquant" });
|
||||||
try {
|
try {
|
||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
|
|
@ -41,8 +42,6 @@ exports.handleGoogleAuth = async (code, res) => {
|
||||||
const newUser = {
|
const newUser = {
|
||||||
username: userData.name || userData.email,
|
username: userData.name || userData.email,
|
||||||
google_id: userData.id,
|
google_id: userData.id,
|
||||||
email: userData.email,
|
|
||||||
avatar: userData.picture || null,
|
|
||||||
};
|
};
|
||||||
savedUser = await postUser(newUser);
|
savedUser = await postUser(newUser);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
6
package-lock.json
generated
6
package-lock.json
generated
|
|
@ -12,6 +12,7 @@
|
||||||
"axios": "^1.11.0",
|
"axios": "^1.11.0",
|
||||||
"ejs": "^3.1.10",
|
"ejs": "^3.1.10",
|
||||||
"express": "^5.1.0",
|
"express": "^5.1.0",
|
||||||
|
"express-ejs-layouts": "^2.5.1",
|
||||||
"express-session": "^1.18.2",
|
"express-session": "^1.18.2",
|
||||||
"sqlite3": "^5.1.7"
|
"sqlite3": "^5.1.7"
|
||||||
}
|
}
|
||||||
|
|
@ -708,6 +709,11 @@
|
||||||
"url": "https://opencollective.com/express"
|
"url": "https://opencollective.com/express"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/express-ejs-layouts": {
|
||||||
|
"version": "2.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/express-ejs-layouts/-/express-ejs-layouts-2.5.1.tgz",
|
||||||
|
"integrity": "sha512-IXROv9n3xKga7FowT06n1Qn927JR8ZWDn5Dc9CJQoiiaaDqbhW5PDmWShzbpAa2wjWT1vJqaIM1S6vJwwX11gA=="
|
||||||
|
},
|
||||||
"node_modules/express-session": {
|
"node_modules/express-session": {
|
||||||
"version": "1.18.2",
|
"version": "1.18.2",
|
||||||
"resolved": "https://registry.npmjs.org/express-session/-/express-session-1.18.2.tgz",
|
"resolved": "https://registry.npmjs.org/express-session/-/express-session-1.18.2.tgz",
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
"axios": "^1.11.0",
|
"axios": "^1.11.0",
|
||||||
"ejs": "^3.1.10",
|
"ejs": "^3.1.10",
|
||||||
"express": "^5.1.0",
|
"express": "^5.1.0",
|
||||||
|
"express-ejs-layouts": "^2.5.1",
|
||||||
"express-session": "^1.18.2",
|
"express-session": "^1.18.2",
|
||||||
"sqlite3": "^5.1.7"
|
"sqlite3": "^5.1.7"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 238 KiB After Width: | Height: | Size: 238 KiB |
111
public/resto.css
Normal file
111
public/resto.css
Normal file
|
|
@ -0,0 +1,111 @@
|
||||||
|
main {
|
||||||
|
text-align: left !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.restaurant-page {
|
||||||
|
width: 90%;
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: flex-start;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.restaurant-info h1 {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heart {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: #ececec;
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
font-size: 20px;
|
||||||
|
margin-left: 8px;
|
||||||
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);
|
||||||
|
}
|
||||||
|
|
||||||
|
.rating {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin: 10px 0;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
background: #999;
|
||||||
|
border: none;
|
||||||
|
color: white;
|
||||||
|
padding: 5px 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-placeholder {
|
||||||
|
width: 200px;
|
||||||
|
height: 200px;
|
||||||
|
background: #eee;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-image {
|
||||||
|
width: 100%;
|
||||||
|
height: 200px;
|
||||||
|
background: #ccc;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
background: #f9f9f9;
|
||||||
|
padding: 15px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gallery {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gallery-item {
|
||||||
|
width: 32%;
|
||||||
|
height: 150px;
|
||||||
|
background: #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reviews-title {
|
||||||
|
background: #eee;
|
||||||
|
padding: 10px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reviews {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 20px;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.review {
|
||||||
|
background: #f5f5f5;
|
||||||
|
padding: 15px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.review h3 {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.review-rating div {
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
294
public/style.css
Normal file
294
public/style.css
Normal file
|
|
@ -0,0 +1,294 @@
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
background: linear-gradient(135deg, #f8f6fc 0%, #fffbe7 100%);
|
||||||
|
color: #7a5c1e;
|
||||||
|
}
|
||||||
|
|
||||||
|
header {
|
||||||
|
background: linear-gradient(90deg, #8e68aa 60%, #cb8d37 100%);
|
||||||
|
color: white;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 10px 20px;
|
||||||
|
box-shadow: 0 2px 8px rgba(140, 104, 170, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
header h1 {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-bar {
|
||||||
|
flex-grow: 1;
|
||||||
|
margin: 0 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-bar input {
|
||||||
|
width: 100%;
|
||||||
|
padding: 5px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account {
|
||||||
|
background: linear-gradient(90deg, #cb8d37 60%, #8e68aa 100%);
|
||||||
|
padding: 6px 12px;
|
||||||
|
border-radius: 4px;
|
||||||
|
color: white;
|
||||||
|
cursor: pointer;
|
||||||
|
font-weight: bold;
|
||||||
|
transition: background 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account:hover {
|
||||||
|
background: #a97b2c;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
padding: 20px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
main h2 {
|
||||||
|
font-size: 2rem;
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sections {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 30px;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section h3 {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cards {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
background: #ddd;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 15px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-info {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-info h4 {
|
||||||
|
margin: 0 0 5px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-photo {
|
||||||
|
background: #8e68aa;
|
||||||
|
width: 120px;
|
||||||
|
height: 80px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
background: #8e68aa;
|
||||||
|
text-align: center;
|
||||||
|
padding: 10px;
|
||||||
|
margin-top: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer a {
|
||||||
|
margin: 0 10px;
|
||||||
|
text-decoration: none;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Header layout amélioré */
|
||||||
|
.main-header {
|
||||||
|
background: linear-gradient(90deg, #8e68aa 60%, #cb8d37 100%);
|
||||||
|
color: white;
|
||||||
|
box-shadow: 0 2px 8px rgba(140, 104, 170, 0.08);
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-content {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 10px 20px;
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
width: 100%;
|
||||||
|
gap: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-left {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
min-width: 220px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-left h1 {
|
||||||
|
font-size: 1.4rem;
|
||||||
|
margin: 0 0 0 10px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-center {
|
||||||
|
flex: 1 1 0;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-right {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
min-width: 260px;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-bar {
|
||||||
|
flex: 1 1 300px;
|
||||||
|
max-width: 700px;
|
||||||
|
margin: 0 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-bar input {
|
||||||
|
width: 100%;
|
||||||
|
padding: 7px 12px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
background: linear-gradient(90deg, #cb8d37 60%, #8e68aa 100%);
|
||||||
|
padding: 6px 12px;
|
||||||
|
border-radius: 4px;
|
||||||
|
color: white;
|
||||||
|
font-weight: bold;
|
||||||
|
transition: background 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account a {
|
||||||
|
color: white;
|
||||||
|
text-decoration: none;
|
||||||
|
margin-left: 8px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account a:first-child {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account:hover {
|
||||||
|
background: #a97b2c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.social-buttons {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-social {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 8px 18px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 30px;
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 600;
|
||||||
|
cursor: pointer;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.07);
|
||||||
|
transition: transform 0.1s, box-shadow 0.2s;
|
||||||
|
outline: none;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-social:active {
|
||||||
|
transform: scale(0.97);
|
||||||
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-google {
|
||||||
|
background: #fff;
|
||||||
|
color: #444;
|
||||||
|
border: 1px solid #e0e0e0;
|
||||||
|
}
|
||||||
|
.btn-google:hover {
|
||||||
|
background: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-discord {
|
||||||
|
background: #5865f2;
|
||||||
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
.btn-discord:hover {
|
||||||
|
background: #4752c4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-social {
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
height: 40px;
|
||||||
|
width: 40px;
|
||||||
|
border-radius: 8px;
|
||||||
|
margin-right: 10px;
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Responsive */
|
||||||
|
@media (max-width: 900px) {
|
||||||
|
.header-content {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: stretch;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
.header-center {
|
||||||
|
justify-content: stretch;
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
.header-right {
|
||||||
|
justify-content: center;
|
||||||
|
min-width: 0;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
.search-bar {
|
||||||
|
min-width: 180px;
|
||||||
|
max-width: 100%;
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
.account {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
.sections {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
.social-buttons {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
34
routes.js
34
routes.js
|
|
@ -6,6 +6,11 @@ router.get('/', (req, res) => {
|
||||||
res.render('index', { user: req.session.user });
|
res.render('index', { user: req.session.user });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Page resto
|
||||||
|
router.get('/resto/:id', (req, res) => {
|
||||||
|
res.render('resto', { user: req.session.user });
|
||||||
|
});
|
||||||
|
|
||||||
// Auth Discord
|
// Auth Discord
|
||||||
router.get('/auth/discord', (req, res) => {
|
router.get('/auth/discord', (req, res) => {
|
||||||
const clientId = '1410258710407811082';
|
const clientId = '1410258710407811082';
|
||||||
|
|
@ -17,6 +22,17 @@ router.get('/auth/discord', (req, res) => {
|
||||||
|
|
||||||
router.get('/auth/discord/callback', require('./modules/auth/discord').handleDiscordAuth);
|
router.get('/auth/discord/callback', require('./modules/auth/discord').handleDiscordAuth);
|
||||||
|
|
||||||
|
// Auth Google
|
||||||
|
router.get('/auth/google', (req, res) => {
|
||||||
|
const clientId = '71229835507-9413gbpdamv2qbcb2ov8oda2oqgcsk8q.apps.googleusercontent.com';
|
||||||
|
const redirectUri = 'http://localhost:3000/auth/google/callback';
|
||||||
|
const scope = 'https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile';
|
||||||
|
const googleAuthUrl = `https://accounts.google.com/o/oauth2/auth?client_id=${clientId}&redirect_uri=${encodeURIComponent(redirectUri)}&response_type=code&scope=${encodeURIComponent(scope)}`;
|
||||||
|
res.redirect(googleAuthUrl);
|
||||||
|
});
|
||||||
|
|
||||||
|
router.get('/auth/google/callback', require('./modules/auth/google').handleGoogleAuth);
|
||||||
|
|
||||||
// Déconnexion
|
// Déconnexion
|
||||||
router.get('/logout', (req, res) => {
|
router.get('/logout', (req, res) => {
|
||||||
req.session.destroy((err) => {
|
req.session.destroy((err) => {
|
||||||
|
|
@ -28,22 +44,4 @@ router.get('/logout', (req, res) => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Infos resto
|
|
||||||
router.get('/restaurants/:id', async (req, res) => {
|
|
||||||
const id = req.params.id;
|
|
||||||
try {
|
|
||||||
const restaurant = await db.get(`SELECT * FROM restaurants WHERE id = ?`, [id]);
|
|
||||||
if (!restaurant) {
|
|
||||||
res.status(404).send('Restaurant non trouvé');
|
|
||||||
} else {
|
|
||||||
res.render('restaurant', { restaurant });
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
res.status(500).send('Erreur lors de la récupération des informations du restaurant');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
150
views/index.ejs
150
views/index.ejs
|
|
@ -1,76 +1,78 @@
|
||||||
<!DOCTYPE html>
|
<div style="display:flex; justify-content: center; align-items: center;">
|
||||||
<html lang="fr">
|
<h2 style="margin-right: 20px;">L’EPICURIEN</h2>
|
||||||
<head>
|
<img style="height: 70px; width: 70px; object-fit: contain;" alt="Logo de l'entreprise" src="logo.png" onerror="this.onerror=null;this.src='https://via.placeholder.com/70?text=Logo';" />
|
||||||
<meta charset="UTF-8">
|
</div>
|
||||||
<title>Diagramme Radar avec Chart.js</title>
|
<div class="sections">
|
||||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
<!-- Restaurants proches -->
|
||||||
</head>
|
<div class="section">
|
||||||
<body>
|
<h3>Restaurants les plus proches</h3>
|
||||||
<div style="width: 35%; margin: 0 auto;">
|
<div class="cards">
|
||||||
<canvas id="radarChart"></canvas>
|
<a href="/resto/1" style="text-decoration:none; color:inherit;">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-info">
|
||||||
|
<h4>Le Canard Toulousain</h4>
|
||||||
|
<p>12 Rue du Capitole, 31000 Toulouse</p>
|
||||||
|
<p>Avis général</p>
|
||||||
|
</div>
|
||||||
|
<img alt="Photo du restaurant" src="https://source.unsplash.com/100x100/?restaurant=1" />
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<a href="/resto/2" style="text-decoration:none; color:inherit;">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-info">
|
||||||
|
<h4>Chez Pépé Louis</h4>
|
||||||
|
<p>8 Avenue de la Garonne, 31000 Toulouse</p>
|
||||||
|
<p>Avis général</p>
|
||||||
|
</div>
|
||||||
|
<img alt="Photo du restaurant" src="https://source.unsplash.com/100x100/?restaurant=2" />
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<a href="/resto/3" style="text-decoration:none; color:inherit;">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-info">
|
||||||
|
<h4>La Table Rose</h4>
|
||||||
|
<p>25 Rue Saint-Rome, 31000 Toulouse</p>
|
||||||
|
<p>Avis général</p>
|
||||||
|
</div>
|
||||||
|
<img alt="Photo du restaurant" src="https://source.unsplash.com/100x100/?restaurant=3" />
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<!-- Restaurants populaires -->
|
||||||
const ctx = document.getElementById('radarChart').getContext('2d');
|
<div class="section">
|
||||||
const radarChart = new Chart(ctx, {
|
<h3>Restaurants les plus populaires</h3>
|
||||||
type: 'radar',S,
|
<div class="cards">
|
||||||
data: {
|
<a href="/resto/4" style="text-decoration:none; color:inherit;">
|
||||||
labels: ['Qualité des plats', 'Ambiance', 'Accessibilité', 'Service', 'Tradition'],
|
<div class="card">
|
||||||
datasets: [
|
<div class="card-info">
|
||||||
{
|
<h4>Bistro Occitan</h4>
|
||||||
label: 'Moyenne des notes',
|
<p>5 Place Wilson, 31000 Toulouse</p>
|
||||||
data: [4.7, 4.6, 4.4, 4.3, 4.8],
|
<p>Avis général</p>
|
||||||
fill: true,
|
</div>
|
||||||
backgroundColor: 'rgba(255, 215, 0, 0.2)',
|
<img alt="Photo du restaurant" src="https://source.unsplash.com/100x100/?restaurant=4" />
|
||||||
borderColor: 'rgb(255, 215, 0)',
|
</div>
|
||||||
pointBackgroundColor: 'rgb(255, 215, 0)',
|
</a>
|
||||||
pointBorderColor: '#fff',
|
<a href="/resto/5" style="text-decoration:none; color:inherit;">
|
||||||
pointHoverBackgroundColor: '#fff',
|
<div class="card">
|
||||||
pointHoverBorderColor: 'rgb(255, 215, 0)',
|
<div class="card-info">
|
||||||
pointStyle: 'circle',
|
<h4>L’Assiette du Sud</h4>
|
||||||
pointRadius: 5,
|
<p>17 Allée Jean Jaurès, 31000 Toulouse</p>
|
||||||
pointRotation: 0,
|
<p>Avis général</p>
|
||||||
},
|
</div>
|
||||||
]
|
<img alt="Photo du restaurant" src="https://source.unsplash.com/100x100/?restaurant=5" />
|
||||||
},
|
</div>
|
||||||
options: {
|
</a>
|
||||||
plugins: {
|
<a href="/resto/6" style="text-decoration:none; color:inherit;">
|
||||||
legend: {
|
<div class="card">
|
||||||
display: false
|
<div class="card-info">
|
||||||
},
|
<h4>Le Petit Cassoulet</h4>
|
||||||
tooltip: {
|
<p>3 Rue des Filatiers, 31000 Toulouse</p>
|
||||||
callbacks: {
|
<p>Avis général</p>
|
||||||
label: function(context) {
|
</div>
|
||||||
let label = context.dataset.label || '';
|
<img alt="Photo du restaurant" src="https://source.unsplash.com/100x100/?restaurant=6" />
|
||||||
if (label) {
|
</div>
|
||||||
label += ': ';
|
</a>
|
||||||
}
|
</div>
|
||||||
label += context.formattedValue;
|
</div>
|
||||||
return label;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
scales: {
|
|
||||||
r: {
|
|
||||||
max: 5,
|
|
||||||
min: 0,
|
|
||||||
ticks: {
|
|
||||||
stepSize: 1,
|
|
||||||
callback: function(value, index, values) {
|
|
||||||
return value.toFixed(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
elements: {
|
|
||||||
line: {
|
|
||||||
borderWidth: 3
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
209
views/index.html
209
views/index.html
|
|
@ -1,209 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="fr">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<title>L'EPICURIEN</title>
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
font-family: Arial, sans-serif;
|
|
||||||
background: #fff;
|
|
||||||
color: #cb8d37;
|
|
||||||
}
|
|
||||||
|
|
||||||
header {
|
|
||||||
background: #8e68aa;
|
|
||||||
color: white;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 10px 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
header h1 {
|
|
||||||
font-size: 1.2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-bar {
|
|
||||||
flex-grow: 1;
|
|
||||||
margin: 0 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-bar input {
|
|
||||||
width: 100%;
|
|
||||||
padding: 5px;
|
|
||||||
border: none;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.account {
|
|
||||||
background: #666;
|
|
||||||
padding: 6px 12px;
|
|
||||||
border-radius: 4px;
|
|
||||||
color: white;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
main {
|
|
||||||
padding: 20px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
main h2 {
|
|
||||||
font-size: 2rem;
|
|
||||||
margin: 10px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sections {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr 1fr;
|
|
||||||
gap: 30px;
|
|
||||||
margin-top: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.section h3 {
|
|
||||||
margin-bottom: 15px;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cards {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card {
|
|
||||||
background: #ddd;
|
|
||||||
border-radius: 8px;
|
|
||||||
padding: 15px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.card-info {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card-info h4 {
|
|
||||||
margin: 0 0 5px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card-photo {
|
|
||||||
background: #8e68aa;
|
|
||||||
width: 120px;
|
|
||||||
height: 80px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
font-size: 0.9rem;
|
|
||||||
color: #555;
|
|
||||||
}
|
|
||||||
|
|
||||||
footer {
|
|
||||||
background: #8e68aa;
|
|
||||||
text-align: center;
|
|
||||||
padding: 10px;
|
|
||||||
margin-top: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
footer a {
|
|
||||||
margin: 0 10px;
|
|
||||||
text-decoration: none;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<!-- HEADER -->
|
|
||||||
<header>
|
|
||||||
<h1>L'EPICURIEN</h1>
|
|
||||||
<div class="search-bar">
|
|
||||||
<input type="text" placeholder="Rechercher un restaurant" />
|
|
||||||
</div>
|
|
||||||
<div class="account">Mon compte</div>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<!-- MAIN CONTENT -->
|
|
||||||
<main>
|
|
||||||
<div style="display:flex; justify-content: center; align-items: center ;">
|
|
||||||
<h2>L’EPICURIEN</h2><img style="height: 70px; width: 70px;" alt="Logo de l'entreprise" src="logo.png" />
|
|
||||||
</div>
|
|
||||||
<div class="sections">
|
|
||||||
<!-- Restaurants proches -->
|
|
||||||
<div class="section">
|
|
||||||
<h3>Restaurants les plus proches</h3>
|
|
||||||
<div class="cards">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-info">
|
|
||||||
<h4>Nom restaurant</h4>
|
|
||||||
<p>Adresse</p>
|
|
||||||
<p>Avis général</p>
|
|
||||||
</div>
|
|
||||||
<img alt="Photo du restaurant" src="" />
|
|
||||||
</div>
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-info">
|
|
||||||
<h4>Nom restaurant</h4>
|
|
||||||
<p>Adresse</p>
|
|
||||||
<p>Avis général</p>
|
|
||||||
</div>
|
|
||||||
<img alt="Photo du restaurant" src="" />
|
|
||||||
</div>
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-info">
|
|
||||||
<h4>Nom restaurant</h4>
|
|
||||||
<p>Adresse</p>
|
|
||||||
<p>Avis général</p>
|
|
||||||
</div>
|
|
||||||
<img alt="Photo du restaurant" src="" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Restaurants populaires -->
|
|
||||||
<div class="section">
|
|
||||||
<h3>Restaurants les plus populaires</h3>
|
|
||||||
<div class="cards">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-info">
|
|
||||||
<h4>Nom restaurant</h4>
|
|
||||||
<p>Adresse</p>
|
|
||||||
<p>Avis général</p>
|
|
||||||
</div>
|
|
||||||
<img alt="Photo du restaurant" src="" />
|
|
||||||
</div>
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-info">
|
|
||||||
<h4>Nom restaurant</h4>
|
|
||||||
<p>Adresse</p>
|
|
||||||
<p>Avis général</p>
|
|
||||||
</div>
|
|
||||||
<img alt="Photo du restaurant" src="" />
|
|
||||||
</div>
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-info">
|
|
||||||
<h4>Nom restaurant</h4>
|
|
||||||
<p>Adresse</p>
|
|
||||||
<p>Avis général</p>
|
|
||||||
</div>
|
|
||||||
<img alt="Photo du restaurant" src="" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
|
|
||||||
<!-- FOOTER -->
|
|
||||||
<footer>
|
|
||||||
<a href="#">Mentions légales</a> |
|
|
||||||
<a href="#">Politique de confidentialité</a> |
|
|
||||||
<a href="#">CGU</a>
|
|
||||||
</footer>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title><%= restaurant.nom %></title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1><%= restaurant.nom %></h1>
|
|
||||||
<p><%= restaurant.description %></p>
|
|
||||||
<p>Adresse : <%= restaurant.adresse %></p>
|
|
||||||
<h2>Menu</h2>
|
|
||||||
<ul>
|
|
||||||
<% restaurant.menu.forEach((plat) => { %>
|
|
||||||
<li><%= plat %></li>
|
|
||||||
<% }); %>
|
|
||||||
</ul>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
60
views/layout.ejs
Normal file
60
views/layout.ejs
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="fr">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<meta name="description" content="L'EPICURIEN - Découvrez et partagez les meilleurs restaurants autour de vous." />
|
||||||
|
<meta name="author" content="L'EPICURIEN Team" />
|
||||||
|
<title>L'EPICURIEN</title>
|
||||||
|
<link rel="stylesheet" href="/style.css" />
|
||||||
|
<link rel="icon" href="/logo.png" type="image/png" />
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<header class="main-header">
|
||||||
|
<div class="header-content">
|
||||||
|
<div class="header-left">
|
||||||
|
<a href="/" class="logo-link">
|
||||||
|
<img src="/logo.png" alt="Logo L'EPICURIEN" class="logo" />
|
||||||
|
</a>
|
||||||
|
<a href="/" class="">
|
||||||
|
<h1 style="text-decoration: none; color: white;">L'EPICURIEN</h1>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="header-center">
|
||||||
|
<div class="search-bar">
|
||||||
|
<input type="text" placeholder="Rechercher un restaurant" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="header-right">
|
||||||
|
<div class="account">
|
||||||
|
<% if (user) { %>
|
||||||
|
<a href="/logout" style="margin-left:12px;">Déconnexion</a>
|
||||||
|
<% } else { %>
|
||||||
|
<div class="social-buttons">
|
||||||
|
<a href="/auth/google" class="btn-social btn-google">
|
||||||
|
<img src="https://cdn.jsdelivr.net/gh/devicons/devicon/icons/google/google-original.svg" alt="Google" class="icon-social"/>
|
||||||
|
</a>
|
||||||
|
<a href="/auth/discord" class="btn-social btn-discord">
|
||||||
|
<img src="https://cdn.jsdelivr.net/gh/edent/SuperTinyIcons/images/svg/discord.svg" alt="Discord" class="icon-social"/>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<% } %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<%- body %>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<footer class="main-footer">
|
||||||
|
<a href="#">Mentions légales</a> |
|
||||||
|
<a href="#">Politique de confidentialité</a> |
|
||||||
|
<a href="#">CGU</a>
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
166
views/resto.ejs
Normal file
166
views/resto.ejs
Normal file
|
|
@ -0,0 +1,166 @@
|
||||||
|
<link rel="stylesheet" href="/resto.css" />
|
||||||
|
|
||||||
|
<div class="restaurant-page">
|
||||||
|
<!-- En-tête restaurant -->
|
||||||
|
<div class="header">
|
||||||
|
<div class="restaurant-info">
|
||||||
|
<h1>
|
||||||
|
Nom restaurant
|
||||||
|
<span class="heart">
|
||||||
|
<% if (user) { %>
|
||||||
|
❤️
|
||||||
|
<% } else { %>
|
||||||
|
🤍
|
||||||
|
<% } %>
|
||||||
|
</span>
|
||||||
|
</h1>
|
||||||
|
<p class="address">Adresse</p>
|
||||||
|
<div class="rating">
|
||||||
|
<span>⭐️⭐️⭐️⭐️⭐️</span>
|
||||||
|
<a href="#avis" class="btn">Voir tous les avis</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="chart">
|
||||||
|
<div class="chart-placeholder">
|
||||||
|
<canvas id="radarChart"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Image principale -->
|
||||||
|
<div class="main-image"></div>
|
||||||
|
|
||||||
|
<!-- Description -->
|
||||||
|
<div class="description">
|
||||||
|
<p>
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
|
||||||
|
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
|
||||||
|
veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
|
||||||
|
commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
|
||||||
|
velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
|
||||||
|
occaecat cupidatat
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Galerie -->
|
||||||
|
<div class="gallery">
|
||||||
|
<div class="gallery-item"></div>
|
||||||
|
<div class="gallery-item"></div>
|
||||||
|
<div class="gallery-item"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Avis -->
|
||||||
|
<h2 class="reviews-title" id="avis">Avis</h2>
|
||||||
|
<div class="reviews">
|
||||||
|
<div class="review">
|
||||||
|
<h3>Titre avis</h3>
|
||||||
|
<p>
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
|
||||||
|
eiusmod tempor incididunt ut labore et dolore magna aliqua.
|
||||||
|
</p>
|
||||||
|
<div class="review-rating">
|
||||||
|
<div>Qualité des plats ⭐⭐⭐⭐⭐</div>
|
||||||
|
<div>Service ⭐⭐⭐⭐⭐</div>
|
||||||
|
<div>Ambiance ⭐⭐⭐⭐⭐</div>
|
||||||
|
<div>Accessibilité ⭐⭐⭐⭐⭐</div>
|
||||||
|
<div>Tarif ⭐⭐⭐⭐⭐</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="review">
|
||||||
|
<h3>Titre avis</h3>
|
||||||
|
<p>
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
|
||||||
|
eiusmod tempor incididunt ut labore et dolore magna aliqua.
|
||||||
|
</p>
|
||||||
|
<div class="review-rating">
|
||||||
|
<div>Qualité des plats ⭐⭐⭐⭐⭐</div>
|
||||||
|
<div>Service ⭐⭐⭐⭐⭐</div>
|
||||||
|
<div>Ambiance ⭐⭐⭐⭐⭐</div>
|
||||||
|
<div>Accessibilité ⭐⭐⭐⭐⭐</div>
|
||||||
|
<div>Tarif ⭐⭐⭐⭐⭐</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="review">
|
||||||
|
<h3>Titre avis</h3>
|
||||||
|
<p>
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
|
||||||
|
eiusmod tempor incididunt ut labore et dolore magna aliqua.
|
||||||
|
</p>
|
||||||
|
<div class="review-rating">
|
||||||
|
<div>Qualité des plats ⭐⭐⭐⭐⭐</div>
|
||||||
|
<div>Service ⭐⭐⭐⭐⭐</div>
|
||||||
|
<div>Ambiance ⭐⭐⭐⭐⭐</div>
|
||||||
|
<div>Accessibilité ⭐⭐⭐⭐⭐</div>
|
||||||
|
<div>Tarif ⭐⭐⭐⭐⭐</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
const ctx = document.getElementById('radarChart').getContext('2d');
|
||||||
|
const radarChart = new Chart(ctx, {
|
||||||
|
type: 'radar',
|
||||||
|
data: {
|
||||||
|
labels: ['Qualité des plats', 'Ambiance', 'Accessibilité', 'Service', 'Tradition'],
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
label: 'Moyenne des notes',
|
||||||
|
data: [4.7, 4.6, 4.4, 4.3, 4.8],
|
||||||
|
fill: true,
|
||||||
|
backgroundColor: 'rgba(255,215, 0, 0.2)',
|
||||||
|
borderColor: 'rgb(255,215, 0, 1)',
|
||||||
|
pointBackgroundColor: 'rgb(255,215, 0)',
|
||||||
|
pointBorderColor: '#fff',
|
||||||
|
pointHoverBackgroundColor: '#fff',
|
||||||
|
pointHoverBorderColor: 'rgb(255,215, 0)',
|
||||||
|
pointStyle: 'circle',
|
||||||
|
pointRadius: 5,
|
||||||
|
pointRotation: 0,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
plugins: {
|
||||||
|
legend: {
|
||||||
|
display: false
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
callbacks: {
|
||||||
|
label: function(context) {
|
||||||
|
let label = context.dataset.label || '';
|
||||||
|
if (label) {
|
||||||
|
label += ': ';
|
||||||
|
}
|
||||||
|
label += context.formattedValue;
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
scales: {
|
||||||
|
r: {
|
||||||
|
max: 5,
|
||||||
|
min: 0,
|
||||||
|
ticks: {
|
||||||
|
stepSize: 1,
|
||||||
|
display: false,
|
||||||
|
callback: function(value, index, values) {
|
||||||
|
return value.toFixed(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
elements: {
|
||||||
|
line: {
|
||||||
|
borderWidth: 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
Loading…
Add table
Reference in a new issue