Skip to content

Commit

Permalink
Merge pull request #149 from GTBitsOfGood/nathan/147-user-info
Browse files Browse the repository at this point in the history
User info emails
  • Loading branch information
SamratSahoo authored Oct 16, 2024
2 parents def34d6 + d54da84 commit 645b44e
Show file tree
Hide file tree
Showing 13 changed files with 21,206 additions and 1,189 deletions.
18,123 changes: 18,123 additions & 0 deletions backend/package-lock.json

Large diffs are not rendered by default.

12 changes: 10 additions & 2 deletions backend/server/mongodb/actions/User.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@ export async function createUser(
lastName?: string,
handlerType?: HandlerType,
profileImage?: string,
address?: string,
annualPetVisitDay?: Date,
verifiedByAdmin?: boolean,
emailVerified?: boolean
emailVerified?: boolean,
) {
await dbConnect();
const user = await UserModel.create({
Expand All @@ -44,6 +46,8 @@ export async function createUser(
lastName: lastName,
handlerType: handlerType,
profileImage: profileImage,
address: address,
annualPetVisitDay: annualPetVisitDay,
verifiedByAdmin: verifiedByAdmin,
emailVerified: emailVerified,
});
Expand All @@ -57,7 +61,9 @@ export async function updateUser(
firstName?: string,
lastName?: string,
handlerType?: HandlerType,
profileImage?: string
address?: string,
annualPetVisitDay?: Date,
profileImage?: string,
) {
await dbConnect();
const user = UserModel.findByIdAndUpdate(userId, {
Expand All @@ -66,6 +72,8 @@ export async function updateUser(
lastName: lastName,
handlerType: handlerType,
birthday: birthday,
address: address,
annualPetVisitDay: annualPetVisitDay,
profileImage: profileImage,
});
return user;
Expand Down
10 changes: 10 additions & 0 deletions backend/server/mongodb/models/User.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@ const UserSchema = new mongoose.Schema<User>({
type: String,
required: false,
},
annualPetVisitDay: {
type: Date,
required: true,
default: Date.now()
},
address: {
type: String,
required: true,
default: ""
},
firebaseUid: {
type: String,
required: true,
Expand Down
2 changes: 1 addition & 1 deletion backend/server/utils/APIWrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ function APIWrapper(
if (e instanceof mongoose.Error) {
return res.status(500).json({
success: false,
message: "An Internal Server error occurred.",
message: `An Internal Server error occurred - ${e.message}`,
});
}

Expand Down
120 changes: 120 additions & 0 deletions backend/server/utils/emails/create/html.pug
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
doctype html
html(dir="ltr" xmlns="http://www.w3.org/1999/xhtml" xmlns:o="urn:schemas-microsoft-com:office:office" lang="en")
head
meta(charset="UTF-8")
meta(name="viewport" content="width=device-width, initial-scale=1")
meta(name="x-apple-disable-message-reformatting")
meta(http-equiv="X-UA-Compatible" content="IE=edge")
meta(name="format-detection" content="telephone=no")
title New Message
//[if (mso 16)]
style.
a { text-decoration: none; }
//[endif]
//[if gte mso 9]
style.
sup { font-size: 100% !important; }
//[endif]
//[if gte mso 9]
noscript
xml
o:OfficeDocumentSettings
o:AllowPNG
o:PixelsPerInch 96
style.
.rollover:hover .rollover-first { max-height: 0px !important; display: none !important; }
.rollover:hover .rollover-second { max-height: none !important; display: block !important; }
.rollover span { font-size: 0px; }
u + .body img ~ div div { display: none; }
#outlook a { padding: 0; }
span.MsoHyperlink, span.MsoHyperlinkFollowed { color: inherit; mso-style-priority: 99; }
a.es-button { mso-style-priority: 100 !important; text-decoration: none !important; }
a[x-apple-data-detectors], #MessageViewBody a {
color: inherit !important;
text-decoration: none !important;
font-size: inherit !important;
font-family: inherit !important;
font-weight: inherit !important;
line-height: inherit !important;
}
.es-desk-hidden {
display: none;
float: left;
overflow: hidden;
width: 0;
max-height: 0;
line-height: 0;
mso-hide: all;
}
@media only screen and (max-width: 600px) {
.es-m-p20b { padding-bottom: 20px !important; }
.es-p-default { }
*[class="gmail-fix"] { display: none !important; }
p, a { line-height: 150% !important; }
h1, h1 a, h2, h2 a, h3, h3 a, h4, h4 a, h5, h5 a, h6, h6 a { line-height: 120% !important; }
h1 { font-size: 30px !important; text-align: left; }
h2 { font-size: 24px !important; text-align: left; }
h3 { font-size: 20px !important; text-align: left; }
h4 { font-size: 24px !important; text-align: left; }
h5 { font-size: 20px !important; text-align: left; }
h6 { font-size: 16px !important; text-align: left; }
.es-menu td a { font-size: 14px !important; }
.es-m-txt-c { text-align: center !important; }
.es-m-txt-r { text-align: right !important; }
.es-m-txt-j { text-align: justify !important; }
.es-m-txt-l { text-align: left !important; }
.adapt-img { width: 100% !important; height: auto !important; }
}
@media screen and (max-width: 384px) {
.mail-message-content { width: 414px !important; }
}
body.body(style="width:100%;height:100%;padding:0;Margin:0")
.es-wrapper-color(dir="ltr" lang="en" style="background-color:#F6F6F6")
table.es-wrapper(role="none" style="border-collapse:collapse;border-spacing:0px;padding:0;Margin:0;width:100%;height:100%;background-repeat:repeat;background-position:center top;background-color:#F6F6F6")
tr
td(valign="top" style="padding:0;Margin:0")
table.es-header(role="none" style="width:100%;table-layout:fixed !important;background-color:transparent;background-repeat:repeat;background-position:center top")
tr
td(align="center" style="padding:0;Margin:0")
table.es-header-body(role="none" bgcolor="#ffffff" align="center" style="background-color:#FFFFFF;width:600px")
tr
td(align="left" style="padding-top:20px;padding-right:150px;padding-left:150px")
table.es-right(role="none" align="right" style="float:right")
tr
td(align="left" style="width:300px")
table(role="presentation" style="width:100%")
tr
td(align="center" style="font-size:0")
img.adapt-img(src="https://epiujlr.stripocdn.email/content/guids/CABINET_7549fef78daf44f7e4239172940d77c4be0d1029babaaeba34ec276d15a5ae69/images/h4hlogo.png" width="150" alt="" style="display:block;font-size:14px;border:0;outline:none;text-decoration:none")
table.es-content(role="none" align="center" style="width:100%;table-layout:fixed !important")
tr
td(align="center" style="padding:0;Margin:0")
table.es-content-body(role="none" bgcolor="#ffffff" align="center" style="background-color:#FFFFFF;width:600px")
tr
td(align="left" style="padding-top:20px;padding-right:20px;padding-left:20px")
table(role="none" style="width:100%")
tr
td(align="center" valign="top" style="width:560px")
table(role="presentation" style="width:100%")
tr
td(align="left")
p(style="Margin:0;font-family:arial, 'helvetica neue', helvetica, sans-serif;line-height:21px;letter-spacing:0;color:#333333;font-size:14px")
| Hello #{firstName} #{lastName}! This email was sent to you because an account was made with the email (#{email}) and the address #{address}.
table.es-footer(role="none" align="center" style="width:100%;table-layout:fixed !important;background-color:transparent;background-repeat:repeat;background-position:center top")
tr
td(align="center" style="padding:0;Margin:0")
table.es-footer-body(role="none" bgcolor="#ffffff" align="center" style="background-color:#FFFFFF;width:600px")
tr
td(align="left" style="padding-top:20px;padding-right:20px;padding-left:20px;padding-bottom:20px")
table.es-left(role="none" align="left" style="float:left;width:270px")
tr
td(align="left" class="es-m-p20b")
table(role="none" style="width:100%")
tr
td(align="center" style="display:none")
table.es-right(role="none" align="right" style="float:right;width:270px")
tr
td(align="left")
table(role="none" style="width:100%")
tr
td(align="center" style="display:none")
4 changes: 4 additions & 0 deletions backend/server/utils/seed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ async function generateUsers(): Promise<User[]> {
const lastName = faker.name.lastName();
const birthday = faker.date.birthdate();
const profileImage = faker.image.people();
const address = faker.address.streetAddress();
const annualPetVisitDay = faker.date.recent();
const profileImageFirebaseLocation = await uploadImageToFirebase(
StorageLocation.HANDLER_PICTURES,
profileImage
Expand Down Expand Up @@ -74,6 +76,8 @@ async function generateUsers(): Promise<User[]> {
lastName,
randomEnum(HandlerType) as HandlerType,
profileImageFirebaseLocation,
address,
annualPetVisitDay,
randomBoolean(),
true
);
Expand Down
39 changes: 37 additions & 2 deletions backend/src/pages/api/user/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import {
import APIWrapper from "server/utils/APIWrapper";
import { getUser } from "server/utils/Authentication";
import { HandlerType, Role } from "src/utils/types";
import { sendEmail } from "server/utils/Authentication";
import { EmailSubject } from "src/utils/types";
import { EmailTemplate } from "src/utils/types";
import { User } from "src/utils/types";

export default APIWrapper({
GET: {
Expand Down Expand Up @@ -39,12 +43,13 @@ export default APIWrapper({
const lastName: string = req.body.lastName as string;
const handlerType: HandlerType = req.body.handlerType as HandlerType;
const profileImage: string = req.body.profileImage as string;
const address: string = req.body.address as string;
const annualPetVisitDay: Date = req.body.annualPetVisitDay as Date;

const dbUser = await findUserByFirebaseUid(firebaseUid);
if (dbUser) {
throw new Error("User already exists in database!");
}

const roles = [Role.NONPROFIT_USER];
const isAdmin = email.endsWith("@healing4heroes.org");
if (isAdmin) {
Expand All @@ -60,12 +65,13 @@ export default APIWrapper({
lastName,
handlerType,
profileImage,
address,
annualPetVisitDay,
isAdmin
);
if (!user) {
throw new Error("Failed to create user!");
}

return user;
},
},
Expand All @@ -82,6 +88,8 @@ export default APIWrapper({
const lastName: string = req.body.lastName as string;
const handlerType: HandlerType = req.body.handlerType as HandlerType;
const profileImage: string = req.body.profileImage as string;
const address: string = req.body.address as string;
const annualPetVisitDay: Date = req.body.annualPetVisitDay as Date;

const user = await getUser(accessToken);

Expand All @@ -96,13 +104,40 @@ export default APIWrapper({
firstName,
lastName,
handlerType,
address,
annualPetVisitDay,
profileImage
);

if (!updatedUser?.modifiedPaths) {
throw new Error("Failed to update user!");
}

// Only send email if user isn't on profile image upload
if (!profileImage) {
const emailData = {
email: (user as User).email,
firstName: firstName,
lastName: lastName,
address: address,
};
if (process.env.DEPLOY_CONTEXT === "production") {
await sendEmail(
"[email protected]",
EmailSubject.ACCOUNT_CREATED,
EmailTemplate.ACCOUNT_CREATED,
emailData
);
} else {
await sendEmail(
"[email protected]",
EmailSubject.ACCOUNT_CREATED,
EmailTemplate.ACCOUNT_CREATED,
emailData
);
}
}

return updatedUser;
},
},
Expand Down
4 changes: 4 additions & 0 deletions backend/src/utils/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ export interface User {
_id: Types.ObjectId;
firstName: string;
lastName: string;
address: string;
annualPetVisitDay: Date;
email: string;
firebaseUid: string;
handlerType: HandlerType;
Expand Down Expand Up @@ -180,11 +182,13 @@ export interface UploadedPart {
export enum EmailSubject {
EMAIL_VERIFICATION = "Verify Your Email for Healing4Heroes",
PASSWORD_RESET = "Reset Your Password for Healing4Heroes",
ACCOUNT_CREATED = "Account Created on Healing4Heroes",
}

export enum EmailTemplate {
EMAIL_VERIFICATION = "verify",
PASSWORD_RESET = "reset",
ACCOUNT_CREATED = "create",
}

/* User Retrieval */
Expand Down
Loading

0 comments on commit 645b44e

Please sign in to comment.