Compare commits

..

No commits in common. "master" and "features/info-restos" have entirely different histories.

15 changed files with 346 additions and 742 deletions

10
app.js
View file

@ -1,10 +1,11 @@
const SESSION_SECRET = "your_session_secret";
// ...existing code...
const express = require('express');
const session = require('express-session');
const initDb = require('./db_init');
const path = require('path');
const expressLayouts = require('express-ejs-layouts');
const routes = require('./routes');
@ -33,13 +34,6 @@ app.use(session({
app.set('view engine', 'ejs');
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
app.use('/', routes);

Binary file not shown.

View file

@ -22,4 +22,25 @@ 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;

View file

@ -1,14 +1,13 @@
const axios = require("axios");
const { getUserByGId } = require('../users/getUsers');
const { getUserByDId } = require('../users/getUsers');
const { postUser } = require('../users/postUsers');
const CLIEN_ID = "71229835507-9413gbpdamv2qbcb2ov8oda2oqgcsk8q.apps.googleusercontent.com";
const GOOGLE_SECRET = "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";
const GOOGLE_REDIRECT_URI = "http://localhost:3000/auth/google/callback";
const REDIRECT_URI = "http://localhost:3000/auth/google/callback";
exports.handleGoogleAuth = async (req, res) => {
const code = req.query.code;
exports.handleGoogleAuth = async (code, res) => {
if (!code) return res.status(400).json({ error: "Code de validation manquant" });
try {
const params = new URLSearchParams();
@ -42,6 +41,8 @@ exports.handleGoogleAuth = async (req, res) => {
const newUser = {
username: userData.name || userData.email,
google_id: userData.id,
email: userData.email,
avatar: userData.picture || null,
};
savedUser = await postUser(newUser);
}

6
package-lock.json generated
View file

@ -12,7 +12,6 @@
"axios": "^1.11.0",
"ejs": "^3.1.10",
"express": "^5.1.0",
"express-ejs-layouts": "^2.5.1",
"express-session": "^1.18.2",
"sqlite3": "^5.1.7"
}
@ -709,11 +708,6 @@
"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": {
"version": "1.18.2",
"resolved": "https://registry.npmjs.org/express-session/-/express-session-1.18.2.tgz",

View file

@ -18,7 +18,6 @@
"axios": "^1.11.0",
"ejs": "^3.1.10",
"express": "^5.1.0",
"express-ejs-layouts": "^2.5.1",
"express-session": "^1.18.2",
"sqlite3": "^5.1.7"
}

View file

@ -1,111 +0,0 @@
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;
}

View file

@ -1,294 +0,0 @@
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;
}
}

View file

@ -6,11 +6,6 @@ router.get('/', (req, res) => {
res.render('index', { user: req.session.user });
});
// Page resto
router.get('/resto/:id', (req, res) => {
res.render('resto', { user: req.session.user });
});
// Auth Discord
router.get('/auth/discord', (req, res) => {
const clientId = '1410258710407811082';
@ -22,17 +17,6 @@ router.get('/auth/discord', (req, res) => {
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
router.get('/logout', (req, res) => {
req.session.destroy((err) => {
@ -44,4 +28,22 @@ 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;

View file

@ -1,78 +1,76 @@
<div style="display:flex; justify-content: center; align-items: center;">
<h2 style="margin-right: 20px;">LEPICURIEN</h2>
<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';" />
</div>
<div class="sections">
<!-- Restaurants proches -->
<div class="section">
<h3>Restaurants les plus proches</h3>
<div class="cards">
<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>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Diagramme Radar avec Chart.js</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>
<div style="width: 35%; margin: 0 auto;">
<canvas id="radarChart"></canvas>
</div>
<!-- Restaurants populaires -->
<div class="section">
<h3>Restaurants les plus populaires</h3>
<div class="cards">
<a href="/resto/4" style="text-decoration:none; color:inherit;">
<div class="card">
<div class="card-info">
<h4>Bistro Occitan</h4>
<p>5 Place Wilson, 31000 Toulouse</p>
<p>Avis général</p>
</div>
<img alt="Photo du restaurant" src="https://source.unsplash.com/100x100/?restaurant=4" />
</div>
</a>
<a href="/resto/5" style="text-decoration:none; color:inherit;">
<div class="card">
<div class="card-info">
<h4>LAssiette du Sud</h4>
<p>17 Allée Jean Jaurès, 31000 Toulouse</p>
<p>Avis général</p>
</div>
<img alt="Photo du restaurant" src="https://source.unsplash.com/100x100/?restaurant=5" />
</div>
</a>
<a href="/resto/6" style="text-decoration:none; color:inherit;">
<div class="card">
<div class="card-info">
<h4>Le Petit Cassoulet</h4>
<p>3 Rue des Filatiers, 31000 Toulouse</p>
<p>Avis général</p>
</div>
<img alt="Photo du restaurant" src="https://source.unsplash.com/100x100/?restaurant=6" />
</div>
</a>
</div>
</div>
<script>
const ctx = document.getElementById('radarChart').getContext('2d');
const radarChart = new Chart(ctx, {
type: 'radar',S,
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)',
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,
callback: function(value, index, values) {
return value.toFixed(1);
}
}
}
},
elements: {
line: {
borderWidth: 3
}
}
}
});
</script>
</body>
</html>

209
views/index.html Normal file
View file

@ -0,0 +1,209 @@
<!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>LEPICURIEN</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>

17
views/infos.ejs Normal file
View file

@ -0,0 +1,17 @@
<!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>

View file

@ -1,60 +0,0 @@
<!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>

View file

Before

Width:  |  Height:  |  Size: 238 KiB

After

Width:  |  Height:  |  Size: 238 KiB

View file

@ -1,166 +0,0 @@
<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>