diff --git a/main.ts b/main.ts index 0aa6fb4..fd53d58 100644 --- a/main.ts +++ b/main.ts @@ -100,6 +100,7 @@ object-src 'none'; base-uri 'none';" const feedUpdates = ( await db .select({ + id: updates.id, user: users.name, mood: updates.mood, date: updates.date, @@ -111,6 +112,7 @@ object-src 'none'; base-uri 'none';" .orderBy(desc(updates.date)) ).map((e) => { return { + id: e.id, user: e.user, mood: moods[e.mood], date: e.date, diff --git a/routes/updates.ts b/routes/updates.ts index ae37912..c053b31 100644 --- a/routes/updates.ts +++ b/routes/updates.ts @@ -55,6 +55,7 @@ export default async function (app: Express, db: NodePgDatabase) { const recentUpdates = ( await db .select({ + id: updates.id, user: users.name, mood: updates.mood, desc: updates.description, @@ -73,6 +74,7 @@ export default async function (app: Express, db: NodePgDatabase) { .limit(25) ).map((e) => { return { + id: e.id, user: e.user, mood: moods[e.mood], desc: e.desc, @@ -131,7 +133,7 @@ export default async function (app: Express, db: NodePgDatabase) { feed: [] }); }); - app.post("/update/mood", async (req, res) => { + app.post("/mood/update", async (req, res) => { if (!req.session["loggedIn"]) { res.redirect("/login"); return; @@ -174,6 +176,29 @@ export default async function (app: Express, db: NodePgDatabase) { req.flash("success", "Mood updated!"); res.redirect("/dashboard"); }); + app.post("/mood/delete", async (req, res) => { + const u = parseInt(req.body.upd); + if (!req.session["loggedIn"] || !req.body.upd || isNaN(u)) { + render404(db, res, req); + return; + } + + const { user } = (await db.select({user: updates.user}).from(updates).where(eq(updates.id, u)).limit(1))[0]; + if (!user || (user !== req.session["uid"] && !(req.session["status"] & UserStatus.MODERATOR))) { + render404(db, res, req); + return; + } + + if (!confirm(db, res, req, "/dashboard")) { + return; + } + await db.delete(updates).where(eq(updates.id, u)); + + req.flash("success", "Update deleted ;w;"); + //! TODO: do we have to do it this way????? confirm() is fucking this up + // also for the API using localstorage here from then would probably be a better idea + res.redirect(req.session["back"]); + }); // JOURNAL app.get("/journal", async (req, res) => { @@ -285,18 +310,17 @@ export default async function (app: Express, db: NodePgDatabase) { if (req.body.action === "edit") { // TODO!! } else if (req.body.action === "delete") { - if (!req.body.confirm) { - confirm(db, res, req); + if (!confirm(db, res, req, `/journal/${req.params.id}`)) { return; } await db.delete(journalEntries).where(eq(journalEntries.id, id)); req.flash("success", "Journal entry deleted ;w;"); - res.redirect("/"); + res.redirect(req.session["back"]); } else { render404(db, res, req); } }); - app.post("/update/journal", async (req, res) => { + app.post("/journal/update", async (req, res) => { if (!req.session["loggedIn"]) { res.redirect("/login"); return; diff --git a/routes/users.ts b/routes/users.ts index 2303304..84ca354 100644 --- a/routes/users.ts +++ b/routes/users.ts @@ -114,6 +114,7 @@ export default async function (app: Express, db: NodePgDatabase) { const userMoodFeed = ( await db .select({ + id: updates.id, mood: updates.mood, date: updates.date, desc: updates.description @@ -123,6 +124,7 @@ export default async function (app: Express, db: NodePgDatabase) { .orderBy(desc(updates.date)) ).map((e) => { return { + id: e.id, user: user.name, mood: moods[e.mood], date: e.date, diff --git a/routes/util.ts b/routes/util.ts index c8a8261..5f76841 100644 --- a/routes/util.ts +++ b/routes/util.ts @@ -136,9 +136,19 @@ export function journalMoodString(mood: number) { export function confirm( db: NodePgDatabase, res: Response, - req: Request + req: Request, + defaultUrl = "/" ) { - render(db, "confirm", "Confirm action", res, req, { body: req.body, url: req.url }); + if (req.body.confirm === undefined) { + req.session["back"] = req.get("Referrer") || defaultUrl; + render(db, "confirm", "Confirm action", res, req, { body: req.body, url: req.url }); + } else if (req.body.confirm === "y") { + return true; + } else { + //! dumb + res.redirect(req.session["back"] || defaultUrl); + } + return false; } const emailRegex = /^([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22))*\x40([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d))*$/i; diff --git a/static/css/main.css b/static/css/main.css index 154b5ee..ac85e11 100644 --- a/static/css/main.css +++ b/static/css/main.css @@ -209,11 +209,32 @@ tr:hover td { display: flex; justify-content: space-between; } -.feed-update div:last-child { - text-align: right; +.feed-update-footer { + display: flex; + justify-content: space-between; +} +.feed-update-date { color: #3f3f38; font-style: italic; } +.feed-update-actions form { + display: inline; +} +.feed-update-actions form:first-child button { + color: #c51e48; +} + +.button-link { + margin: 0; + border: 0; + padding: 0; + background: none; +} +.button-link:hover, .button-link:focus, .button-link:focus-visible { + outline: 0; + border: 0; + text-decoration: underline; +} @font-face { font-family: "Gohufont 14"; diff --git a/views/_util.pug b/views/_util.pug index e8d31c6..e4b5536 100644 --- a/views/_util.pug +++ b/views/_util.pug @@ -9,7 +9,13 @@ mixin feed(feed, hideUser) | #{update.user} strong= update.mood div= update.desc || "[no mood description provided]" - div(title=update.date.toLocaleString())= update.relativeDate + .feed-update-footer + .feed-update-actions + if update.user === session.user || session.status & 0b0001 + form(action="/mood/delete", method="post") + input(type="number", name="upd", value=update.id, style="display:none;", readonly) + button.button-link(title="Delete this update") x + .feed-update-date(title=update.date.toLocaleString())= update.relativeDate else span [no updates] diff --git a/views/confirm.pug b/views/confirm.pug index 93cda3a..3ed4823 100644 --- a/views/confirm.pug +++ b/views/confirm.pug @@ -6,4 +6,4 @@ block content input(type="text", name=k, value=v, hidden) p Sure you want to do this?? button(name="confirm", value="y") Yes - button(onclick="history.back();") NO!!!! + button(name="confirm", value="n") NO!!!! diff --git a/views/dashboard.pug b/views/dashboard.pug index 453e0ea..5312731 100644 --- a/views/dashboard.pug +++ b/views/dashboard.pug @@ -40,7 +40,7 @@ block content a(href="#invite-codes") Invite codes p This is where you "MIPILIN"! That is all you need to know!!! p If onlookers notice your actions and inquire about what you are doing, you MUST tell them that you are mipilining all over the place, and then PROMPTLY SCROLL DOWN AND GENERATE AN INVITE CODE SO THAT THEY CAN MIPILIN TOO. - form#dashboard-update-form(action="/update/mood", method="post") + form#dashboard-update-form(action="/mood/update", method="post") select(name="mood", required) //- Maybe put the index of the mood in the value of the option element //- so that indexOf (slow) wont have to be used everytime mood is updated diff --git a/views/journal.pug b/views/journal.pug index e24a515..c00c5e0 100644 --- a/views/journal.pug +++ b/views/journal.pug @@ -8,7 +8,7 @@ block content h1 Your Journal p This is where you can log your overall mood every day, and get a glimpse at how your life is going so far! p In the near future there will be a magnificient graph that will let you visualize your past entries and your mood trends. You must tay stuned. - form#journal-update(action="/update/journal", method="post") + form#journal-update(action="/journal/update", method="post") .input span Overall mood change (how do you feel compared to yesterday?) #ovm