|
| 1 | +# Email Forms Setup Guide |
| 2 | + |
| 3 | +This document describes how to set up the Partnership Application and Organisation Request forms with SendGrid email integration. |
| 4 | + |
| 5 | +## Environment Variables |
| 6 | + |
| 7 | +Add the following environment variables to your `.env.local` file: |
| 8 | + |
| 9 | +```bash |
| 10 | +# SendGrid Configuration |
| 11 | +SENDGRID_API_KEY=your_sendgrid_api_key_here |
| 12 | + |
| 13 | +# Email Addresses |
| 14 | + |
| 15 | +[email protected] # Admin email for partnership applications |
| 16 | +[email protected] # Admin email for organisation requests |
| 17 | + |
| 18 | +# SendGrid Template IDs (create templates in SendGrid Dashboard) |
| 19 | +SENDGRID_PARTNERSHIP_APPLICATION_TEMPLATE_ID=d-xxxxxxxxxxxxx |
| 20 | +SENDGRID_ORGANISATION_REQUEST_TEMPLATE_ID=d-xxxxxxxxxxxxx |
| 21 | +``` |
| 22 | + |
| 23 | +## SendGrid Template Setup |
| 24 | + |
| 25 | +### 1. Partnership Application Template |
| 26 | + |
| 27 | +1. Go to SendGrid Dashboard → Email API → Dynamic Templates |
| 28 | +2. Create a new Dynamic Template |
| 29 | +3. Copy the HTML from `/src/templates/partnership-application-email.html` |
| 30 | +4. Save and copy the Template ID to `SENDGRID_PARTNERSHIP_APPLICATION_TEMPLATE_ID` |
| 31 | + |
| 32 | +**Template Variables:** |
| 33 | +- `{{OrganisationName}}` - Organisation name |
| 34 | +- `{{CharityOrCompanyNumber}}` - Charity/Company number |
| 35 | +- `{{Website}}` - Organisation website |
| 36 | +- `{{LocationsOfOperation}}` - Comma-separated locations |
| 37 | +- `{{ShortDescription}}` - Description of their work |
| 38 | +- `{{WhyInterested}}` - Why they want to join |
| 39 | +- `{{ContactFullName}}` - Contact name |
| 40 | +- `{{ContactJobTitle}}` - Contact job title |
| 41 | +- `{{ContactEmail}}` - Contact email |
| 42 | +- `{{ContactPhone}}` - Contact phone |
| 43 | +- `{{SubmittedAt}}` - Submission timestamp |
| 44 | +- `{{is_admin_copy}}` - Boolean for admin vs applicant email |
| 45 | + |
| 46 | +### 2. Organisation Request Template |
| 47 | + |
| 48 | +1. Create another Dynamic Template |
| 49 | +2. Copy the HTML from `/src/templates/organisation-request-email.html` |
| 50 | +3. Save and copy the Template ID to `SENDGRID_ORGANISATION_REQUEST_TEMPLATE_ID` |
| 51 | + |
| 52 | +**Template Variables:** |
| 53 | +- `{{OrganisationName}}` - Organisation name |
| 54 | +- `{{Description}}` - Organisation description |
| 55 | +- `{{OrganisationEmail}}` - Organisation email |
| 56 | +- `{{OrganisationPhone}}` - Organisation phone |
| 57 | +- `{{Website}}` - Organisation website |
| 58 | +- `{{LocationsServed}}` - Comma-separated locations |
| 59 | +- `{{ContactFullName}}` - Contact name |
| 60 | +- `{{ContactEmail}}` - Contact email |
| 61 | +- `{{ServicesHtml}}` - HTML formatted services list including category name, subcategory name, availability (either "Open 24/7" or detailed opening times), address and per-service contact details. Use `{{{ServicesHtml}}}` for raw HTML. |
| 62 | +- `{{SubmittedAt}}` - Submission timestamp |
| 63 | +- `{{is_admin_copy}}` - Boolean for admin vs requester email |
| 64 | + |
| 65 | +**Availability & opening times behaviour (IsOpen247):** |
| 66 | +- Each service in the Organisation Request form has an `Open 24/7` toggle (`IsOpen247`). |
| 67 | +- If `IsOpen247` is **true** for a service: |
| 68 | + - The form hides the opening times inputs for that service. |
| 69 | + - The email shows **"Open 24/7"** in the Availability row and does **not** list individual opening times. |
| 70 | +- If `IsOpen247` is **false** for a service: |
| 71 | + - At least one opening time (day + start/end) is required and validated. |
| 72 | + - The email shows a line per opening time (e.g. `Monday: 09:00 - 17:00`). |
| 73 | + |
| 74 | +## Form Pages |
| 75 | + |
| 76 | +- **Partnership Application**: `/partnership-application-form` |
| 77 | +- **Organisation Request**: `/organisation-request-form` |
| 78 | + |
| 79 | +## File Structure |
| 80 | + |
| 81 | +``` |
| 82 | +streetsupport-platform-web/src/ |
| 83 | +├── app/ |
| 84 | +│ ├── api/ |
| 85 | +│ │ ├── partnership-application/ |
| 86 | +│ │ │ └── route.ts # API endpoint for partnership applications |
| 87 | +│ │ └── organisation-request/ |
| 88 | +│ │ └── route.ts # API endpoint for organisation requests |
| 89 | +│ ├── partnership-application-form/ |
| 90 | +│ │ └── page.tsx # Partnership application form page |
| 91 | +│ └── organisation-request-form/ |
| 92 | +│ └── page.tsx # Organisation request form page |
| 93 | +├── schemas/ |
| 94 | +│ ├── partnershipApplicationSchema.ts # Zod validation schema |
| 95 | +│ └── organisationRequestSchema.ts # Zod validation schema |
| 96 | +├── templates/ |
| 97 | +│ ├── partnership-application-email.html # Email template (copy to SendGrid) |
| 98 | +│ └── organisation-request-email.html # Email template (copy to SendGrid) |
| 99 | +├── types/ |
| 100 | +│ ├── partnershipApplication.ts # TypeScript interfaces |
| 101 | +│ └── organisationRequest.ts # TypeScript interfaces |
| 102 | +└── utils/ |
| 103 | + └── emailService.ts # Reusable SendGrid email utility |
| 104 | +``` |
| 105 | + |
| 106 | +## Installation |
| 107 | + |
| 108 | +Run the following command to install new dependencies: |
| 109 | + |
| 110 | +```bash |
| 111 | +cd streetsupport-platform-web |
| 112 | +npm install |
| 113 | +``` |
| 114 | + |
| 115 | +New packages added: |
| 116 | +- `zod` - Form validation |
| 117 | +- `@sendgrid/mail` - SendGrid email sending |
| 118 | + |
| 119 | +## Testing |
| 120 | + |
| 121 | +1. Ensure all environment variables are set |
| 122 | +2. Start the development server: `npm run dev` |
| 123 | +3. Visit `/partnership-application-form` to test the partnership form |
| 124 | +4. Visit `/organisation-request-form` to test the organisation request form |
| 125 | +5. Submit forms and check: |
| 126 | + - Admin email receives notification |
| 127 | + - Applicant/requester receives confirmation copy |
| 128 | + |
| 129 | +## Email Flow |
| 130 | + |
| 131 | +1. User fills out form on the website |
| 132 | +2. Client-side Zod validation runs on submit |
| 133 | +3. Form data is sent to API route |
| 134 | +4. Server-side Zod validation runs |
| 135 | +5. Email data is prepared |
| 136 | +6. Single email is sent via SendGrid with CC functionality: |
| 137 | + - **Partnership Application**: |
| 138 | + - Sent to `PARTNERSHIP_APPLICATION_ADMIN_EMAIL` |
| 139 | + - CC to applicant's `ContactEmail` (if provided) for their records |
| 140 | + - **Organisation Request**: |
| 141 | + - Sent to `ORGANISATION_REQUEST_ADMIN_EMAIL` |
| 142 | + - CC to requester's `ContactEmail` (if provided) for their records |
| 143 | +7. Success response returned to client |
| 144 | + |
| 145 | +## Customization |
| 146 | + |
| 147 | +### Changing Admin Emails |
| 148 | +- Update `PARTNERSHIP_APPLICATION_ADMIN_EMAIL` to change where partnership applications are sent |
| 149 | +- Update `ORGANISATION_REQUEST_ADMIN_EMAIL` to change where organisation requests are sent |
| 150 | +- These can be the same email address or different addresses for different teams |
| 151 | + |
| 152 | +### Adding New Form Types |
| 153 | +1. Create interface in `/types/` |
| 154 | +2. Create Zod schema in `/schemas/` |
| 155 | +3. Create email template in `/templates/` |
| 156 | +4. Create form page in `/app/` |
| 157 | +5. Create API route in `/app/api/` |
| 158 | +6. Add email sending function to `/utils/emailService.ts` |
0 commit comments