Skip to content

Commit

Permalink
Resend RSVP message on dupe submission (#43)
Browse files Browse the repository at this point in the history
When a user tries to RSVP twice for the same event with the same email,
show them this friendly message and resend their confirmation email:
<img width="804" alt="image"
src="https://github.com/user-attachments/assets/df029817-b01a-4b91-afd2-925cca739fbb">
  • Loading branch information
mplewis authored Nov 20, 2024
1 parent 1262026 commit 2c32698
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 3 deletions.
5 changes: 5 additions & 0 deletions NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@
- [ ] Why are hamburger items missing on Confirm RSVP page?
- [ ] URL builder helpers
- [ ] Form to request resend link(s) for email address
<<<<<<< HEAD
- [ ] # Add Sentry to frontend
- [ ] Resend confirmation if an RSVP enters an existing email
> > > > > > > origin/main
- [ ] Diff dates in `notify` so that they are omitted when unchanged
- [ ] Investigate why some emailed URLs use incorrect hosts for Netlify Deploy Preview
- [ ] Stably sort RSVP list
Expand All @@ -39,11 +42,13 @@
- [ ] Consensually gather user emails for mailing list
- [ ] Add pretty error messages for 404s (e.g. clicked an expired/tidied link)
- [ ] Redirect old slugs on slug change
- [ ] Add sticky bit to "sent you a confirmation email for your RSVP"
- [ ] Site-wide announcement feature
- [ ] Unify email templates (header, unsub footer, etc.)
- [ ] Unify email and Discord notifications
- [ ] "Serious mode" for LoadingBuddy for e.g. unsubscribe requests
- [ ] Notification when target email is denylisted on record creation
- [x] Resend confirmation if an RSVP enters an existing email
- [x] Captcha
- [x] Hold RSVP locally with cookie
- [x] **Scheduler engine**
Expand Down
15 changes: 14 additions & 1 deletion api/src/services/responses/responses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,23 @@ export const createResponse: MutationResolvers['createResponse'] = async ({

const { captchaResponse, ...input } = _input
const valid = await validateCaptcha(captchaResponse)
if (!valid)
if (!valid) {
throw new RedwoodError(
'Could not validate reCAPTCHA. Please refresh the page and try again.'
)
}

const existingResponse = await db.response.findFirst({
where: { eventId, email: input.email },
})
if (existingResponse) {
await sendResponseConfirmation({ event, response: existingResponse })
throw new RedwoodError(
`You have already RSVPed to this event. ` +
`We've resent your confirmation email to ${input.email}.`,
{ forbidResubmitForEmail: input.email }
)
}

const reminders: { sendAt: Date }[] = []
if (input.remindPriorSec) {
Expand Down
13 changes: 11 additions & 2 deletions web/src/components/ResponseForm/ResponseForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,11 @@ const ResponseForm = (props: Props) => {
onCaptchaResponse,
onSubmit,
} = props
const { formState } = formMethods
const { formState, getValues } = formMethods

const { email } = getValues()
const forbidResubmit =
email === error?.cause?.extensions?.['forbidResubmitForEmail']

const [exampleName, setExampleName] = useState('')
useEffect(() => {
Expand Down Expand Up @@ -172,7 +176,12 @@ const ResponseForm = (props: Props) => {

<Submit
className="button is-success mt-3"
disabled={loading || !formState.isValid || !formState.isDirty}
disabled={
loading ||
!formState.isValid ||
!formState.isDirty ||
forbidResubmit
}
>
{mode === 'CREATE'
? loading
Expand Down

0 comments on commit 2c32698

Please sign in to comment.