more code

This commit is contained in:
Mike 2024-12-27 22:17:36 -05:00
parent e07590d6e5
commit 90769c9bf1
16 changed files with 1710 additions and 63 deletions

1
.gitignore vendored
View file

@ -1,3 +1,4 @@
*.db
# Logs # Logs
logs logs
*.log *.log

View file

@ -1,6 +1,6 @@
FROM node:23-alpine FROM node:23-alpine
COPY package*.json /app/package*.json COPY package.json package-lock.json /app
WORKDIR /app WORKDIR /app
@ -12,6 +12,8 @@ EXPOSE 3000
USER nobody USER nobody
CMD ["node", "src/app.js"] ENTRYPOINT ["node"]
CMD ["src/app.js"]

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,14 @@
{ {
"name": "Odin - Message Board",
"version": "0.1.0",
"dependencies": { "dependencies": {
"ejs": "^3.1.10", "ejs": "^3.1.10",
"express": "^4.21.2" "express": "^4.21.2",
"express-validator": "^7.2.0",
"sqlite3": "^5.1.7"
},
"scripts": {
"seed_db": "node $PWD/src/db/seedDb.js",
"start": "node --watch src/app.js"
} }
} }

View file

@ -6,6 +6,7 @@ const port = 3000;
const { indexRouter } = require("./routes/indexRouter"); const { indexRouter } = require("./routes/indexRouter");
//const { msgRouter } = require("./routes/msgRouter"); //const { msgRouter } = require("./routes/msgRouter");
//
app.set("views", path.join(__dirname, "views")); app.set("views", path.join(__dirname, "views"));
app.set("view engine", "ejs"); app.set("view engine", "ejs");
@ -15,8 +16,15 @@ app.use(express.static(assetsPath));
app.use(express.urlencoded({ extended: true })); app.use(express.urlencoded({ extended: true }));
app.use((req, res, next) => {
req.time = new Date(Date.now()).toISOString();
console.log(req.time, req.method, req.hostname, req.path);
next();
});
app.use("/", indexRouter); app.use("/", indexRouter);
//app.use("/new", msgRouter); //app.use("/new", msgRouter);
//
const server = app.listen(port, () => { const server = app.listen(port, () => {
console.log(`Webserver running on ${port}.`); console.log(`Webserver running on ${port}.`);

View file

@ -0,0 +1,53 @@
const db = require("../db/query");
const { body, validationResult } = require("express-validator");
const links = [
{ href: "/", text: "Home" },
{ href: "/new", text: "New" },
];
const validateContent = [
body("message").isLength({ min: 2 }).withMessage("Must enter a message!"),
body("username")
.trim()
.isLength({ min: 2, max: 25 })
.withMessage("Username Must be between 2 and 25 chars."),
];
async function indexGet(req, res, next) {
try {
const rows = await db.getAllMessages();
if (rows === undefined) rows = [];
res.render("index", { links: links, msgs: rows });
} catch {
res.render("index", { links: links, msgs: [] });
}
}
function newGet(req, res) {
res.render("msgs", { links: links });
}
async function newPost(req, res) {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).render("msgs", {
links: links,
errors: errors.array(),
});
}
const { message, username } = req.body;
db.insertMessage({
message: message,
username: username,
date: new Date().toISOString(),
});
res.redirect("/");
}
module.exports = {
indexGet,
newGet,
newPost,
validateContent,
};

View file

@ -0,0 +1,22 @@
const sqlite3 = require("sqlite3").verbose();
const path = require("node:path");
const { stat } = require("node:fs");
const { mkdir } = require("node:fs/promises");
const dbDirPath = path.join(path.dirname(__dirname));
const dbPath = path.join(dbDirPath, "/message-board.db");
async function makeDirectory(path) {
const dirCreation = await mkdir(path);
return dirCreation;
}
// Make sure DB exists
stat(dbDirPath, (err, stats) => {
if (err !== null) {
makeDirectory(dbDirPath);
}
});
const db = new sqlite3.Database(dbPath);
module.exports = db;

View file

@ -0,0 +1,22 @@
const db = require("../db");
async function getAllMessages() {
return new Promise((resolve) => {
db.all("SELECT * FROM messages ORDER BY date DESC;", async (err, rows) =>
resolve(rows),
);
});
}
async function insertMessage(msg) {
db.run("INSERT INTO MESSAGES (message, username, date) VALUES (?, ?, ?)", [
msg.message,
msg.username,
msg.date,
]);
}
module.exports = {
getAllMessages,
insertMessage,
};

View file

@ -0,0 +1,26 @@
const db = require("../db");
const SQL = `
CREATE TABLE IF NOT EXISTS messages (
id INTEGER PRIMARY KEY ASC,
message TEXT,
username VARCHAR(25),
date TEXT
);
INSERT INTO messages (message, username, date)
VALUES
('this is cool', 'smig.tech', '2024-12-24T01:12:340Z'),
('I like this app', 'smigz', '2024-12-25T00:32:43.540Z'),
('For real, it is nice', 'mikey', '2024-12-28T00:35:43.540Z')
`;
async function main(db) {
console.log("seeding db...");
db.serialize(() => {
db.exec(SQL);
});
}
main(db);

View file

@ -8,6 +8,7 @@
justify-content: center; justify-content: center;
align-items: center; align-items: center;
list-style-type: none; list-style-type: none;
font-size: 1.5rem;
} }
.nav-item { .nav-item {
@ -25,7 +26,39 @@
align-items: center; align-items: center;
} }
.msg-feed {
margin-top: 3rem;
}
.card { .card {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
min-width: 300px;
align-items: center;
}
.form-item {
display: flex;
flex-direction: column;
padding: 10px 0;
min-width: 300px;
}
.form-item input {
padding: 10px 20px;
margin: 8px 0;
width: 100%;
box-sizing: border-box;
font-size: 1rem;
}
.btn {
padding: 1rem;
margin: 0 1rem;
font-size: 1.3rem;
/*width: 100%;*/
}
.errors {
color: red;
} }

View file

@ -1,45 +1,15 @@
const { Router } = require("express"); const { Router } = require("express");
const indexController = require("../controllers/indexController");
const db = require("../db");
const indexRouter = Router(); const indexRouter = Router();
links = [ indexRouter.get("/", indexController.indexGet);
{ href: "/", text: "Home" }, indexRouter.get("/new", indexController.newGet);
{ href: "/new", text: "New" }, indexRouter.post(
]; "/new",
indexController.validateContent,
const messages = [ indexController.newPost,
{ );
text: "Hi there!",
user: "Amando",
added: new Date(),
},
{
text: "Hello World!",
user: "Charles",
added: new Date(),
},
{
text: "This is a smig's app",
user: "Smig's",
added: new Date(),
},
];
indexRouter.get("/", (req, res) => {
res.render("index", { links: links, msgs: messages });
});
indexRouter.get("/new", (req, res) => {
res.render("msgs");
});
indexRouter.post("/new", (req, res) => {
messages.unshift({
text: req.body.message,
user: req.body.username,
added: new Date(),
});
res.redirect("/");
});
module.exports = { indexRouter }; module.exports = { indexRouter };

View file

@ -6,13 +6,12 @@
<body> <body>
<!-- this should be some stuff that loads --!> <!-- this should be some stuff that loads --!>
<%- include('navbar', {links: links}) %> <%- include('navbar', {links: links}) %>
<div class="container"> <div class="container msg-feed">
<% msgs.forEach((msg) => { %> <% msgs.forEach((msg) => { %>
<div class="card"> <div class="card">
<h3><%= msg.user %></h3> <h3><%= msg.username %></h3>
<span><%= msg.added %></span> <span><%= msg.date %></span>
<p><%= msg.text %></p> <p><%= msg.message %></p>
</div> </div>
<% }); %> <% }); %>

View file

@ -1,17 +1,28 @@
<html>
<head>
<title>Message the people</title>
<link rel="stylesheet" href="/styles.css">
</head>
<body>
<%- include('navbar', {links: links}) %>
<%- include('partials/errors.ejs') %>
<form method="POST" action="/new"> <form method="POST" action="/new">
<div class="form-item"> <div class="container">
<div class="form-item">
<label for="uername">Username</label> <label for="uername">Username</label>
<input type="text" id="username" name="username"> <input type="text" id="username" name="username">
</div> </div>
<div class="form-item"> <div class="form-item">
<label for="message">Message</label> <label for="message">Message</label>
<input type="text" id="message" name="message"> <input type="text" id="message" name="message">
</div> </div>
<div class="form-item"> <div class="form-item">
<button type="submit">Submit</button> <button class="btn" type="submit">Submit</button>
</div> <button class="btn" type="button" onCLick="window.location='/';">Return</button>
</div>
</div>
</form> </form>
</body>
</html>
<!-- vim: sts=2 sw=2 et ts=2 # --> <!-- vim: sts=2 sw=2 et ts=2 # -->

View file

@ -0,0 +1,9 @@
<% if (locals.errors) {%>
<div class="container errors">
<ul>
<% errors.forEach(function(error) { %>
<li><%= error.msg %></li>
<% }); %>
</ul>
</div>
<% } %>