mirror of
https://gitea.smigz.com/smiggiddy/odin-codeprojects.git
synced 2025-04-04 19:10:56 -04:00
more code
This commit is contained in:
parent
e07590d6e5
commit
90769c9bf1
16 changed files with 1710 additions and 63 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,3 +1,4 @@
|
|||
*.db
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
FROM node:23-alpine
|
||||
|
||||
COPY package*.json /app/package*.json
|
||||
COPY package.json package-lock.json /app
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
|
@ -12,6 +12,8 @@ EXPOSE 3000
|
|||
|
||||
USER nobody
|
||||
|
||||
CMD ["node", "src/app.js"]
|
||||
ENTRYPOINT ["node"]
|
||||
|
||||
CMD ["src/app.js"]
|
||||
|
||||
|
||||
|
|
1487
nodejs-mini-message-board/package-lock.json
generated
1487
nodejs-mini-message-board/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,14 @@
|
|||
{
|
||||
"name": "Odin - Message Board",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"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"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ const port = 3000;
|
|||
|
||||
const { indexRouter } = require("./routes/indexRouter");
|
||||
//const { msgRouter } = require("./routes/msgRouter");
|
||||
//
|
||||
|
||||
app.set("views", path.join(__dirname, "views"));
|
||||
app.set("view engine", "ejs");
|
||||
|
@ -15,8 +16,15 @@ app.use(express.static(assetsPath));
|
|||
|
||||
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("/new", msgRouter);
|
||||
//
|
||||
|
||||
const server = app.listen(port, () => {
|
||||
console.log(`Webserver running on ${port}.`);
|
||||
|
|
53
nodejs-mini-message-board/src/controllers/indexController.js
Normal file
53
nodejs-mini-message-board/src/controllers/indexController.js
Normal 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,
|
||||
};
|
0
nodejs-mini-message-board/src/controllers/newMessage.js
Normal file
0
nodejs-mini-message-board/src/controllers/newMessage.js
Normal file
22
nodejs-mini-message-board/src/db.js
Normal file
22
nodejs-mini-message-board/src/db.js
Normal 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;
|
22
nodejs-mini-message-board/src/db/query.js
Normal file
22
nodejs-mini-message-board/src/db/query.js
Normal 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,
|
||||
};
|
26
nodejs-mini-message-board/src/db/seedDb.js
Normal file
26
nodejs-mini-message-board/src/db/seedDb.js
Normal 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);
|
0
nodejs-mini-message-board/src/populateDb.js
Normal file
0
nodejs-mini-message-board/src/populateDb.js
Normal file
|
@ -8,6 +8,7 @@
|
|||
justify-content: center;
|
||||
align-items: center;
|
||||
list-style-type: none;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
|
@ -25,7 +26,39 @@
|
|||
align-items: center;
|
||||
}
|
||||
|
||||
.msg-feed {
|
||||
margin-top: 3rem;
|
||||
}
|
||||
|
||||
.card {
|
||||
display: flex;
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -1,45 +1,15 @@
|
|||
const { Router } = require("express");
|
||||
const indexController = require("../controllers/indexController");
|
||||
const db = require("../db");
|
||||
|
||||
const indexRouter = Router();
|
||||
|
||||
links = [
|
||||
{ href: "/", text: "Home" },
|
||||
{ href: "/new", text: "New" },
|
||||
];
|
||||
|
||||
const messages = [
|
||||
{
|
||||
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("/");
|
||||
});
|
||||
indexRouter.get("/", indexController.indexGet);
|
||||
indexRouter.get("/new", indexController.newGet);
|
||||
indexRouter.post(
|
||||
"/new",
|
||||
indexController.validateContent,
|
||||
indexController.newPost,
|
||||
);
|
||||
|
||||
module.exports = { indexRouter };
|
||||
|
|
|
@ -6,13 +6,12 @@
|
|||
<body>
|
||||
<!-- this should be some stuff that loads --!>
|
||||
<%- include('navbar', {links: links}) %>
|
||||
<div class="container">
|
||||
|
||||
<div class="container msg-feed">
|
||||
<% msgs.forEach((msg) => { %>
|
||||
<div class="card">
|
||||
<h3><%= msg.user %></h3>
|
||||
<span><%= msg.added %></span>
|
||||
<p><%= msg.text %></p>
|
||||
<h3><%= msg.username %></h3>
|
||||
<span><%= msg.date %></span>
|
||||
<p><%= msg.message %></p>
|
||||
</div>
|
||||
<% }); %>
|
||||
|
||||
|
|
|
@ -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">
|
||||
<div class="form-item">
|
||||
<label for="uername">Username</label>
|
||||
<input type="text" id="username" name="username">
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<label for="message">Message</label>
|
||||
<input type="text" id="message" name="message">
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<button type="submit">Submit</button>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="container">
|
||||
<div class="form-item">
|
||||
<label for="uername">Username</label>
|
||||
<input type="text" id="username" name="username">
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<label for="message">Message</label>
|
||||
<input type="text" id="message" name="message">
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<button class="btn" type="submit">Submit</button>
|
||||
<button class="btn" type="button" onCLick="window.location='/';">Return</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
<!-- vim: sts=2 sw=2 et ts=2 # -->
|
||||
|
|
9
nodejs-mini-message-board/src/views/partials/errors.ejs
Normal file
9
nodejs-mini-message-board/src/views/partials/errors.ejs
Normal file
|
@ -0,0 +1,9 @@
|
|||
<% if (locals.errors) {%>
|
||||
<div class="container errors">
|
||||
<ul>
|
||||
<% errors.forEach(function(error) { %>
|
||||
<li><%= error.msg %></li>
|
||||
<% }); %>
|
||||
</ul>
|
||||
</div>
|
||||
<% } %>
|
Loading…
Add table
Reference in a new issue