comment #9
@ -67,4 +67,35 @@ router.post('/delete/:id', async (req, res) => {
|
|||||||
res.redirect('/');
|
res.redirect('/');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
router.get('/image/:id', async (req, res) => {
|
||||||
|
const imageId = req.params.id;
|
||||||
|
const result = await pool.query('SELECT * FROM images WHERE id = $1', [imageId]);
|
||||||
|
const image = result.rows[0];
|
||||||
|
|
||||||
|
const commentsResult = await pool.query(
|
||||||
|
'SELECT * FROM comments WHERE image_id = $1 ORDER BY created_at ASC',
|
||||||
|
[imageId]
|
||||||
|
);
|
||||||
|
const comments = commentsResult.rows;
|
||||||
|
|
||||||
|
res.render('image', {
|
||||||
|
user: req.user,
|
||||||
|
image,
|
||||||
|
comments
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
router.post('/image/:id/comment', async (req, res) => {
|
||||||
|
const imageId = req.params.id;
|
||||||
|
const author = req.user ? req.user.displayName : 'Anonym';
|
||||||
|
const content = req.body.content;
|
||||||
|
|
||||||
|
await pool.query(
|
||||||
|
'INSERT INTO comments (image_id, author, content) VALUES ($1, $2, $3)',
|
||||||
|
[imageId, author, content]
|
||||||
|
);
|
||||||
|
|
||||||
|
res.redirect(`/image/${imageId}`);
|
||||||
|
});
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
|
|||||||
@ -9,16 +9,28 @@ import { fileURLToPath } from 'url';
|
|||||||
|
|
||||||
import pool from './db.js';
|
import pool from './db.js';
|
||||||
|
|
||||||
await pool.query(`
|
const initDB = async () => {
|
||||||
CREATE TABLE IF NOT EXISTS images (
|
await pool.query(`
|
||||||
id SERIAL PRIMARY KEY,
|
CREATE TABLE IF NOT EXISTS images (
|
||||||
filename TEXT NOT NULL,
|
id SERIAL PRIMARY KEY,
|
||||||
title TEXT NOT NULL,
|
filename TEXT NOT NULL,
|
||||||
description TEXT NOT NULL,
|
title TEXT NOT NULL,
|
||||||
uploader TEXT,
|
description TEXT NOT NULL,
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
uploader TEXT,
|
||||||
);
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
`);
|
);
|
||||||
|
`);
|
||||||
|
await pool.query(`
|
||||||
|
CREATE TABLE IF NOT EXISTS comments (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
image_id INTEGER REFERENCES images(id) ON DELETE CASCADE,
|
||||||
|
author TEXT,
|
||||||
|
content TEXT NOT NULL,
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
`);
|
||||||
|
};
|
||||||
|
initDB();
|
||||||
|
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
|
|
||||||
|
|||||||
37
backend/views/image.ejs
Normal file
37
backend/views/image.ejs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<title><%= image.title %></title>
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@1/css/pico.min.css" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<main class="container">
|
||||||
|
<h2><%= image.title %></h2>
|
||||||
|
<p><%= image.description %></p>
|
||||||
|
<img src="/uploads/<%= image.filename %>" alt="" style="max-width: 100%;" />
|
||||||
|
<p>Hochgeladen von <strong><%= image.uploader %></strong></p>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<h3>Kommentare</h3>
|
||||||
|
<ul>
|
||||||
|
<% comments.forEach(comment => { %>
|
||||||
|
<li><strong><%= comment.author %></strong>: <%= comment.content %></li>
|
||||||
|
<% }) %>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<% if (user) { %>
|
||||||
|
<form method="POST" action="/image/<%= image.id %>/comment">
|
||||||
|
<input type="text" name="content" placeholder="Kommentar schreiben..." required />
|
||||||
|
<button type="submit">Senden</button>
|
||||||
|
</form>
|
||||||
|
<% } else { %>
|
||||||
|
<p>Bitte <a href="/auth/google">einloggen</a>, um zu kommentieren.</p>
|
||||||
|
<% } %>
|
||||||
|
|
||||||
|
<a href="/" role="button">Zurück zur Galerie</a>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -33,7 +33,9 @@
|
|||||||
<h3><%= img.title %></h3>
|
<h3><%= img.title %></h3>
|
||||||
<p><%= img.description %></p>
|
<p><%= img.description %></p>
|
||||||
<figure>
|
<figure>
|
||||||
<img src="<%= img.path %>" alt="<%= img.title %>" style="max-width: 100%; border-radius: 8px;" />
|
<a href="/image/<%= img.id %>">
|
||||||
|
<img src="<%= img.path %>" alt="<%= img.title %>" style="max-width: 100%; border-radius: 8px;" />
|
||||||
|
</a>
|
||||||
<figcaption>Hochgeladen von <strong><%= img.uploader %></strong></figcaption>
|
<figcaption>Hochgeladen von <strong><%= img.uploader %></strong></figcaption>
|
||||||
</figure>
|
</figure>
|
||||||
<% if (user && (user.displayName === img.uploader || user.emails[0].value === 'DEINE_ADMIN_MAIL@deine-domain.de')) { %>
|
<% if (user && (user.displayName === img.uploader || user.emails[0].value === 'DEINE_ADMIN_MAIL@deine-domain.de')) { %>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user