From d83c97e87bf953d399dfda1bfd12e2dd7edcf5a7 Mon Sep 17 00:00:00 2001
From: Mario Nikhil Pereira <45009203+nmpereira@users.noreply.github.com>
Date: Thu, 4 Jan 2024 22:50:10 -0500
Subject: [PATCH 01/18] update .env example to add more documentation
---
.env.example | 1 +
1 file changed, 1 insertion(+)
diff --git a/.env.example b/.env.example
index 67057f9..f3502b0 100644
--- a/.env.example
+++ b/.env.example
@@ -25,5 +25,6 @@ GOOGLE_ID = x
GOOGLE_SECRET = x
# Only needed if you are using Github login
+# For local development, use http://localhost:3000 as the homepage URL and http://localhost:3000/oauth/github/callback as the callback URL
GITHUB_ID = x
GITHUB_SECRET = x
From 4e7ad8cdcd69317d02a9df4ff73bca73f53e0b34 Mon Sep 17 00:00:00 2001
From: Mario Nikhil Pereira <45009203+nmpereira@users.noreply.github.com>
Date: Fri, 5 Jan 2024 00:27:11 -0500
Subject: [PATCH 02/18] add tags
---
src/controllers/lessons.js | 7 +++++++
src/models/Lesson.js | 3 +++
src/tailwind.css | 2 ++
src/views/addLesson.pug | 6 ++++++
src/views/lesson.pug | 9 +++++++++
src/views/mixins/lessonCard.pug | 10 ++++++++++
6 files changed, 37 insertions(+)
diff --git a/src/controllers/lessons.js b/src/controllers/lessons.js
index f37ab42..36f4200 100644
--- a/src/controllers/lessons.js
+++ b/src/controllers/lessons.js
@@ -55,6 +55,13 @@ export const addEditLesson = async (req, res) => {
motivationTitle: req.body.motivationTitle,
cohort: req.body.cohort,
note: req.body.note,
+ tags: req.body.tags
+ ? req.body.tags
+ .split(",")
+ .map((tag) => tag.trim().toLowerCase())
+ // add space after comma
+ .map((tag) => tag.replace(/,/g, ", "))
+ : [],
timestamps: timestamps,
};
const lesson = await Lesson.findByIdAndUpdate(
diff --git a/src/models/Lesson.js b/src/models/Lesson.js
index 39edb50..134944e 100644
--- a/src/models/Lesson.js
+++ b/src/models/Lesson.js
@@ -49,6 +49,9 @@ const lessonSchema = new Schema({
motivationTitle: {
type: String
},
+ tags: {
+ type: [String]
+ },
timestamps: [TimestampSchema],
cohort: Number,
note: String
diff --git a/src/tailwind.css b/src/tailwind.css
index 72f6497..0228592 100644
--- a/src/tailwind.css
+++ b/src/tailwind.css
@@ -85,6 +85,8 @@
@apply text-right;
}
#timestamps,
+ #tags,
+ /* do i need to add this here? */
#hw-items,
#pw-items {
@apply mt-3 w-full border px-5 py-3;
diff --git a/src/views/addLesson.pug b/src/views/addLesson.pug
index 8f96ba1..9ab7c18 100644
--- a/src/views/addLesson.pug
+++ b/src/views/addLesson.pug
@@ -53,6 +53,12 @@ block content
input#ts-time-0(type="number", name="tsTime")
label(for="ts-title-0") Title
input#ts-title-0(type="text", name="tsTitle")
+ #tags.col-span-4
+ h2.col-span-4.mb-3 Tags
+ label(for="tags") Tags
+ textarea#tag.col-span-4(type="text", name="tags"
+ placeholder="html, css, javascript, js, career help,ejs"
+ ) #{edit? lesson.tags : ""}
.col-span-4.mt-3.text-center
button(class="btn primary max-w-1/3 mx-auto" type="submit") #{action} Class
diff --git a/src/views/lesson.pug b/src/views/lesson.pug
index 25bb9bc..c8ed4ed 100644
--- a/src/views/lesson.pug
+++ b/src/views/lesson.pug
@@ -68,6 +68,15 @@ block content
h2 Motivation
a(href=lesson.motivationLink) #{lesson.motivationTitle}
+ if lesson.tags && lesson.tags.length
+ h2 Tags
+ .tags.flex.flex-wrap.px-3.py-2
+ each tag in lesson.tags
+ .text-xs.mr-2.border
+ = tag
+
+
+
if lesson.videoId && !lesson.twitchVideo
h3.mt-8 Feed the algorithm and spread the word!
p #[a(href=`https://www.youtube.com/watch?v=${lesson.videoId}` target="_blank") Like, comment and subscribe on Youtube]
diff --git a/src/views/mixins/lessonCard.pug b/src/views/mixins/lessonCard.pug
index ce065f7..cadb7b3 100644
--- a/src/views/mixins/lessonCard.pug
+++ b/src/views/mixins/lessonCard.pug
@@ -26,11 +26,21 @@ mixin lessonCard(lesson)
input.checkedin.hidden(type="checkbox" id="checkedin-" + lesson._id autocomplete="off" checked)
| No Check In
+
+
.card-main-content.py-4.px-6.mb-12.group
a(href=`/class/${lesson.permalink}` class="hover:no-underline")
img.w-full.mb-2(src=lesson.thumbnail class="group-hover:shadow-[0_0_10px_rgba(0,_0,_0,_0.2)]")
h2(class="group-hover:text-pink-900") #{lesson.title}
+ //- show tags if there are any
+ if lesson.tags && lesson.tags.length
+ h5.mt-3 Tags
+ .tags.flex.flex-wrap.px-3.py-2.mt-5
+ each tag in lesson.tags
+ .text-xs.mr-2.border
+ = tag
+
a.absolute.bottom-3(href=`/class/${lesson.permalink}`) More Info
if lesson.videoId && !lesson.twitchVideo
a.absolute.bottom-3.right-6.text-right(href=`https://youtu.be/${lesson.videoId}`) Youtube
From ddc3a6fd6c530dd800a3c249644a6aa8e5f9f4bb Mon Sep 17 00:00:00 2001
From: Mario Nikhil Pereira <45009203+nmpereira@users.noreply.github.com>
Date: Sun, 7 Jan 2024 13:29:56 -0500
Subject: [PATCH 03/18] fix styling and add link to query
---
src/views/lesson.pug | 4 ++--
src/views/mixins/lessonCard.pug | 8 ++++----
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/views/lesson.pug b/src/views/lesson.pug
index c8ed4ed..3644a5b 100644
--- a/src/views/lesson.pug
+++ b/src/views/lesson.pug
@@ -72,7 +72,7 @@ block content
h2 Tags
.tags.flex.flex-wrap.px-3.py-2
each tag in lesson.tags
- .text-xs.mr-2.border
+ a.text-xs.mr-2(href=`/class?tags=${tag}`)
= tag
@@ -82,7 +82,7 @@ block content
p #[a(href=`https://www.youtube.com/watch?v=${lesson.videoId}` target="_blank") Like, comment and subscribe on Youtube]
if assigned.length
- h2.mt-10.mb-3 Homework Assigned
+ h2.mt-10.mb-3.border-2.border-orange-600.border-dashed Homework Assigned
each homework in assigned
.mb-6(class="shadow-[0_2px_10px_0_rgba(0,0,0,0.1)]")
+homework(homework)
diff --git a/src/views/mixins/lessonCard.pug b/src/views/mixins/lessonCard.pug
index cadb7b3..c9f3f79 100644
--- a/src/views/mixins/lessonCard.pug
+++ b/src/views/mixins/lessonCard.pug
@@ -33,12 +33,12 @@ mixin lessonCard(lesson)
img.w-full.mb-2(src=lesson.thumbnail class="group-hover:shadow-[0_0_10px_rgba(0,_0,_0,_0.2)]")
h2(class="group-hover:text-pink-900") #{lesson.title}
- //- show tags if there are any
+
if lesson.tags && lesson.tags.length
- h5.mt-3 Tags
- .tags.flex.flex-wrap.px-3.py-2.mt-5
+ h4.mt-3 Tags
+ .tags.flex.flex-wrap.px-3.py-2
each tag in lesson.tags
- .text-xs.mr-2.border
+ a.text-xs.mr-2(href=`/class?tags=${tag}`)
= tag
a.absolute.bottom-3(href=`/class/${lesson.permalink}`) More Info
From cd5c3a180afc5cc45faea6da1529a172821d43fb Mon Sep 17 00:00:00 2001
From: Mario Nikhil Pereira <45009203+nmpereira@users.noreply.github.com>
Date: Sun, 7 Jan 2024 14:24:13 -0500
Subject: [PATCH 04/18] add router logic for filtering by tags
---
src/controllers/lessons.js | 360 +++++++++++++++++---------------
src/routes/lessonRouter.js | 1 +
src/views/lesson.pug | 2 +-
src/views/mixins/lessonCard.pug | 2 +-
4 files changed, 190 insertions(+), 175 deletions(-)
diff --git a/src/controllers/lessons.js b/src/controllers/lessons.js
index 36f4200..ad27a37 100644
--- a/src/controllers/lessons.js
+++ b/src/controllers/lessons.js
@@ -8,203 +8,217 @@ import Homework from "../models/Homework.js";
import { getHwProgress } from "./homework.js";
export const addEditLessonForm = async (req, res) => {
- if (!req.isAuthenticated() || !req.user.admin) return res.redirect("/");
- const edit = !!req.params.id;
- let lesson = null;
- if (edit) {
- lesson = await Lesson.findById(req.params.id).lean();
- lesson.classNo = lesson.classNo.join(",");
- lesson.checkin = lesson.checkin.join(",");
- lesson.slides = lesson.slides.join(",");
- lesson.dates = lesson.dates
- .map((date) => {
- return date.toISOString().split("T")[0];
- })
- .join(",");
- }
- res.render("addLesson", { edit, lesson });
+ if (!req.isAuthenticated() || !req.user.admin) return res.redirect("/");
+ const edit = !!req.params.id;
+ let lesson = null;
+ if (edit) {
+ lesson = await Lesson.findById(req.params.id).lean();
+ lesson.classNo = lesson.classNo.join(",");
+ lesson.checkin = lesson.checkin.join(",");
+ lesson.slides = lesson.slides.join(",");
+ lesson.dates = lesson.dates
+ .map((date) => {
+ return date.toISOString().split("T")[0];
+ })
+ .join(",");
+ }
+ res.render("addLesson", { edit, lesson });
};
export const addEditLesson = async (req, res) => {
- if (!req.isAuthenticated() || !req.user.admin) return res.redirect("/");
- try {
- let dates = [];
- if (req.body.date) {
- dates = req.body.date.split(",").map((date) => new Date(date));
- }
- let slides = [];
- const timestamps = [];
- for (let i = 0; i < req.body.tsTime.length; i++) {
- timestamps.push({
- time: Number(req.body.tsTime[i]),
- title: req.body.tsTitle[i],
- });
- }
- const lessonData = {
- videoId: req.body.videoId,
- twitchVideo: !!req.body.twitch ? true : false,
- title: req.body.videoTitle,
- dates: dates,
- permalink: req.body.permalink,
- thumbnail: req.body.thumbnail,
- classNo: req.body.number ? req.body.number.split(",") : [],
- slides: req.body.slides ? req.body.slides.split(",") : [],
- materials: req.body.materials,
- checkin: req.body.checkin ? req.body.checkin.split(",") : [],
- motivationLink: req.body.motivationLink,
- motivationTitle: req.body.motivationTitle,
- cohort: req.body.cohort,
- note: req.body.note,
- tags: req.body.tags
- ? req.body.tags
- .split(",")
- .map((tag) => tag.trim().toLowerCase())
- // add space after comma
- .map((tag) => tag.replace(/,/g, ", "))
- : [],
- timestamps: timestamps,
- };
- const lesson = await Lesson.findByIdAndUpdate(
- req.params.id || mongoose.Types.ObjectId(),
- lessonData,
- { upsert: true, new: true }
- );
+ if (!req.isAuthenticated() || !req.user.admin) return res.redirect("/");
+ try {
+ let dates = [];
+ if (req.body.date) {
+ dates = req.body.date.split(",").map((date) => new Date(date));
+ }
+ let slides = [];
+ const timestamps = [];
+ for (let i = 0; i < req.body.tsTime.length; i++) {
+ timestamps.push({
+ time: Number(req.body.tsTime[i]),
+ title: req.body.tsTitle[i],
+ });
+ }
+ const lessonData = {
+ videoId: req.body.videoId,
+ twitchVideo: !!req.body.twitch ? true : false,
+ title: req.body.videoTitle,
+ dates: dates,
+ permalink: req.body.permalink,
+ thumbnail: req.body.thumbnail,
+ classNo: req.body.number ? req.body.number.split(",") : [],
+ slides: req.body.slides ? req.body.slides.split(",") : [],
+ materials: req.body.materials,
+ checkin: req.body.checkin ? req.body.checkin.split(",") : [],
+ motivationLink: req.body.motivationLink,
+ motivationTitle: req.body.motivationTitle,
+ cohort: req.body.cohort,
+ note: req.body.note,
+ tags: req.body.tags
+ ? req.body.tags
+ .split(",")
+ .map((tag) => tag.trim().toLowerCase())
+ // add space after comma
+ .map((tag) => tag.replace(/,/g, ", "))
+ : [],
+ timestamps: timestamps,
+ };
+ const lesson = await Lesson.findByIdAndUpdate(
+ req.params.id || mongoose.Types.ObjectId(),
+ lessonData,
+ { upsert: true, new: true }
+ );
- // if this is a new class, update all users with current class = null so this is now their current class
- if (!req.params.id) {
- await User.updateMany(
- { currentClass: null },
- { currentClass: lesson._id }
- );
- }
- req.session.flash = {
- type: "success",
- message: [`Class ${!!req.params.id ? "updated" : "added"}`],
- };
- } catch (err) {
- console.log(err);
- req.session.flash = {
- type: "error",
- message: [`Class not ${!!req.params.id ? "updated" : "added"}`],
- };
- } finally {
- res.redirect("/class/add");
- }
+ // if this is a new class, update all users with current class = null so this is now their current class
+ if (!req.params.id) {
+ await User.updateMany(
+ { currentClass: null },
+ { currentClass: lesson._id }
+ );
+ }
+ req.session.flash = {
+ type: "success",
+ message: [`Class ${!!req.params.id ? "updated" : "added"}`],
+ };
+ } catch (err) {
+ console.log(err);
+ req.session.flash = {
+ type: "error",
+ message: [`Class not ${!!req.params.id ? "updated" : "added"}`],
+ };
+ } finally {
+ res.redirect("/class/add");
+ }
};
export const getAllLessonsProgress = async (userId, lessons) => {
- const lessonProgress = await LessonProgress.find({ user: userId }).lean();
- const lessonsObj = {};
- lessonProgress.forEach((p) => {
- lessonsObj[p.lesson] = {
- watched: p.watched,
- checkedIn: p.checkedIn,
- };
- });
- lessons.forEach((lesson) => {
- const prog = lessonsObj[lesson._id];
- lesson.watched = prog ? !!prog.watched : false;
- lesson.checkedIn = prog ? !!prog.checkedIn : false;
- });
- return lessons;
+ const lessonProgress = await LessonProgress.find({ user: userId }).lean();
+ const lessonsObj = {};
+ lessonProgress.forEach((p) => {
+ lessonsObj[p.lesson] = {
+ watched: p.watched,
+ checkedIn: p.checkedIn,
+ };
+ });
+ lessons.forEach((lesson) => {
+ const prog = lessonsObj[lesson._id];
+ lesson.watched = prog ? !!prog.watched : false;
+ lesson.checkedIn = prog ? !!prog.checkedIn : false;
+ });
+ return lessons;
};
export const allLessons = async (req, res) => {
- let lessons = await Lesson.find().lean().sort({ _id: 1 });
- if (req.isAuthenticated()) {
- lessons = await getAllLessonsProgress(req.user.id, lessons);
- }
- res.render("allLessons", { lessons });
+ let lessons = await Lesson.find().lean().sort({ _id: 1 });
+ if (req.isAuthenticated()) {
+ lessons = await getAllLessonsProgress(req.user.id, lessons);
+ }
+ res.render("allLessons", { lessons });
};
export const getLessonProgress = async (userId, lesson) => {
- const progress = await LessonProgress.findOne({
- user: userId,
- lesson: lesson._id,
- });
- lesson.watched = progress ? progress.watched : false;
- lesson.checkedIn = progress ? progress.checkedIn : false;
- return lesson;
+ const progress = await LessonProgress.findOne({
+ user: userId,
+ lesson: lesson._id,
+ });
+ lesson.watched = progress ? progress.watched : false;
+ lesson.checkedIn = progress ? progress.checkedIn : false;
+ return lesson;
};
export const showLesson = async (req, res) => {
- try {
- let lesson = await Lesson.findOne({
- permalink: req.params.permalink,
- }).lean();
- let next = await Lesson.find({ _id: { $gt: lesson._id } })
- .sort({ _id: 1 })
- .limit(1);
- next = next.length ? next[0].permalink : null;
- let prev = await Lesson.find({ _id: { $lt: lesson._id } })
- .sort({ _id: -1 })
- .limit(1);
- prev = prev.length ? prev[0].permalink : null;
- let assigned = await Homework.find({ classNo: { $in: lesson.classNo } })
- .lean()
- .sort({ _id: 1 })
- .populate(["items", "extras"]);
- let due = await Homework.find({ dueNo: { $in: lesson.classNo } })
- .lean()
- .sort({ _id: 1 })
- .populate(["items", "extras"]);
+ try {
+ let lesson = await Lesson.findOne({
+ permalink: req.params.permalink,
+ }).lean();
+ let next = await Lesson.find({ _id: { $gt: lesson._id } })
+ .sort({ _id: 1 })
+ .limit(1);
+ next = next.length ? next[0].permalink : null;
+ let prev = await Lesson.find({ _id: { $lt: lesson._id } })
+ .sort({ _id: -1 })
+ .limit(1);
+ prev = prev.length ? prev[0].permalink : null;
+ let assigned = await Homework.find({ classNo: { $in: lesson.classNo } })
+ .lean()
+ .sort({ _id: 1 })
+ .populate(["items", "extras"]);
+ let due = await Homework.find({ dueNo: { $in: lesson.classNo } })
+ .lean()
+ .sort({ _id: 1 })
+ .populate(["items", "extras"]);
- if (req.isAuthenticated()) {
- lesson = await getLessonProgress(req.user.id, lesson);
- if (assigned.length)
- assigned = await getHwProgress(req.user.id, assigned);
- if (due.length) due = await getHwProgress(req.user.id, due);
- }
- res.render("lesson", { lesson, next, prev, assigned, due });
- } catch (err) {
- console.log(err);
- res.redirect("/class/all");
- }
+ if (req.isAuthenticated()) {
+ lesson = await getLessonProgress(req.user.id, lesson);
+ if (assigned.length)
+ assigned = await getHwProgress(req.user.id, assigned);
+ if (due.length) due = await getHwProgress(req.user.id, due);
+ }
+ res.render("lesson", { lesson, next, prev, assigned, due });
+ } catch (err) {
+ console.log(err);
+ res.redirect("/class/all");
+ }
+};
+
+export const filterByTags = async (req, res) => {
+ try {
+ const tags = req.query.tags?.split(",").map((tag) => tag.trim());
+ console.log({ tags });
+ const lessons = await Lesson.find(tags ? { tags: { $in: tags } } : {})
+ .sort({ _id: 1 })
+ .lean();
+ res.render("allLessons", { lessons });
+ } catch (err) {
+ console.log(err);
+ res.redirect("/class/all");
+ }
};
export const deleteLesson = async (req, res) => {
- if (!req.user?.admin) return res.redirect("/");
- try {
- const lessonId = req.params.id;
- let next = await Lesson.find({ _id: { $gt: lessonId } })
- .sort({ _id: 1 })
- .limit(1);
- const nextId = next[0] ? next[0]._id : null;
- const res = await User.updateMany(
- { currentClass: lessonId },
- { currentClass: nextId }
- );
- await LessonProgress.deleteMany({ lesson: lessonId });
- await Lesson.deleteOne({ _id: lessonId });
- } catch (err) {
- console.log(err);
- } finally {
- res.redirect("/class/all");
- }
+ if (!req.user?.admin) return res.redirect("/");
+ try {
+ const lessonId = req.params.id;
+ let next = await Lesson.find({ _id: { $gt: lessonId } })
+ .sort({ _id: 1 })
+ .limit(1);
+ const nextId = next[0] ? next[0]._id : null;
+ const res = await User.updateMany(
+ { currentClass: lessonId },
+ { currentClass: nextId }
+ );
+ await LessonProgress.deleteMany({ lesson: lessonId });
+ await Lesson.deleteOne({ _id: lessonId });
+ } catch (err) {
+ console.log(err);
+ } finally {
+ res.redirect("/class/all");
+ }
};
export const toggleWatched = async (req, res) => {
- if (!req.user) return res.status(401).json({ msg: "not logged in" });
- try {
- const userId = req.user.id;
- const lessonId = req.params.id;
- await LessonProgress.toggleWatched(lessonId, userId);
- res.json({ msg: "toggled lesson watched" });
- } catch (err) {
- console.log(err);
- res.status(err.status || 500).json({ error: err.message });
- }
+ if (!req.user) return res.status(401).json({ msg: "not logged in" });
+ try {
+ const userId = req.user.id;
+ const lessonId = req.params.id;
+ await LessonProgress.toggleWatched(lessonId, userId);
+ res.json({ msg: "toggled lesson watched" });
+ } catch (err) {
+ console.log(err);
+ res.status(err.status || 500).json({ error: err.message });
+ }
};
export const toggleCheckedIn = async (req, res) => {
- if (!req.user) return res.status(401).json({ msg: "not logged in" });
- try {
- const userId = req.user.id;
- const lessonId = req.params.id;
- await LessonProgress.toggleCheckedIn(lessonId, req.user.id);
- res.json({ msg: "toggled lesson checked in" });
- } catch (err) {
- console.log(err);
- res.status(err.status || 500).json({ error: err.message });
- }
+ if (!req.user) return res.status(401).json({ msg: "not logged in" });
+ try {
+ const userId = req.user.id;
+ const lessonId = req.params.id;
+ await LessonProgress.toggleCheckedIn(lessonId, req.user.id);
+ res.json({ msg: "toggled lesson checked in" });
+ } catch (err) {
+ console.log(err);
+ res.status(err.status || 500).json({ error: err.message });
+ }
};
diff --git a/src/routes/lessonRouter.js b/src/routes/lessonRouter.js
index d589e64..9d39acd 100644
--- a/src/routes/lessonRouter.js
+++ b/src/routes/lessonRouter.js
@@ -11,6 +11,7 @@ router.post("/add", lessons.addEditLesson);
router.post("/edit/:id", lessons.addEditLesson);
router.get("/all", lessons.allLessons);
+router.get("/tags", lessons.filterByTags);
router.get("/:permalink", lessons.showLesson);
router.put("/watched/:id", lessons.toggleWatched);
diff --git a/src/views/lesson.pug b/src/views/lesson.pug
index 3644a5b..2680118 100644
--- a/src/views/lesson.pug
+++ b/src/views/lesson.pug
@@ -72,7 +72,7 @@ block content
h2 Tags
.tags.flex.flex-wrap.px-3.py-2
each tag in lesson.tags
- a.text-xs.mr-2(href=`/class?tags=${tag}`)
+ a.text-xs.mr-2(href=`/class/tags?tags=${tag}`)
= tag
diff --git a/src/views/mixins/lessonCard.pug b/src/views/mixins/lessonCard.pug
index c9f3f79..2961af0 100644
--- a/src/views/mixins/lessonCard.pug
+++ b/src/views/mixins/lessonCard.pug
@@ -38,7 +38,7 @@ mixin lessonCard(lesson)
h4.mt-3 Tags
.tags.flex.flex-wrap.px-3.py-2
each tag in lesson.tags
- a.text-xs.mr-2(href=`/class?tags=${tag}`)
+ a.text-xs.mr-2(href=`/class/tags?tags=${tag}`)
= tag
a.absolute.bottom-3(href=`/class/${lesson.permalink}`) More Info
From f7300b671dc98af28687d1d92b448d22b7321b77 Mon Sep 17 00:00:00 2001
From: Mario Nikhil Pereira <45009203+nmpereira@users.noreply.github.com>
Date: Sun, 7 Jan 2024 14:40:59 -0500
Subject: [PATCH 05/18] add filteredLessons page
---
src/controllers/lessons.js | 9 ++++++---
src/views/filteredLessons.pug | 25 +++++++++++++++++++++++++
src/views/mixins/lessonCard.pug | 2 +-
3 files changed, 32 insertions(+), 4 deletions(-)
create mode 100644 src/views/filteredLessons.pug
diff --git a/src/controllers/lessons.js b/src/controllers/lessons.js
index ad27a37..9cd8b9c 100644
--- a/src/controllers/lessons.js
+++ b/src/controllers/lessons.js
@@ -165,11 +165,14 @@ export const showLesson = async (req, res) => {
export const filterByTags = async (req, res) => {
try {
const tags = req.query.tags?.split(",").map((tag) => tag.trim());
- console.log({ tags });
- const lessons = await Lesson.find(tags ? { tags: { $in: tags } } : {})
+ let lessons = await Lesson.find(tags ? { tags: { $in: tags } } : {})
.sort({ _id: 1 })
.lean();
- res.render("allLessons", { lessons });
+
+ if (req.isAuthenticated()) {
+ lessons = await getAllLessonsProgress(req.user.id, lessons);
+ }
+ res.render("filteredLessons", { lessons });
} catch (err) {
console.log(err);
res.redirect("/class/all");
diff --git a/src/views/filteredLessons.pug b/src/views/filteredLessons.pug
new file mode 100644
index 0000000..1f07a58
--- /dev/null
+++ b/src/views/filteredLessons.pug
@@ -0,0 +1,25 @@
+extends layouts/default.pug
+include ./mixins/lessonCard.pug
+
+block variables
+ - title = "Classes"
+ - active = "Classes"
+
+block content
+ if !loggedIn
+ include ./partials/flash-nologin.pug
+
+ h1.mb-4 Filter Results
+
+
+
+ #lessons.grid.gap-y-12.gap-x-16(class="sm:gap-y-24 grid-cols-[repeat(auto-fill,_minmax(285px,_1fr))]")
+ each lesson in lessons
+ +lessonCard(lesson)
+
+ include ./partials/to-top.pug
+
+append scripts
+ if loggedIn
+ script(src="/js/lessonProgress.js")
+ script(src="/js/lessonDone.js")
diff --git a/src/views/mixins/lessonCard.pug b/src/views/mixins/lessonCard.pug
index 2961af0..3f4fa38 100644
--- a/src/views/mixins/lessonCard.pug
+++ b/src/views/mixins/lessonCard.pug
@@ -35,7 +35,7 @@ mixin lessonCard(lesson)
if lesson.tags && lesson.tags.length
- h4.mt-3 Tags
+
.tags.flex.flex-wrap.px-3.py-2
each tag in lesson.tags
a.text-xs.mr-2(href=`/class/tags?tags=${tag}`)
From ecc2d26dde7bdab63858676fc0cb3f680f4add38 Mon Sep 17 00:00:00 2001
From: Mario Nikhil Pereira <45009203+nmpereira@users.noreply.github.com>
Date: Sun, 7 Jan 2024 17:07:54 -0500
Subject: [PATCH 06/18] improve filter page
---
src/controllers/lessons.js | 10 +++++++++-
src/views/filteredLessons.pug | 6 +++++-
2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/src/controllers/lessons.js b/src/controllers/lessons.js
index 9cd8b9c..6e764e7 100644
--- a/src/controllers/lessons.js
+++ b/src/controllers/lessons.js
@@ -169,10 +169,18 @@ export const filterByTags = async (req, res) => {
.sort({ _id: 1 })
.lean();
+ const allTags = await Lesson.aggregate([
+ { $unwind: "$tags" },
+ { $group: { _id: "$tags", count: { $sum: 1 } } },
+ { $sort: { _id: 1 } },
+ ]);
+
+ console.log({allTags});
+
if (req.isAuthenticated()) {
lessons = await getAllLessonsProgress(req.user.id, lessons);
}
- res.render("filteredLessons", { lessons });
+ res.render("filteredLessons", { lessons, allTags });
} catch (err) {
console.log(err);
res.redirect("/class/all");
diff --git a/src/views/filteredLessons.pug b/src/views/filteredLessons.pug
index 1f07a58..7a9b029 100644
--- a/src/views/filteredLessons.pug
+++ b/src/views/filteredLessons.pug
@@ -11,7 +11,11 @@ block content
h1.mb-4 Filter Results
-
+ h4 Results: #{lessons.length}
+
+ h4 Filters:
+ each tag in allTags || []
+ a.mr-2(href=`/class/tags?tags=${tag._id}`) #{tag._id}
#lessons.grid.gap-y-12.gap-x-16(class="sm:gap-y-24 grid-cols-[repeat(auto-fill,_minmax(285px,_1fr))]")
each lesson in lessons
From 350b134249286aeef7eb8e3c2914fc09f09091b9 Mon Sep 17 00:00:00 2001
From: Mario Nikhil Pereira <45009203+nmpereira@users.noreply.github.com>
Date: Sun, 7 Jan 2024 19:32:14 -0500
Subject: [PATCH 07/18] added ability to use filter buttons
---
src/assets/js/filterTags.js | 32 ++++++++++++++++++++++++++++++++
src/controllers/lessons.js | 4 +---
src/views/filteredLessons.pug | 26 +++++++++++++++++++++-----
src/views/lesson.pug | 2 +-
4 files changed, 55 insertions(+), 9 deletions(-)
create mode 100644 src/assets/js/filterTags.js
diff --git a/src/assets/js/filterTags.js b/src/assets/js/filterTags.js
new file mode 100644
index 0000000..9ec2171
--- /dev/null
+++ b/src/assets/js/filterTags.js
@@ -0,0 +1,32 @@
+const filterTags = document.querySelectorAll(".filter-tag");
+const clearFilterBtn = document.getElementById("filter-tag-clear");
+
+// when clicking on a filter tag, add it to the url query string like /class/tags?tags=tag1,tag2
+filterTags.forEach((tag) => {
+ tag.addEventListener("click", (e) => {
+ let tag = e.target.innerText;
+ //url encode the tag
+ tag = encodeURIComponent(e.target.innerText);
+ const tags = new URLSearchParams(window.location.search).get("tags");
+
+ // if the tag is already in the query string, remove it
+ let newTags = "";
+ if (tags) {
+ const tagArr = tags.split(",");
+ if (tagArr.includes(tag)) {
+ tagArr.splice(tagArr.indexOf(tag), 1);
+ } else {
+ tagArr.push(tag);
+ }
+ newTags = tagArr.join(",");
+ } else {
+ newTags = tag;
+ }
+
+ window.location.href = `/class/tags?tags=${newTags}`;
+ });
+});
+
+clearFilterBtn.addEventListener("click", (e) => {
+ window.location.href = `/class/tags`;
+});
diff --git a/src/controllers/lessons.js b/src/controllers/lessons.js
index 6e764e7..343c0ed 100644
--- a/src/controllers/lessons.js
+++ b/src/controllers/lessons.js
@@ -175,12 +175,10 @@ export const filterByTags = async (req, res) => {
{ $sort: { _id: 1 } },
]);
- console.log({allTags});
-
if (req.isAuthenticated()) {
lessons = await getAllLessonsProgress(req.user.id, lessons);
}
- res.render("filteredLessons", { lessons, allTags });
+ res.render("filteredLessons", { lessons, allTags, selectedTags: tags });
} catch (err) {
console.log(err);
res.redirect("/class/all");
diff --git a/src/views/filteredLessons.pug b/src/views/filteredLessons.pug
index 7a9b029..de8ea13 100644
--- a/src/views/filteredLessons.pug
+++ b/src/views/filteredLessons.pug
@@ -11,11 +11,26 @@ block content
h1.mb-4 Filter Results
- h4 Results: #{lessons.length}
-
- h4 Filters:
- each tag in allTags || []
- a.mr-2(href=`/class/tags?tags=${tag._id}`) #{tag._id}
+ h4.mt-2 Filters Available:
+
+ #tags
+ .flex.flex-wrap.mb-4
+ each tag in allTags || []
+ button.mr-1.text-xs.mb-1(
+ type="button"
+ class=`filter-tag px-2 py-1 rounded ${
+ selectedTags && selectedTags.includes(tag._id) ? "bg-pink-500 text-white" : "bg-pink-200 text-pink-800"
+ }`) #{tag._id}
+
+
+ button.mr-1.text-xs.mb-1(
+ type="button"
+ id="filter-tag-clear"
+ class=`px-2 py-1 rounded ${
+ selectedTags && selectedTags.length > 1 ? "bg-pink-500 text-white" : "bg-pink-200 text-pink-800"
+ }`) Clear Filters
+
+ h4.mt-2.mb-2 Results: #{lessons.length}
#lessons.grid.gap-y-12.gap-x-16(class="sm:gap-y-24 grid-cols-[repeat(auto-fill,_minmax(285px,_1fr))]")
each lesson in lessons
@@ -27,3 +42,4 @@ append scripts
if loggedIn
script(src="/js/lessonProgress.js")
script(src="/js/lessonDone.js")
+ script(src="/js/filterTags.js")
diff --git a/src/views/lesson.pug b/src/views/lesson.pug
index 2680118..25c77a5 100644
--- a/src/views/lesson.pug
+++ b/src/views/lesson.pug
@@ -82,7 +82,7 @@ block content
p #[a(href=`https://www.youtube.com/watch?v=${lesson.videoId}` target="_blank") Like, comment and subscribe on Youtube]
if assigned.length
- h2.mt-10.mb-3.border-2.border-orange-600.border-dashed Homework Assigned
+ h2.mt-10.mb-3 Homework Assigned
each homework in assigned
.mb-6(class="shadow-[0_2px_10px_0_rgba(0,0,0,0.1)]")
+homework(homework)
From 96dfee4700d4fbbb417d4520dd76c26221c84d7c Mon Sep 17 00:00:00 2001
From: Mario Nikhil Pereira <45009203+nmpereira@users.noreply.github.com>
Date: Sun, 7 Jan 2024 19:42:01 -0500
Subject: [PATCH 08/18] add count of filter results for each tag
---
src/assets/js/filterTags.js | 6 ++++--
src/views/filteredLessons.pug | 6 +++---
2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/src/assets/js/filterTags.js b/src/assets/js/filterTags.js
index 9ec2171..e697748 100644
--- a/src/assets/js/filterTags.js
+++ b/src/assets/js/filterTags.js
@@ -4,9 +4,11 @@ const clearFilterBtn = document.getElementById("filter-tag-clear");
// when clicking on a filter tag, add it to the url query string like /class/tags?tags=tag1,tag2
filterTags.forEach((tag) => {
tag.addEventListener("click", (e) => {
- let tag = e.target.innerText;
+ let tag = e.target.value;
+
//url encode the tag
- tag = encodeURIComponent(e.target.innerText);
+ tag = encodeURIComponent(tag);
+
const tags = new URLSearchParams(window.location.search).get("tags");
// if the tag is already in the query string, remove it
diff --git a/src/views/filteredLessons.pug b/src/views/filteredLessons.pug
index de8ea13..827054e 100644
--- a/src/views/filteredLessons.pug
+++ b/src/views/filteredLessons.pug
@@ -18,10 +18,10 @@ block content
each tag in allTags || []
button.mr-1.text-xs.mb-1(
type="button"
+ value=tag._id
class=`filter-tag px-2 py-1 rounded ${
selectedTags && selectedTags.includes(tag._id) ? "bg-pink-500 text-white" : "bg-pink-200 text-pink-800"
- }`) #{tag._id}
-
+ }`) #{tag._id} (#{tag.count})
button.mr-1.text-xs.mb-1(
type="button"
@@ -30,7 +30,7 @@ block content
selectedTags && selectedTags.length > 1 ? "bg-pink-500 text-white" : "bg-pink-200 text-pink-800"
}`) Clear Filters
- h4.mt-2.mb-2 Results: #{lessons.length}
+ h3.mt-2.mb-2 Results: #{lessons.length}
#lessons.grid.gap-y-12.gap-x-16(class="sm:gap-y-24 grid-cols-[repeat(auto-fill,_minmax(285px,_1fr))]")
each lesson in lessons
From af04d41c2f82e0986ca1c13a8ee7539f9765911f Mon Sep 17 00:00:00 2001
From: Mario Nikhil Pereira <45009203+nmpereira@users.noreply.github.com>
Date: Sun, 7 Jan 2024 19:52:52 -0500
Subject: [PATCH 09/18] fix styling on edit class page
---
src/views/addLesson.pug | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/views/addLesson.pug b/src/views/addLesson.pug
index 9ab7c18..73428b2 100644
--- a/src/views/addLesson.pug
+++ b/src/views/addLesson.pug
@@ -55,9 +55,10 @@ block content
input#ts-title-0(type="text", name="tsTitle")
#tags.col-span-4
h2.col-span-4.mb-3 Tags
- label(for="tags") Tags
+ label(for="tags" class="absolute -ml-2 -mt-2 px-1 text-xs bg-white text-gray-500 rounded") Tags (separated by commas. e.g. html, css, job hunt)
textarea#tag.col-span-4(type="text", name="tags"
placeholder="html, css, javascript, js, career help,ejs"
+ class="h-24 w-full "
) #{edit? lesson.tags : ""}
.col-span-4.mt-3.text-center
button(class="btn primary max-w-1/3 mx-auto" type="submit") #{action} Class
From 7610f44e06eb5318cc19ce565fc17a0f8919f064 Mon Sep 17 00:00:00 2001
From: Mario Nikhil Pereira <45009203+nmpereira@users.noreply.github.com>
Date: Sun, 7 Jan 2024 20:00:50 -0500
Subject: [PATCH 10/18] update the redirect when editing a class
---
src/controllers/lessons.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/controllers/lessons.js b/src/controllers/lessons.js
index 343c0ed..f91ac53 100644
--- a/src/controllers/lessons.js
+++ b/src/controllers/lessons.js
@@ -88,7 +88,7 @@ export const addEditLesson = async (req, res) => {
message: [`Class not ${!!req.params.id ? "updated" : "added"}`],
};
} finally {
- res.redirect("/class/add");
+ res.redirect(`/class/edit/${req.params.id}`);
}
};
From 2f27451653ac0bcecfa4e68194f3266cfcf36277 Mon Sep 17 00:00:00 2001
From: Mario Nikhil Pereira <45009203+nmpereira@users.noreply.github.com>
Date: Sun, 7 Jan 2024 22:05:34 -0500
Subject: [PATCH 11/18] add some final styling
---
src/assets/js/addLesson.js | 61 ++++++++++++++++++---------------
src/assets/js/filterTags.js | 10 +++---
src/controllers/lessons.js | 10 +++---
src/views/addLesson.pug | 4 +--
src/views/filteredLessons.pug | 12 +++----
src/views/lesson.pug | 11 +++---
src/views/mixins/lessonCard.pug | 2 +-
7 files changed, 57 insertions(+), 53 deletions(-)
diff --git a/src/assets/js/addLesson.js b/src/assets/js/addLesson.js
index 1e223fb..5178856 100644
--- a/src/assets/js/addLesson.js
+++ b/src/assets/js/addLesson.js
@@ -1,48 +1,53 @@
-const title = document.getElementById('video-title');
-const videoId = document.getElementById('video-id');
-const classNo = document.getElementById('number');
-const addTsButton = document.getElementById('add-timestamp');
-let tsIndex = document.querySelectorAll('.timestamp').length;
+const title = document.getElementById("video-title");
+const videoId = document.getElementById("video-id");
+const classNo = document.getElementById("number");
+const addTsButton = document.getElementById("add-timestamp");
+let tsIndex = document.querySelectorAll(".timestamp").length;
title.addEventListener("change", addPermalink);
videoId.addEventListener("change", addThumbnail);
classNo.addEventListener("change", updateSlidesClass);
-addTsButton.addEventListener('click', addTimestamp);
+addTsButton.addEventListener("click", addTimestamp);
function addPermalink() {
- const permalink = title.value
-
- .split('')
- .map(c => c.toLowerCase())
- .filter(c => {
- return (c.charCodeAt(0) >= 97 && c.charCodeAt(0) <= 122) || c.charCodeAt(0) === 32;
- })
- .join('')
- .replace(/\s/g, "-");
- document.getElementById("permalink").value = permalink;
- document.getElementById("permalink").disabled = false;
+ const permalink = title.value
+
+ .split("")
+ .map((c) => c.toLowerCase())
+ .filter((c) => {
+ return (
+ (c.charCodeAt(0) >= 97 && c.charCodeAt(0) <= 122) ||
+ c.charCodeAt(0) === 32
+ );
+ })
+ .join("")
+ .replace(/\s/g, "-");
+ document.getElementById("permalink").value = permalink;
+ document.getElementById("permalink").disabled = false;
}
function addThumbnail() {
- const thumbnail = `https://i3.ytimg.com/vi/${videoId.value}/maxresdefault.jpg`;
- document.getElementById("thumbnail").value = thumbnail;
- document.getElementById("thumbnail").disabled = false;
+ const thumbnail = `https://i3.ytimg.com/vi/${videoId.value}/maxresdefault.jpg`;
+ document.getElementById("thumbnail").value = thumbnail;
+ document.getElementById("thumbnail").disabled = false;
}
function updateSlidesClass() {
- document.getElementById("slides-classNo").value = classNo.value;
+ document.getElementById("slides-classNo").value = classNo.value;
}
function addTimestamp(e) {
- e.preventDefault();
- const newTs = document.createElement('div');
- newTs.classList.add('timestamp');
- newTs.innerHTML = `
+ e.preventDefault();
+ const newTs = document.createElement("div");
+ newTs.classList.add("timestamp");
+ newTs.innerHTML = `
`;
- tsIndex += 1;
- document.getElementById('timestamps').append(newTs);
-}
\ No newline at end of file
+ tsIndex += 1;
+ document.getElementById("timestamps").append(newTs);
+}
+
+
diff --git a/src/assets/js/filterTags.js b/src/assets/js/filterTags.js
index e697748..0c4532d 100644
--- a/src/assets/js/filterTags.js
+++ b/src/assets/js/filterTags.js
@@ -4,27 +4,27 @@ const clearFilterBtn = document.getElementById("filter-tag-clear");
// when clicking on a filter tag, add it to the url query string like /class/tags?tags=tag1,tag2
filterTags.forEach((tag) => {
tag.addEventListener("click", (e) => {
- let tag = e.target.value;
+ const tag = e.target.value;
//url encode the tag
- tag = encodeURIComponent(tag);
-
+ const encodedTag = encodeURIComponent(tag);
+
const tags = new URLSearchParams(window.location.search).get("tags");
// if the tag is already in the query string, remove it
let newTags = "";
+
if (tags) {
const tagArr = tags.split(",");
if (tagArr.includes(tag)) {
tagArr.splice(tagArr.indexOf(tag), 1);
} else {
- tagArr.push(tag);
+ tagArr.push(encodedTag);
}
newTags = tagArr.join(",");
} else {
newTags = tag;
}
-
window.location.href = `/class/tags?tags=${newTags}`;
});
});
diff --git a/src/controllers/lessons.js b/src/controllers/lessons.js
index f91ac53..2b2cae8 100644
--- a/src/controllers/lessons.js
+++ b/src/controllers/lessons.js
@@ -169,11 +169,11 @@ export const filterByTags = async (req, res) => {
.sort({ _id: 1 })
.lean();
- const allTags = await Lesson.aggregate([
- { $unwind: "$tags" },
- { $group: { _id: "$tags", count: { $sum: 1 } } },
- { $sort: { _id: 1 } },
- ]);
+ const allTags = await Lesson.aggregate([
+ { $unwind: "$tags" },
+ { $group: { _id: "$tags", count: { $sum: 1 } } },
+ { $sort: { _id: 1 } },
+ ]);
if (req.isAuthenticated()) {
lessons = await getAllLessonsProgress(req.user.id, lessons);
diff --git a/src/views/addLesson.pug b/src/views/addLesson.pug
index 73428b2..50ad590 100644
--- a/src/views/addLesson.pug
+++ b/src/views/addLesson.pug
@@ -56,9 +56,9 @@ block content
#tags.col-span-4
h2.col-span-4.mb-3 Tags
label(for="tags" class="absolute -ml-2 -mt-2 px-1 text-xs bg-white text-gray-500 rounded") Tags (separated by commas. e.g. html, css, job hunt)
- textarea#tag.col-span-4(type="text", name="tags"
+ textarea.col-span-4(type="text", name="tags"
placeholder="html, css, javascript, js, career help,ejs"
- class="h-24 w-full "
+ class="h-24 w-full"
) #{edit? lesson.tags : ""}
.col-span-4.mt-3.text-center
button(class="btn primary max-w-1/3 mx-auto" type="submit") #{action} Class
diff --git a/src/views/filteredLessons.pug b/src/views/filteredLessons.pug
index 827054e..9b81bdf 100644
--- a/src/views/filteredLessons.pug
+++ b/src/views/filteredLessons.pug
@@ -11,26 +11,24 @@ block content
h1.mb-4 Filter Results
- h4.mt-2 Filters Available:
#tags
+ h3.mt-2.mb-2 Filters Available:
.flex.flex-wrap.mb-4
each tag in allTags || []
- button.mr-1.text-xs.mb-1(
+ button.text-xs.m-1(
type="button"
value=tag._id
class=`filter-tag px-2 py-1 rounded ${
- selectedTags && selectedTags.includes(tag._id) ? "bg-pink-500 text-white" : "bg-pink-200 text-pink-800"
+ selectedTags && selectedTags.includes(tag._id) ? "outline outline-1 outline-pink-800 bg-pink-800 text-white" : "outline outline-1 text-pink-800"
}`) #{tag._id} (#{tag.count})
button.mr-1.text-xs.mb-1(
type="button"
id="filter-tag-clear"
- class=`px-2 py-1 rounded ${
- selectedTags && selectedTags.length > 1 ? "bg-pink-500 text-white" : "bg-pink-200 text-pink-800"
- }`) Clear Filters
+ class=`px-2 py-1 rounded bg-pink-800 text-white`) Clear Filters
- h3.mt-2.mb-2 Results: #{lessons.length}
+ h3.mt-2.mb-4 Results: #{lessons.length}
#lessons.grid.gap-y-12.gap-x-16(class="sm:gap-y-24 grid-cols-[repeat(auto-fill,_minmax(285px,_1fr))]")
each lesson in lessons
diff --git a/src/views/lesson.pug b/src/views/lesson.pug
index 25c77a5..473cd73 100644
--- a/src/views/lesson.pug
+++ b/src/views/lesson.pug
@@ -69,11 +69,11 @@ block content
a(href=lesson.motivationLink) #{lesson.motivationTitle}
if lesson.tags && lesson.tags.length
- h2 Tags
- .tags.flex.flex-wrap.px-3.py-2
- each tag in lesson.tags
- a.text-xs.mr-2(href=`/class/tags?tags=${tag}`)
- = tag
+ h2 Tags
+ .tags.flex.flex-wrap.py-2
+ each tag in lesson.tags
+ a.text-sm.mr-2(href=`/class/tags?tags=${tag}`)
+ = tag
@@ -93,6 +93,7 @@ block content
.mb-6(class="shadow-[0_2px_10px_0_rgba(0,0,0,0.1)]")
+homework(homework)
+
append scripts
if loggedIn
script(src="/js/hwDone.js")
diff --git a/src/views/mixins/lessonCard.pug b/src/views/mixins/lessonCard.pug
index 3f4fa38..fe66252 100644
--- a/src/views/mixins/lessonCard.pug
+++ b/src/views/mixins/lessonCard.pug
@@ -36,7 +36,7 @@ mixin lessonCard(lesson)
if lesson.tags && lesson.tags.length
- .tags.flex.flex-wrap.px-3.py-2
+ .tags.flex.flex-wrap.py-2
each tag in lesson.tags
a.text-xs.mr-2(href=`/class/tags?tags=${tag}`)
= tag
From e0b2961491119636253eb4e94567f236e757dab2 Mon Sep 17 00:00:00 2001
From: Mario Nikhil Pereira <45009203+nmpereira@users.noreply.github.com>
Date: Sun, 7 Jan 2024 22:27:31 -0500
Subject: [PATCH 12/18] change endpoint to /filter instead of /tags
---
src/assets/js/filterTags.js | 6 +++---
src/routes/lessonRouter.js | 2 +-
src/views/lesson.pug | 2 +-
src/views/mixins/lessonCard.pug | 2 +-
4 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/assets/js/filterTags.js b/src/assets/js/filterTags.js
index 0c4532d..c957c86 100644
--- a/src/assets/js/filterTags.js
+++ b/src/assets/js/filterTags.js
@@ -1,7 +1,7 @@
const filterTags = document.querySelectorAll(".filter-tag");
const clearFilterBtn = document.getElementById("filter-tag-clear");
-// when clicking on a filter tag, add it to the url query string like /class/tags?tags=tag1,tag2
+// when clicking on a filter tag, add it to the url query string like /class/filter?tags=tag1,tag2
filterTags.forEach((tag) => {
tag.addEventListener("click", (e) => {
const tag = e.target.value;
@@ -25,10 +25,10 @@ filterTags.forEach((tag) => {
} else {
newTags = tag;
}
- window.location.href = `/class/tags?tags=${newTags}`;
+ window.location.href = `/class/filter?tags=${newTags}`;
});
});
clearFilterBtn.addEventListener("click", (e) => {
- window.location.href = `/class/tags`;
+ window.location.href = `/class/filter`;
});
diff --git a/src/routes/lessonRouter.js b/src/routes/lessonRouter.js
index 9d39acd..9ea9de9 100644
--- a/src/routes/lessonRouter.js
+++ b/src/routes/lessonRouter.js
@@ -11,7 +11,7 @@ router.post("/add", lessons.addEditLesson);
router.post("/edit/:id", lessons.addEditLesson);
router.get("/all", lessons.allLessons);
-router.get("/tags", lessons.filterByTags);
+router.get("/filter", lessons.filterByTags);
router.get("/:permalink", lessons.showLesson);
router.put("/watched/:id", lessons.toggleWatched);
diff --git a/src/views/lesson.pug b/src/views/lesson.pug
index 473cd73..efbb952 100644
--- a/src/views/lesson.pug
+++ b/src/views/lesson.pug
@@ -72,7 +72,7 @@ block content
h2 Tags
.tags.flex.flex-wrap.py-2
each tag in lesson.tags
- a.text-sm.mr-2(href=`/class/tags?tags=${tag}`)
+ a.text-sm.mr-2(href=`/class/filter?tags=${tag}`)
= tag
diff --git a/src/views/mixins/lessonCard.pug b/src/views/mixins/lessonCard.pug
index fe66252..6f9cda5 100644
--- a/src/views/mixins/lessonCard.pug
+++ b/src/views/mixins/lessonCard.pug
@@ -38,7 +38,7 @@ mixin lessonCard(lesson)
.tags.flex.flex-wrap.py-2
each tag in lesson.tags
- a.text-xs.mr-2(href=`/class/tags?tags=${tag}`)
+ a.text-xs.mr-2(href=`/class/filter?tags=${tag}`)
= tag
a.absolute.bottom-3(href=`/class/${lesson.permalink}`) More Info
From 7152aa35677aca24b9b4f93da50d9b0b905eaa7d Mon Sep 17 00:00:00 2001
From: Mario Nikhil Pereira <45009203+nmpereira@users.noreply.github.com>
Date: Sun, 7 Jan 2024 22:43:06 -0500
Subject: [PATCH 13/18] whitespace/formatting changes
---
src/assets/js/addLesson.js | 61 +++++++++++++++------------------
src/views/mixins/lessonCard.pug | 6 +---
2 files changed, 29 insertions(+), 38 deletions(-)
diff --git a/src/assets/js/addLesson.js b/src/assets/js/addLesson.js
index 5178856..5b8070c 100644
--- a/src/assets/js/addLesson.js
+++ b/src/assets/js/addLesson.js
@@ -1,53 +1,48 @@
-const title = document.getElementById("video-title");
-const videoId = document.getElementById("video-id");
-const classNo = document.getElementById("number");
-const addTsButton = document.getElementById("add-timestamp");
-let tsIndex = document.querySelectorAll(".timestamp").length;
+const title = document.getElementById('video-title');
+const videoId = document.getElementById('video-id');
+const classNo = document.getElementById('number');
+const addTsButton = document.getElementById('add-timestamp');
+let tsIndex = document.querySelectorAll('.timestamp').length;
title.addEventListener("change", addPermalink);
videoId.addEventListener("change", addThumbnail);
classNo.addEventListener("change", updateSlidesClass);
-addTsButton.addEventListener("click", addTimestamp);
+addTsButton.addEventListener('click', addTimestamp);
function addPermalink() {
- const permalink = title.value
-
- .split("")
- .map((c) => c.toLowerCase())
- .filter((c) => {
- return (
- (c.charCodeAt(0) >= 97 && c.charCodeAt(0) <= 122) ||
- c.charCodeAt(0) === 32
- );
- })
- .join("")
- .replace(/\s/g, "-");
- document.getElementById("permalink").value = permalink;
- document.getElementById("permalink").disabled = false;
+ const permalink = title.value
+
+ .split('')
+ .map(c => c.toLowerCase())
+ .filter(c => {
+ return (c.charCodeAt(0) >= 97 && c.charCodeAt(0) <= 122) || c.charCodeAt(0) === 32;
+ })
+ .join('')
+ .replace(/\s/g, "-");
+ document.getElementById("permalink").value = permalink;
+ document.getElementById("permalink").disabled = false;
}
function addThumbnail() {
- const thumbnail = `https://i3.ytimg.com/vi/${videoId.value}/maxresdefault.jpg`;
- document.getElementById("thumbnail").value = thumbnail;
- document.getElementById("thumbnail").disabled = false;
+ const thumbnail = `https://i3.ytimg.com/vi/${videoId.value}/maxresdefault.jpg`;
+ document.getElementById("thumbnail").value = thumbnail;
+ document.getElementById("thumbnail").disabled = false;
}
function updateSlidesClass() {
- document.getElementById("slides-classNo").value = classNo.value;
+ document.getElementById("slides-classNo").value = classNo.value;
}
function addTimestamp(e) {
- e.preventDefault();
- const newTs = document.createElement("div");
- newTs.classList.add("timestamp");
- newTs.innerHTML = `
+ e.preventDefault();
+ const newTs = document.createElement('div');
+ newTs.classList.add('timestamp');
+ newTs.innerHTML = `
`;
- tsIndex += 1;
- document.getElementById("timestamps").append(newTs);
-}
-
-
+ tsIndex += 1;
+ document.getElementById('timestamps').append(newTs);
+}
\ No newline at end of file
diff --git a/src/views/mixins/lessonCard.pug b/src/views/mixins/lessonCard.pug
index 6f9cda5..5765d0b 100644
--- a/src/views/mixins/lessonCard.pug
+++ b/src/views/mixins/lessonCard.pug
@@ -26,16 +26,12 @@ mixin lessonCard(lesson)
input.checkedin.hidden(type="checkbox" id="checkedin-" + lesson._id autocomplete="off" checked)
| No Check In
-
-
.card-main-content.py-4.px-6.mb-12.group
a(href=`/class/${lesson.permalink}` class="hover:no-underline")
img.w-full.mb-2(src=lesson.thumbnail class="group-hover:shadow-[0_0_10px_rgba(0,_0,_0,_0.2)]")
h2(class="group-hover:text-pink-900") #{lesson.title}
-
-
- if lesson.tags && lesson.tags.length
+ if lesson.tags && lesson.tags.length
.tags.flex.flex-wrap.py-2
each tag in lesson.tags
a.text-xs.mr-2(href=`/class/filter?tags=${tag}`)
From 0eb9bba51521a1c8f62237815a3379eeaf2909cf Mon Sep 17 00:00:00 2001
From: Mario Nikhil Pereira <45009203+nmpereira@users.noreply.github.com>
Date: Sun, 7 Jan 2024 22:49:00 -0500
Subject: [PATCH 14/18] remove comment
---
src/tailwind.css | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/tailwind.css b/src/tailwind.css
index 0228592..4c51e49 100644
--- a/src/tailwind.css
+++ b/src/tailwind.css
@@ -86,7 +86,6 @@
}
#timestamps,
#tags,
- /* do i need to add this here? */
#hw-items,
#pw-items {
@apply mt-3 w-full border px-5 py-3;
From f27de2f22f2d7827405718c008edd60d00c290e6 Mon Sep 17 00:00:00 2001
From: Mario Nikhil Pereira <45009203+nmpereira@users.noreply.github.com>
Date: Mon, 8 Jan 2024 01:33:33 -0500
Subject: [PATCH 15/18] fix bug with crash when there are no tags
---
src/controllers/lessons.js | 2 ++
src/views/lesson.pug | 10 +++++-----
2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/src/controllers/lessons.js b/src/controllers/lessons.js
index 2b2cae8..fec5945 100644
--- a/src/controllers/lessons.js
+++ b/src/controllers/lessons.js
@@ -149,6 +149,8 @@ export const showLesson = async (req, res) => {
.sort({ _id: 1 })
.populate(["items", "extras"]);
+ lesson?.tags ? lesson.tags.sort() : (lesson.tags = []);
+
if (req.isAuthenticated()) {
lesson = await getLessonProgress(req.user.id, lesson);
if (assigned.length)
diff --git a/src/views/lesson.pug b/src/views/lesson.pug
index efbb952..02f7d5a 100644
--- a/src/views/lesson.pug
+++ b/src/views/lesson.pug
@@ -69,11 +69,11 @@ block content
a(href=lesson.motivationLink) #{lesson.motivationTitle}
if lesson.tags && lesson.tags.length
- h2 Tags
- .tags.flex.flex-wrap.py-2
- each tag in lesson.tags
- a.text-sm.mr-2(href=`/class/filter?tags=${tag}`)
- = tag
+ h2 Tags
+ .tags.flex.flex-wrap.py-2
+ each tag in lesson.tags
+ a.text-sm.mr-2(href=`/class/filter?tags=${tag}`)
+ = tag
From 10f29e3b032f9870f58d871fb8b9461f26217c17 Mon Sep 17 00:00:00 2001
From: Mario Nikhil Pereira <45009203+nmpereira@users.noreply.github.com>
Date: Thu, 11 Jan 2024 22:06:56 -0500
Subject: [PATCH 16/18] changes from self review
---
src/assets/css/index.css | 149 ++++++++++++++++++------------------
src/assets/js/filterTags.js | 6 +-
src/controllers/lessons.js | 4 +-
3 files changed, 82 insertions(+), 77 deletions(-)
diff --git a/src/assets/css/index.css b/src/assets/css/index.css
index b68f0f4..39a1343 100644
--- a/src/assets/css/index.css
+++ b/src/assets/css/index.css
@@ -902,6 +902,7 @@ h3 {
}
#timestamps,
+ #tags,
#hw-items,
#pw-items {
margin-top: 0.75rem;
@@ -1243,6 +1244,10 @@ dd ol {
top: 0px;
}
+.left-10 {
+ left: 2.5rem;
+}
+
.top-12 {
top: 3rem;
}
@@ -1259,34 +1264,6 @@ dd ol {
right: 0.25rem;
}
-.top-10 {
- top: 2.5rem;
-}
-
-.top-8 {
- top: 2rem;
-}
-
-.-left-20 {
- left: -5rem;
-}
-
-.left-0 {
- left: 0px;
-}
-
-.left-10 {
- left: 2.5rem;
-}
-
-.left-5 {
- left: 1.25rem;
-}
-
-.left-9 {
- left: 2.25rem;
-}
-
.z-10 {
z-index: 10;
}
@@ -1315,6 +1292,10 @@ dd ol {
margin: 0.5rem;
}
+.m-1 {
+ margin: 0.25rem;
+}
+
.m-0 {
margin: 0px;
}
@@ -1365,6 +1346,14 @@ dd ol {
margin-top: 0.75rem;
}
+.-ml-2 {
+ margin-left: -0.5rem;
+}
+
+.-mt-2 {
+ margin-top: -0.5rem;
+}
+
.mb-4 {
margin-bottom: 1rem;
}
@@ -1373,6 +1362,10 @@ dd ol {
margin-right: auto;
}
+.mr-1 {
+ margin-right: 0.25rem;
+}
+
.mb-1 {
margin-bottom: 0.25rem;
}
@@ -1441,8 +1434,8 @@ dd ol {
height: auto;
}
-.min-h-screen {
- min-height: 100vh;
+.h-24 {
+ height: 6rem;
}
.w-full {
@@ -1566,6 +1559,10 @@ dd ol {
white-space: nowrap;
}
+.rounded {
+ border-radius: 0.25rem;
+}
+
.border {
border-width: 1px;
}
@@ -1597,6 +1594,11 @@ dd ol {
border-color: rgb(231 229 228 / var(--tw-border-opacity));
}
+.bg-white {
+ --tw-bg-opacity: 1;
+ background-color: rgb(255 255 255 / var(--tw-bg-opacity));
+}
+
.bg-pink-800 {
--tw-bg-opacity: 1;
background-color: rgb(157 23 77 / var(--tw-bg-opacity));
@@ -1612,11 +1614,6 @@ dd ol {
background-color: rgb(250 250 249 / var(--tw-bg-opacity));
}
-.bg-white {
- --tw-bg-opacity: 1;
- background-color: rgb(255 255 255 / var(--tw-bg-opacity));
-}
-
.p-6 {
padding: 1.5rem;
}
@@ -1625,6 +1622,21 @@ dd ol {
padding: 0px;
}
+.px-1 {
+ padding-left: 0.25rem;
+ padding-right: 0.25rem;
+}
+
+.px-2 {
+ padding-left: 0.5rem;
+ padding-right: 0.5rem;
+}
+
+.py-1 {
+ padding-top: 0.25rem;
+ padding-bottom: 0.25rem;
+}
+
.py-2 {
padding-top: 0.5rem;
padding-bottom: 0.5rem;
@@ -1689,14 +1701,15 @@ dd ol {
text-align: right;
}
-.font-main {
- font-family: Poppins, sans-serif;
-}
-
.font-logo {
font-family: Orienta, serif;
}
+.text-xs {
+ font-size: 0.75rem;
+ line-height: 1rem;
+}
+
.text-xl {
font-size: 1.25rem;
line-height: 1.75rem;
@@ -1707,11 +1720,6 @@ dd ol {
line-height: 1.5rem;
}
-.text-lg {
- font-size: 1.125rem;
- line-height: 1.75rem;
-}
-
.text-sm {
font-size: 0.875rem;
line-height: 1.25rem;
@@ -1722,11 +1730,6 @@ dd ol {
line-height: 2rem;
}
-.text-xs {
- font-size: 0.75rem;
- line-height: 1rem;
-}
-
.text-3xl {
font-size: 1.875rem;
line-height: 2.25rem;
@@ -1766,14 +1769,14 @@ dd ol {
color: rgb(239 68 68 / var(--tw-text-opacity));
}
-.text-twilight-900 {
+.text-gray-500 {
--tw-text-opacity: 1;
- color: rgb(21 63 81 / var(--tw-text-opacity));
+ color: rgb(107 114 128 / var(--tw-text-opacity));
}
-.text-stone-500 {
+.text-twilight-900 {
--tw-text-opacity: 1;
- color: rgb(120 113 108 / var(--tw-text-opacity));
+ color: rgb(21 63 81 / var(--tw-text-opacity));
}
.text-white {
@@ -1786,14 +1789,14 @@ dd ol {
color: rgb(157 23 77 / var(--tw-text-opacity));
}
-.text-twilight-800 {
+.text-stone-500 {
--tw-text-opacity: 1;
- color: rgb(34 101 129 / var(--tw-text-opacity));
+ color: rgb(120 113 108 / var(--tw-text-opacity));
}
-.text-stone-800 {
+.text-twilight-800 {
--tw-text-opacity: 1;
- color: rgb(41 37 36 / var(--tw-text-opacity));
+ color: rgb(34 101 129 / var(--tw-text-opacity));
}
.text-red-800 {
@@ -1805,15 +1808,15 @@ dd ol {
color: rgb(168 162 158 / 0.8);
}
-.text-pink-800\/80 {
- color: rgb(157 23 77 / 0.8);
-}
-
.text-red-700 {
--tw-text-opacity: 1;
color: rgb(185 28 28 / var(--tw-text-opacity));
}
+.text-pink-800\/80 {
+ color: rgb(157 23 77 / 0.8);
+}
+
.no-underline {
text-decoration-line: none;
}
@@ -1842,6 +1845,18 @@ dd ol {
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
+.outline {
+ outline-style: solid;
+}
+
+.outline-1 {
+ outline-width: 1px;
+}
+
+.outline-pink-800 {
+ outline-color: #9d174d;
+}
+
.filter {
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
}
@@ -1883,10 +1898,6 @@ dd ol {
}
@media (min-width: 780px) {
- .sm\:left-8 {
- left: 2rem;
- }
-
.sm\:left-12 {
left: 3rem;
}
@@ -1955,14 +1966,6 @@ dd ol {
}
@media (min-width: 1024px) {
- .lg\:left-14 {
- left: 3.5rem;
- }
-
- .lg\:left-16 {
- left: 4rem;
- }
-
.lg\:left-20 {
left: 5rem;
}
diff --git a/src/assets/js/filterTags.js b/src/assets/js/filterTags.js
index c957c86..3b9efef 100644
--- a/src/assets/js/filterTags.js
+++ b/src/assets/js/filterTags.js
@@ -9,13 +9,13 @@ filterTags.forEach((tag) => {
//url encode the tag
const encodedTag = encodeURIComponent(tag);
- const tags = new URLSearchParams(window.location.search).get("tags");
+ const existTags = new URLSearchParams(window.location.search).get("tags");
// if the tag is already in the query string, remove it
let newTags = "";
- if (tags) {
- const tagArr = tags.split(",");
+ if (existTags) {
+ const tagArr = existTags.split(",");
if (tagArr.includes(tag)) {
tagArr.splice(tagArr.indexOf(tag), 1);
} else {
diff --git a/src/controllers/lessons.js b/src/controllers/lessons.js
index fec5945..298cfab 100644
--- a/src/controllers/lessons.js
+++ b/src/controllers/lessons.js
@@ -149,7 +149,9 @@ export const showLesson = async (req, res) => {
.sort({ _id: 1 })
.populate(["items", "extras"]);
- lesson?.tags ? lesson.tags.sort() : (lesson.tags = []);
+ if (!lesson?.tags) {
+ lesson.tags = [];
+ }
if (req.isAuthenticated()) {
lesson = await getLessonProgress(req.user.id, lesson);
From 4d421ce3447b6b1793c0c5c80781c5cf5a25b37d Mon Sep 17 00:00:00 2001
From: Mario Nikhil Pereira <45009203+nmpereira@users.noreply.github.com>
Date: Thu, 11 Jan 2024 23:27:32 -0500
Subject: [PATCH 17/18] revert index.css
---
src/assets/css/index.css | 149 +++++++++++++++++++--------------------
1 file changed, 73 insertions(+), 76 deletions(-)
diff --git a/src/assets/css/index.css b/src/assets/css/index.css
index 39a1343..b68f0f4 100644
--- a/src/assets/css/index.css
+++ b/src/assets/css/index.css
@@ -902,7 +902,6 @@ h3 {
}
#timestamps,
- #tags,
#hw-items,
#pw-items {
margin-top: 0.75rem;
@@ -1244,10 +1243,6 @@ dd ol {
top: 0px;
}
-.left-10 {
- left: 2.5rem;
-}
-
.top-12 {
top: 3rem;
}
@@ -1264,6 +1259,34 @@ dd ol {
right: 0.25rem;
}
+.top-10 {
+ top: 2.5rem;
+}
+
+.top-8 {
+ top: 2rem;
+}
+
+.-left-20 {
+ left: -5rem;
+}
+
+.left-0 {
+ left: 0px;
+}
+
+.left-10 {
+ left: 2.5rem;
+}
+
+.left-5 {
+ left: 1.25rem;
+}
+
+.left-9 {
+ left: 2.25rem;
+}
+
.z-10 {
z-index: 10;
}
@@ -1292,10 +1315,6 @@ dd ol {
margin: 0.5rem;
}
-.m-1 {
- margin: 0.25rem;
-}
-
.m-0 {
margin: 0px;
}
@@ -1346,14 +1365,6 @@ dd ol {
margin-top: 0.75rem;
}
-.-ml-2 {
- margin-left: -0.5rem;
-}
-
-.-mt-2 {
- margin-top: -0.5rem;
-}
-
.mb-4 {
margin-bottom: 1rem;
}
@@ -1362,10 +1373,6 @@ dd ol {
margin-right: auto;
}
-.mr-1 {
- margin-right: 0.25rem;
-}
-
.mb-1 {
margin-bottom: 0.25rem;
}
@@ -1434,8 +1441,8 @@ dd ol {
height: auto;
}
-.h-24 {
- height: 6rem;
+.min-h-screen {
+ min-height: 100vh;
}
.w-full {
@@ -1559,10 +1566,6 @@ dd ol {
white-space: nowrap;
}
-.rounded {
- border-radius: 0.25rem;
-}
-
.border {
border-width: 1px;
}
@@ -1594,11 +1597,6 @@ dd ol {
border-color: rgb(231 229 228 / var(--tw-border-opacity));
}
-.bg-white {
- --tw-bg-opacity: 1;
- background-color: rgb(255 255 255 / var(--tw-bg-opacity));
-}
-
.bg-pink-800 {
--tw-bg-opacity: 1;
background-color: rgb(157 23 77 / var(--tw-bg-opacity));
@@ -1614,6 +1612,11 @@ dd ol {
background-color: rgb(250 250 249 / var(--tw-bg-opacity));
}
+.bg-white {
+ --tw-bg-opacity: 1;
+ background-color: rgb(255 255 255 / var(--tw-bg-opacity));
+}
+
.p-6 {
padding: 1.5rem;
}
@@ -1622,21 +1625,6 @@ dd ol {
padding: 0px;
}
-.px-1 {
- padding-left: 0.25rem;
- padding-right: 0.25rem;
-}
-
-.px-2 {
- padding-left: 0.5rem;
- padding-right: 0.5rem;
-}
-
-.py-1 {
- padding-top: 0.25rem;
- padding-bottom: 0.25rem;
-}
-
.py-2 {
padding-top: 0.5rem;
padding-bottom: 0.5rem;
@@ -1701,13 +1689,12 @@ dd ol {
text-align: right;
}
-.font-logo {
- font-family: Orienta, serif;
+.font-main {
+ font-family: Poppins, sans-serif;
}
-.text-xs {
- font-size: 0.75rem;
- line-height: 1rem;
+.font-logo {
+ font-family: Orienta, serif;
}
.text-xl {
@@ -1720,6 +1707,11 @@ dd ol {
line-height: 1.5rem;
}
+.text-lg {
+ font-size: 1.125rem;
+ line-height: 1.75rem;
+}
+
.text-sm {
font-size: 0.875rem;
line-height: 1.25rem;
@@ -1730,6 +1722,11 @@ dd ol {
line-height: 2rem;
}
+.text-xs {
+ font-size: 0.75rem;
+ line-height: 1rem;
+}
+
.text-3xl {
font-size: 1.875rem;
line-height: 2.25rem;
@@ -1769,14 +1766,14 @@ dd ol {
color: rgb(239 68 68 / var(--tw-text-opacity));
}
-.text-gray-500 {
+.text-twilight-900 {
--tw-text-opacity: 1;
- color: rgb(107 114 128 / var(--tw-text-opacity));
+ color: rgb(21 63 81 / var(--tw-text-opacity));
}
-.text-twilight-900 {
+.text-stone-500 {
--tw-text-opacity: 1;
- color: rgb(21 63 81 / var(--tw-text-opacity));
+ color: rgb(120 113 108 / var(--tw-text-opacity));
}
.text-white {
@@ -1789,14 +1786,14 @@ dd ol {
color: rgb(157 23 77 / var(--tw-text-opacity));
}
-.text-stone-500 {
+.text-twilight-800 {
--tw-text-opacity: 1;
- color: rgb(120 113 108 / var(--tw-text-opacity));
+ color: rgb(34 101 129 / var(--tw-text-opacity));
}
-.text-twilight-800 {
+.text-stone-800 {
--tw-text-opacity: 1;
- color: rgb(34 101 129 / var(--tw-text-opacity));
+ color: rgb(41 37 36 / var(--tw-text-opacity));
}
.text-red-800 {
@@ -1808,15 +1805,15 @@ dd ol {
color: rgb(168 162 158 / 0.8);
}
+.text-pink-800\/80 {
+ color: rgb(157 23 77 / 0.8);
+}
+
.text-red-700 {
--tw-text-opacity: 1;
color: rgb(185 28 28 / var(--tw-text-opacity));
}
-.text-pink-800\/80 {
- color: rgb(157 23 77 / 0.8);
-}
-
.no-underline {
text-decoration-line: none;
}
@@ -1845,18 +1842,6 @@ dd ol {
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
-.outline {
- outline-style: solid;
-}
-
-.outline-1 {
- outline-width: 1px;
-}
-
-.outline-pink-800 {
- outline-color: #9d174d;
-}
-
.filter {
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
}
@@ -1898,6 +1883,10 @@ dd ol {
}
@media (min-width: 780px) {
+ .sm\:left-8 {
+ left: 2rem;
+ }
+
.sm\:left-12 {
left: 3rem;
}
@@ -1966,6 +1955,14 @@ dd ol {
}
@media (min-width: 1024px) {
+ .lg\:left-14 {
+ left: 3.5rem;
+ }
+
+ .lg\:left-16 {
+ left: 4rem;
+ }
+
.lg\:left-20 {
left: 5rem;
}
From c56f36e41e51e83554a1ce92656894e9505dfaa9 Mon Sep 17 00:00:00 2001
From: Mario Nikhil Pereira <45009203+nmpereira@users.noreply.github.com>
Date: Thu, 11 Jan 2024 23:29:22 -0500
Subject: [PATCH 18/18] update to remove login condition for js script
---
src/views/filteredLessons.pug | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/views/filteredLessons.pug b/src/views/filteredLessons.pug
index 9b81bdf..fc3fb84 100644
--- a/src/views/filteredLessons.pug
+++ b/src/views/filteredLessons.pug
@@ -37,7 +37,7 @@ block content
include ./partials/to-top.pug
append scripts
+ script(src="/js/filterTags.js")
if loggedIn
script(src="/js/lessonProgress.js")
script(src="/js/lessonDone.js")
- script(src="/js/filterTags.js")