Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/arnav jacob/page footer #15

Merged
merged 31 commits into from
Feb 13, 2024
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
a21a924
create components and style folders
Arnav710 Jan 18, 2024
3681152
Adds icons for the page footer
jackavh Jan 18, 2024
efe1781
Merge branch 'feature/arnav-jacob/page-footer' of https://github.com/…
jackavh Jan 18, 2024
fc29221
dummy footer
Arnav710 Jan 19, 2024
bdcfafd
add footer component to page.tsx
Arnav710 Jan 19, 2024
e428bd2
create footer structure + color
Arnav710 Jan 19, 2024
1ac1fc6
Adds four screens to the page footer
jackavh Jan 19, 2024
4ce1ad0
adds logo image, facebook and instagram links, and copyright message …
jackavh Jan 22, 2024
418a94a
newsletter + links section of footer
Arnav710 Jan 23, 2024
8c99dea
updates styles on footer.css to look close to figma design
jackavh Jan 23, 2024
0603e5b
newsletter section
Arnav710 Jan 29, 2024
7daf528
Merge branch 'main' into feature/arnav-jacob/page-footer
jackavh Jan 29, 2024
de8b6c1
imports all fonts and adds checkmark to button, updates some styles
jackavh Jan 29, 2024
ec23938
adds POST /api/subscribers backend route that validates uniqueness fo…
jackavh Jan 29, 2024
5716cd4
adding the api/subscribers route to the frontend
Arnav710 Jan 29, 2024
deacef8
fix button logic
Arnav710 Jan 29, 2024
20d2200
refactors frontend api routes to be consistent with other branches. s…
jackavh Jan 30, 2024
04025b7
consolidates error messages for the newsletter subscription box
jackavh Jan 31, 2024
51c06ab
merging main:
Arnav710 Feb 1, 2024
7ccd1d8
changes facebook and instagram icons from png to svg
jackavh Feb 2, 2024
2e3a02c
fixes lint check errors for pr
jackavh Feb 2, 2024
efd5dee
fixes frontend lint check for pr
jackavh Feb 2, 2024
51713cf
Added Footer component to layout and fonts to globals
jennymar Feb 6, 2024
5ba5df4
frontend linting
jennymar Feb 6, 2024
a358155
Delete .DS_Store
jennymar Feb 6, 2024
791c06d
changes internal link <a> tags to <Link> tags
jackavh Feb 6, 2024
be202e8
Css layout and linting fixes (thx andrew)
jennymar Feb 10, 2024
f424394
Re added tsconfig.json
jennymar Feb 12, 2024
f73dcd9
Merge branch 'main' into feature/arnav-jacob/page-footer
jennymar Feb 12, 2024
f2ae6ea
Linting
jennymar Feb 12, 2024
6603351
CSS fixes after merging main into branch
jennymar Feb 12, 2024
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
Binary file added .DS_Store
Binary file not shown.
23 changes: 0 additions & 23 deletions .husky/lint-config.sh

This file was deleted.

216 changes: 0 additions & 216 deletions .husky/pre-commit

This file was deleted.

3 changes: 0 additions & 3 deletions .husky/pre-push

This file was deleted.

3 changes: 2 additions & 1 deletion backend/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import "dotenv/config";
import cors from "cors";
import express, { NextFunction, Request, Response } from "express";
import { isHttpError } from "http-errors";
import subscriberRoutes from "src/routes/subscriber";

const app = express();

Expand All @@ -23,7 +24,7 @@ app.use(
}),
);

// Routes ( e.g. app.use("/api/task", taskRoutes); )
app.use("/api/subscribers", subscriberRoutes);

/**
* Error handler; all errors thrown by server are handled here.
Expand Down
32 changes: 32 additions & 0 deletions backend/src/controllers/subscriber.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Controller for the newsletter subscriber route, /api/subscribers.
* passes error handling off to /src/util/validationErrorParser.ts
*/

import { RequestHandler } from "express";
import { validationResult } from "express-validator";
import Subscriber from "src/models/subscriber";
import validationErrorParser from "src/util/validationErrorParser";

export const createSubscriber: RequestHandler = async (req, res, next) => {
const errors = validationResult(req);
const { email } = req.body;

try {
// validationErrorParser is a helper that throws 400 if there are errors
validationErrorParser(errors);
const subscriber = await Subscriber.create({
email: email,
});

/*
* TODO: Handle adding the newsletter subscriber
* to a mailing list or however this will be handled.
*/

// successfully created subscriber in db
res.status(201).json(subscriber);
} catch (error) {
next(error);
}
};
13 changes: 13 additions & 0 deletions backend/src/models/subscriber.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* Defines the schema for a newsletter subscriber
*/

import { InferSchemaType, Schema, model } from "mongoose";

const subscriberSchema = new Schema({
email: { type: String, required: true },
});

type Subscriber = InferSchemaType<typeof subscriberSchema>;

export default model<Subscriber>("Subscriber", subscriberSchema);
13 changes: 13 additions & 0 deletions backend/src/routes/subscriber.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* Newsletter subscription route requests.
*/

import express from "express";
import * as SubscriberController from "src/controllers/subscriber";
import * as SubscriberValidator from "src/validators/subscriber";

const router = express.Router();

router.post("/", SubscriberValidator.createSubscriber, SubscriberController.createSubscriber);

export default router;
25 changes: 25 additions & 0 deletions backend/src/util/validationErrorParser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Result, ValidationError } from "express-validator";
import createHttpError from "http-errors";

/**
* Parses through errors thrown by validator (if any exist). Error messages are
* added to a string and that string is used as the error message for the HTTP
* error.
*
* @param errors the validation result provided by express validator middleware
*/
const validationErrorParser = (errors: Result<ValidationError>) => {
if (!errors.isEmpty()) {
let errorString = "";

// parse through errors returned by the validator and append them to the error string
for (const error of errors.array()) {
errorString += error.msg + " ";
}

// trim removes the trailing space created in the for loop
throw createHttpError(400, errorString.trim());
}
};

export default validationErrorParser;
34 changes: 34 additions & 0 deletions backend/src/validators/subscriber.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Normalize and validate emails for newsletter subscribers
* in the route handler.
*/

import { body } from "express-validator";
import Subscriber from "src/models/subscriber";

/*
* 1. Trim whitespace then
* 2. check if empty then
* 3. check if valid email then
* 4. normalize email then
* 5. check if email already exists in db
*/
const makeEmailValidator = () =>
body("email")
.trim()
.exists()
.withMessage("email is required")
.bail()
.isEmail()
.withMessage("email must be a valid email address")
.bail()
.normalizeEmail()
.custom(async (value) => {
// check if email already exists in db
const subscriber = await Subscriber.findOne({ email: value }).exec();
if (subscriber !== null) {
return Promise.reject(`email is already subscribed`);
}
});

export const createSubscriber = [makeEmailValidator()];
Loading
Loading