Skip to content
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
928f81f
feat(faq-page): added model and controller for faq
willjinjin Apr 27, 2026
67ca058
feat(faq-backend): added route for faq
willjinjin Apr 27, 2026
fb4e8e2
feat(faq-backend): added route and updated index to accomodate faq
willjinjin Apr 27, 2026
0375cd4
feat(faq-backend): added try catch error handling
willjinjin Apr 27, 2026
d7094ac
feat(faq-backend_: updated faq to fetch faq data from mongodb instead…
willjinjin Apr 27, 2026
cd5744a
Merge branch 'feat/faq-page' into feat/faq-backend
willjinjin May 3, 2026
1964756
chore(faq-backend): merged main into faq-backend
willjinjin May 3, 2026
86766b9
chore(faq-backend): ran prettier on faq backend related pages
willjinjin May 3, 2026
0fb0bcf
chore(faq-backend): merged main into branch
willjinjin May 10, 2026
27f140a
chore(faq-backend): removed placeholder for faq
willjinjin May 10, 2026
ba4bf13
feat(faq-backend): implemented timer-based caching for faq page
willjinjin May 10, 2026
07178bd
chore(faq-backend): changed faq function name to getFaqs, also change…
willjinjin May 10, 2026
1d73ab3
feat(faq-backend): created createFaq function for faqs
willjinjin May 10, 2026
780da47
feat(faq-backend): created updateFaq function for faq page
willjinjin May 10, 2026
3f2948b
feat(faq-backend): created deleteFaq function for faq page
willjinjin May 10, 2026
dfb8103
fix(faq-backend): fixed a route error where all 4 used get
willjinjin May 10, 2026
175e18c
feat(faq-frontend): updated frontend to accomodate new faq schema by …
willjinjin May 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions client/src/pages/Faq.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,28 @@
import React, { useState, useEffect } from "react";
import Collapsible from "../components/Collapsible";

import "../style/faq.css";
import "../style/common.css";
import faqs from "../placeholders/faqs.json";

interface Faq {
question: string;
answer: string;
}

const Faq = () => {
const [faqs, setFaqs] = useState<Faq[]>([]);

useEffect(() => {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you're hooking up backend to frontend, run a function to parse the content into the desired faq item format. Maybe new lines starting with a # could be used to determine a question, and then the text in the lines below (until the next #) will be that question's answer.

fetch("/api/faqs")
.then((res) => res.json())
.then((data) => setFaqs(data))
.catch((err) => console.error("Failed to fetch faqs:", err));
}, []);

return (
<div className="faq-container yellow-bg">
{/** title */}
<section className="faq-title">F&nbsp;A&nbsp;Q&nbsp;s</section>

{/** faq items */}
<section className="faq-list">
{faqs.map((item, index) => (
Expand Down
12 changes: 12 additions & 0 deletions server/src/controllers/faqController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { RequestHandler } from "express";
import { Faq } from "../model/faq";

export const listFaqs: RequestHandler = async (req, res) => {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since FAQs are unlikely to be updated often, we should look into some sort of caching if possible (might just be as simple as not hitting the DB until timeout or on outdated version).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: getFaqs would be a better function name (a bit more conventional for web servers)

try {
const faqs = await Faq.find().lean();
res.json(faqs);
} catch (error) {
console.error("Error fetching FAQs:", error);
res.status(500).json({ message: "Failed to fetch FAQs" });
}
};
3 changes: 2 additions & 1 deletion server/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Strategy as GoogleStrategy } from "passport-google-oauth20";
import authRoutes from "./routes/authRoutes";
import imageRoutes from "./routes/imageRoutes";
import executivesRoutes from "./routes/executivesRoutes";

import faqRoutes from "./routes/faqRoutes";
// app config
dotenv.config({ quiet: true });

Expand Down Expand Up @@ -47,6 +47,7 @@ app.use(express.json());
app.use("/api/auth", authRoutes);
app.use("/api/images", imageRoutes);
app.use("/api/executives", executivesRoutes);
app.use("/api/faqs", faqRoutes);

// Connect to MongoDB and start the server
mongoose
Expand Down
12 changes: 12 additions & 0 deletions server/src/model/faq.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import mongoose from "mongoose";
const { Schema, model } = mongoose;

const faqSchema = new Schema(
{
question: { type: String, required: true },
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The schema we want instead is a single object like

{
    content: { type: String, required: true },
    timestamp: { type: Date, required: true },
}

Expanding a bit more on why the ticket wants this, allowing admins to directly edit the entire FAQ rather than a bit at a time will probably be a lot easier for them (and for us since we won't have to design a bunch of extra functionality!).

Having this also gives us the potential basis to extend the FAQ backend into a larger 'content' backend, which allows for the editing of text fields in other importantn places.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh whoops, turns out there's a nice and easy way for Mongo/mongoose to automatically add timestamps

{
    content: { type: String, required: true },
},
{ timestamps: true, versionKey: false }

answer: { type: String, required: true },
},
{ versionKey: false }
);

export const Faq = model("Faq", faqSchema);
7 changes: 7 additions & 0 deletions server/src/routes/faqRoutes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import express from "express";
import { listFaqs } from "../controllers/faqController";

const router = express.Router();
router.get("/", listFaqs);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per the ticket we should also include the ability for admins to update the FAQ page, make sure to create an endpoint for this and then test it out with Postman

export default router;
Loading