generated from include-davis/Next.js-App-Router-Starter
-
Notifications
You must be signed in to change notification settings - Fork 2
449 create individual judge hacker hub invite #450
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
Merged
michelleyeoh
merged 41 commits into
main
from
449-create-individual-judge-hacker-hub-invite
Mar 14, 2026
Merged
Changes from all commits
Commits
Show all changes
41 commits
Select commit
Hold shift + click to select a range
c3df639
Judge invites!
ReehalS 302ee39
Linty lint
ReehalS f4d2371
Fix image URL and error handling for sending emails
ReehalS 2ee04c4
Document browser preview csv parser
ReehalS 47aef86
Throw error for missing email ENV vars
ReehalS 3e88930
Single mentor invite
ReehalS b8ae04b
Bulk mentor invites and modify invites page
ReehalS e08f6fa
New format bulk mentor invites
ReehalS 9b2ef1d
Lint fixes
ReehalS fd07861
Single mentor invite
ReehalS 4e25ab9
Bulk mentor invites and modify invites page
ReehalS e0aaf45
New format bulk mentor invites
ReehalS fd85880
Lint fixes
ReehalS 458d2db
Merge branch '376-mentor-email-invites' of https://github.com/HackDav…
ReehalS a4fc269
Revert "Merge branch '376-mentor-email-invites' of https://github.com…
ReehalS 40ce0dd
Move mentor invites to new folder and add vars
ReehalS 2000a1a
Create InviteCSV parsing test
ReehalS 8862474
Update email subject
ReehalS 6306c93
Update sendSingleMentorInvite.ts
ReehalS 7b63f33
Update sendBulkMentorInvites.ts
ReehalS 013f33a
Move EMAIL_SUBJECT to be common rather than redefined for each file
ReehalS 9162ee5
Move Judge+Mentor bulk invite creation to new processing pipeline
ReehalS c68ffdd
Add tests for Limiter and processBulkInvites
ReehalS 4ab3a49
Merge branch 'main' of https://github.com/HackDavis/hackdavis-hub int…
michelleyeoh 2471768
fixed mentor template
michelleyeoh 6e0edb7
redo mentor and judge email design
michelleyeoh f173ff6
extract consts
michelleyeoh 28a286b
cleaned console
michelleyeoh 8a15887
update workflow env vars
michelleyeoh e973aca
added comment to new file
michelleyeoh 0fa1cee
Merge branch 'main' into 376-mentor-email-invites
michelleyeoh 02745ac
Merge branch 'main' of https://github.com/HackDavis/hackdavis-hub int…
michelleyeoh 89258df
update error msg
michelleyeoh e706ad6
Merge branch '376-mentor-email-invites' of https://github.com/HackDav…
michelleyeoh 419bfc9
fix extra bracket
michelleyeoh 1aae2a4
added error message for safe handling
michelleyeoh f7b7649
Merge branch '376-mentor-email-invites' of https://github.com/HackDav…
michelleyeoh 23f6f95
small mentor email template fix
michelleyeoh c33516d
Merge branch '449-create-individual-judge-hacker-hub-invite' of https…
michelleyeoh 684dbc8
added emergency invite
michelleyeoh 4ca8019
template html fix
michelleyeoh File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
50 changes: 50 additions & 0 deletions
50
app/(api)/_actions/emails/emailTemplates/forgotPasswordTemplate.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| export default function forgotPasswordTemplate(link: string) { | ||
| const HEADER_IMAGE_URL = `${process.env.BASE_URL}/email/2025_email_header.png`; | ||
| return ` | ||
| <!DOCTYPE html> | ||
| <html lang="en"> | ||
| <head> | ||
| <meta charset="UTF-8" /> | ||
| <meta http-equiv="X-UA-Compatible" content="IE=edge" /> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
| <title>Reset your HackDavis Hub Password</title> | ||
| <style> | ||
| body { margin: 0; padding: 0; font-family: 'DM Mono', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; background-color: #ffffff; } | ||
| .container { max-width: 600px; margin: 0 auto; background-color: #ffffff; } | ||
| .header-image { width: 100%; height: auto; display: block; } | ||
| .title { text-align: center; font-size: 28px; font-weight: bold; margin: 30px 0; color: #000000; } | ||
| .content-box { background-color: #ffffff; margin: 20px 0; } | ||
| .content-box p { font-size: 16px; line-height: 1.5; color: #222222; margin: 0 0 16px 0; } | ||
| .content-box a { color: #0061FE; text-decoration: none; } | ||
| .content-box a:hover { text-decoration: underline; } | ||
| .content-box ul { margin: 16px 0; padding-left: 20px; } | ||
| .content-box li { font-size: 16px; line-height: 1.6; color: #222222; margin-bottom: 12px; } | ||
| .content-box ul ul { margin-top: 8px; } | ||
| .content-box p.special-note { font-size: 14px; color: #8d9ca2; } | ||
| .bordered-section { border-width: 2px; border-style: solid; border-color: #e5e5e5; border-radius: 5px; padding: 12px 24px; margin: 16px 0; } | ||
| .bold { font-weight: bold; } | ||
| .divider { height: 2px; background-color: #F2F2F2; margin: 40px 0; } | ||
| .footer-image { width: 100%; height: auto; display: block; margin-top: 20px; } | ||
| @media only screen and (max-width: 600px) { | ||
| .content-box { padding: 24px; margin: 10px; } | ||
| .title { font-size: 24px; margin: 20px 0; } | ||
| } | ||
| </style> | ||
| </head> | ||
| <body> | ||
| <div class="container"> | ||
| <img src="${HEADER_IMAGE_URL}" alt="HackDavis 2025 header" class="header-image"> | ||
| <h1 class="title"> | ||
| <span style="color: #173a52;">Reset your HackDavis Hub Password</span> | ||
| </h1> | ||
| <div class="divider"></div> | ||
| <div class="content-box"> | ||
| <p>Click the link below to reset your password for the HackDavis Hub. This link expires in 24 hours. Do <span class="bold">NOT</span> share this link with anyone.</p> | ||
| <p ><a href="${link}" style="font-size: 14px;">${link}</a></p> | ||
| <p class="special-note">If you didn't request to reset your password, you can safely ignore this email.</p> | ||
| </div> | ||
| </div> | ||
| </body> | ||
| </html> | ||
| `; | ||
| } | ||
49 changes: 49 additions & 0 deletions
49
app/(api)/_actions/emails/emailTemplates/hubEmergencyInviteTemplate.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| export default function hubEmergencyInviteTemplate(link: string) { | ||
| const HEADER_IMAGE_URL = `${process.env.BASE_URL}/email/2025_email_header.png`; | ||
| return ` | ||
| <!DOCTYPE html> | ||
| <html lang="en"> | ||
| <head> | ||
| <meta charset="UTF-8" /> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
| <title>HackDavis Hub Invite Link</title> | ||
| <style> | ||
| body { margin: 0; padding: 0; font-family: 'DM Mono', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; background-color: #ffffff; } | ||
| .container { max-width: 600px; margin: 0 auto; background-color: #ffffff; } | ||
michelleyeoh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| .header-image { width: 100%; height: auto; display: block; } | ||
| .title { text-align: center; font-size: 28px; font-weight: bold; margin: 30px 0; color: #000000; } | ||
| .content-box { background-color: #ffffff; margin: 20px 0; } | ||
| .content-box p { font-size: 16px; line-height: 1.5; color: #222222; margin: 0 0 16px 0; } | ||
| .content-box a { color: #0061FE; text-decoration: none; } | ||
| .content-box a:hover { text-decoration: underline; } | ||
| .content-box ul { margin: 16px 0; padding-left: 20px; } | ||
| .content-box li { font-size: 16px; line-height: 1.6; color: #222222; margin-bottom: 12px; } | ||
| .content-box ul ul { margin-top: 8px; } | ||
| .content-box p.special-note { font-size: 14px; color: #8d9ca2; } | ||
| .bordered-section { border-width: 2px; border-style: solid; border-color: #e5e5e5; border-radius: 5px; padding: 12px 24px; margin: 16px 0; } | ||
| .bold { font-weight: bold; } | ||
| .divider { height: 2px; background-color: #F2F2F2; margin: 40px 0; } | ||
| .footer-image { width: 100%; height: auto; display: block; margin-top: 20px; } | ||
| @media only screen and (max-width: 600px) { | ||
| .content-box { padding: 24px; margin: 10px; } | ||
| .title { font-size: 24px; margin: 20px 0; } | ||
| } | ||
| </style> | ||
| </head> | ||
| <body> | ||
| <div class="container"> | ||
| <img src="${HEADER_IMAGE_URL}" alt="HackDavis 2025 header" class="header-image"> | ||
| <h1 class="title"> | ||
| <span style="color: #173a52;">Invitation to the </span> | ||
| <span style="color: #57dade;">HackDavis Hub</span> | ||
| </h1> | ||
| <div class="divider"></div> | ||
| <div class="content-box"> | ||
| <p>Click the link below to create your account on the HackDavis Hub. Do <span class="bold">NOT</span> share this unique invite link with anyone.</p> | ||
| <p><a href="${link}" style="font-size: 14px;">${link}</a></p> | ||
| </div> | ||
| </div> | ||
| </body> | ||
| </html> | ||
| `; | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,162 +1,8 @@ | ||
| export default function emailMessage(type: string, link: string) { | ||
| const inviteMsg = ` | ||
| <!DOCTYPE html> | ||
| <html> | ||
| <head> | ||
| <title>HackDavis Hub Invite Link</title> | ||
| <style> | ||
| * { | ||
| box-sizing: border-box; | ||
| text-decoration: none; | ||
| } | ||
|
|
||
| .container { | ||
| background-color: #E5EEF1; | ||
| width: 100%; | ||
| padding: 48px; | ||
| } | ||
|
|
||
| .welcome-text { | ||
| color: black; | ||
| font-size: 1.5rem; | ||
| font-weight: 700; | ||
| font-family: 'Helvetica'; | ||
| } | ||
|
|
||
| .make-account { | ||
| color: black; | ||
| font-family: 'Helvetica'; | ||
| margin-bottom: 30px; | ||
| } | ||
|
|
||
| span { | ||
| font-weight: 700; | ||
| } | ||
|
|
||
| .button { | ||
| border: none; | ||
| border-radius: 4px; | ||
| padding: 12px; | ||
| background-color: #FFC53D; | ||
| font-weight: 500; | ||
| font-size: 1.25rem; | ||
| cursor: pointer; | ||
| text-align: center; | ||
| text-decoration: none; | ||
| font-family: 'Helvetica'; | ||
| } | ||
|
|
||
| .sub-container { | ||
| margin-top: 30px; | ||
| } | ||
|
|
||
| .bottom-text { | ||
| font-family: 'Helvetica'; | ||
| } | ||
|
|
||
| .link { | ||
| color: blue; | ||
| font-family: 'Helvetica'; | ||
| text-decoration: underline; | ||
| } | ||
|
|
||
| </style> | ||
| </head> | ||
| <body> | ||
| <div class="container"> | ||
| <h3 class="welcome-text">Invitation to the HackDavis Hub</h3> | ||
| <p class="make-account"> | ||
| Click the button below to create your account on the HackDavis Hub. This link expires in 14 days. Do <span>NOT</span> share this unique invite link with anyone. | ||
| </p> | ||
| <a class="button" href="${link}">Register</a> | ||
| <div class="sub-container"> | ||
| <p class="bottom-text">If you're having trouble with the above button, copy and paste the following link into your browser:</p> | ||
| <p class="link">${link}</p> | ||
| </div> | ||
| </div> | ||
| </body> | ||
| </html> | ||
| `; | ||
|
|
||
| const resetMsg = ` | ||
| <!DOCTYPE html> | ||
| <html> | ||
| <head> | ||
| <title>HackDavis Hub Reset Password Link</title> | ||
| <style> | ||
| * { | ||
| box-sizing: border-box; | ||
| text-decoration: none; | ||
| } | ||
|
|
||
| .container { | ||
| background-color: #E5EEF1; | ||
| width: 100%; | ||
| padding: 48px; | ||
| } | ||
|
|
||
| .welcome-text { | ||
| color: black; | ||
| font-size: 1.5rem; | ||
| font-weight: 700; | ||
| font-family: 'Helvetica'; | ||
| } | ||
| import forgotPasswordTemplate from '../emails/emailTemplates/forgotPasswordTemplate'; | ||
| import hubEmergencyInviteTemplate from '../emails/emailTemplates/hubEmergencyInviteTemplate'; | ||
|
|
||
| .make-account { | ||
| color: black; | ||
| font-family: 'Helvetica'; | ||
| margin-bottom: 30px; | ||
| } | ||
|
|
||
| span { | ||
| font-weight: 700; | ||
| } | ||
|
|
||
| .button { | ||
| border: none; | ||
| border-radius: 4px; | ||
| padding: 12px; | ||
| background-color: #FFC53D; | ||
| font-weight: 500; | ||
| font-size: 1.25rem; | ||
| color: #173a52; | ||
| cursor: pointer; | ||
| text-align: center; | ||
| text-decoration: none; | ||
| font-family: 'Helvetica'; | ||
| } | ||
|
|
||
| .sub-container { | ||
| margin-top: 30px; | ||
| } | ||
|
|
||
| .bottom-text { | ||
| font-family: 'Helvetica'; | ||
| } | ||
|
|
||
| .link { | ||
| color: blue; | ||
| font-family: 'Helvetica'; | ||
| text-decoration: underline; | ||
| } | ||
|
|
||
| </style> | ||
| </head> | ||
| <body> | ||
| <div class="container"> | ||
| <h3 class="welcome-text">Reset Password Link for the HackDavis Hub</h3> | ||
| <p class="make-account"> | ||
| Click the button below to reset your password for the HackDavis Hub. This link expires in 24 hours. Do <span>NOT</span> share this link with anyone. If you didn't request a password reset, you can safely ignore this email. | ||
| </p> | ||
| <a class="button" href="${link}">Reset Password</a> | ||
| <div class="sub-container"> | ||
| <p class="bottom-text">If you're having trouble with the above button, copy and paste the following link into your browser:</p> | ||
| <p class="link">${link}</p> | ||
| </div> | ||
| </div> | ||
| </body> | ||
| </html> | ||
| `; | ||
|
|
||
| return type === 'invite' ? inviteMsg : resetMsg; | ||
| export default function emailMessage(type: string, link: string) { | ||
| return type === 'invite' | ||
| ? hubEmergencyInviteTemplate(link) | ||
| : forgotPasswordTemplate(link); | ||
michelleyeoh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.