Skip to content

Commit 2c4d982

Browse files
committed
Add waitlisted proposal status handling and related components
1 parent eabdf12 commit 2c4d982

6 files changed

Lines changed: 83 additions & 5 deletions

File tree

src/components/admin/ProposalActionModal.stories.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,18 @@ export const RemindAction: Story = {
9898
},
9999
}
100100

101+
export const WaitlistAction: Story = {
102+
args: {
103+
open: true,
104+
close: fn(),
105+
proposal: mockProposal,
106+
action: Action.waitlist,
107+
adminUI: true,
108+
onAction: fn(),
109+
domain: 'cloudnativedays.no',
110+
},
111+
}
112+
101113
export const DeleteAction: Story = {
102114
args: {
103115
open: true,

src/components/admin/ProposalCard.stories.tsx

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,17 @@ export const Confirmed: Story = {
167167
},
168168
}
169169

170+
export const Waitlisted: Story = {
171+
args: {
172+
proposal: createMockProposal({
173+
status: Status.waitlisted,
174+
title: 'Cloud Native CI/CD Pipelines',
175+
format: Format.presentation_25,
176+
}),
177+
href: '/admin/proposals/proposal-8',
178+
},
179+
}
180+
170181
export const Rejected: Story = {
171182
args: {
172183
proposal: createMockProposal({
@@ -253,14 +264,22 @@ export const AllStatuses: Story = {
253264
<ProposalCard
254265
proposal={createMockProposal({
255266
_id: 'p5',
267+
status: Status.waitlisted,
268+
title: 'Waitlisted Proposal',
269+
})}
270+
href="#"
271+
/>
272+
<ProposalCard
273+
proposal={createMockProposal({
274+
_id: 'p6',
256275
status: Status.rejected,
257276
title: 'Rejected Proposal',
258277
})}
259278
href="#"
260279
/>
261280
<ProposalCard
262281
proposal={createMockProposal({
263-
_id: 'p6',
282+
_id: 'p7',
264283
status: Status.withdrawn,
265284
title: 'Withdrawn Proposal',
266285
})}

src/components/admin/ProposalsList.stories.tsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -195,17 +195,24 @@ export const AllStatuses: Story = {
195195
),
196196
createMockProposal(
197197
'p5',
198+
'Waitlisted Proposal',
199+
Status.waitlisted,
200+
Format.presentation_25,
201+
'Speaker 5',
202+
),
203+
createMockProposal(
204+
'p6',
198205
'Rejected Proposal',
199206
Status.rejected,
200207
Format.lightning_10,
201-
'Speaker 5',
208+
'Speaker 6',
202209
),
203210
createMockProposal(
204-
'p6',
211+
'p7',
205212
'Withdrawn Proposal',
206213
Status.withdrawn,
207214
Format.workshop_120,
208-
'Speaker 6',
215+
'Speaker 7',
209216
),
210217
],
211218
},

src/components/cfp/CompactProposalList.stories.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,12 @@ const mixedStatusProposals: ProposalExisting[] = [
8383
),
8484
createMockProposal(
8585
'talk-4',
86+
'Cloud Native CI/CD Pipelines',
87+
Status.waitlisted,
88+
Format.presentation_25,
89+
),
90+
createMockProposal(
91+
'talk-5',
8692
'Service Mesh Deep Dive',
8793
Status.rejected,
8894
Format.presentation_45,

src/components/cfp/CompactProposalList.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,10 @@ function getProposalStatusConfig(
5757
return hasApprovedTalk
5858
? { color: 'gray', icon: MinusCircleIcon, label: 'Not selected' }
5959
: { color: 'red', icon: XCircleIcon, label: 'Rejected' }
60+
case 'waitlisted':
61+
return { color: 'orange', icon: ClockIcon, label: 'Waitlisted' }
6062
case 'withdrawn':
61-
return { color: 'orange', icon: XCircleIcon, label: 'Withdrawn' }
63+
return { color: 'purple', icon: XCircleIcon, label: 'Withdrawn' }
6264
case 'draft':
6365
return { color: 'gray', icon: DocumentTextIcon, label: 'Draft' }
6466
default:

src/docs/design-system/examples/EmailTemplates.stories.tsx

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { Meta, StoryObj } from '@storybook/nextjs-vite'
22
import { ProposalAcceptTemplate } from '@/components/email/ProposalAcceptTemplate'
33
import { ProposalRejectTemplate } from '@/components/email/ProposalRejectTemplate'
4+
import { ProposalWaitlistTemplate } from '@/components/email/ProposalWaitlistTemplate'
45
import { ContractSigningTemplate } from '@/components/email/ContractSigningTemplate'
56
import { ContractSignedTemplate } from '@/components/email/ContractSignedTemplate'
67
import { ContractReminderTemplate } from '@/components/email/ContractReminderTemplate'
@@ -186,6 +187,37 @@ export const EmailTemplates: Story = {
186187
</EmailPreviewFrame>
187188
</section>
188189

190+
{/* Live Waitlist Email */}
191+
<section className="mb-16">
192+
<h2 className="font-space-grotesk mb-6 text-2xl font-semibold text-brand-slate-gray dark:text-white">
193+
Proposal Waitlisted Email
194+
</h2>
195+
<p className="font-inter mb-6 text-gray-600 dark:text-gray-400">
196+
Sent when a speaker&apos;s proposal is placed on the waitlist as a
197+
backup.
198+
</p>
199+
<EmailPreviewFrame
200+
from="Cloud Native Days Norway <hello@cloudnativedays.no>"
201+
to="charlie.davis@example.com"
202+
subject="Your proposal has been waitlisted"
203+
time="Just now"
204+
>
205+
<ProposalWaitlistTemplate
206+
speakerName="Charlie Davis"
207+
proposalTitle="Cloud Native CI/CD Pipelines"
208+
eventName="Cloud Native Days Norway 2026"
209+
eventLocation="Oslo, Norway"
210+
eventDate="June 15-16, 2026"
211+
eventUrl="https://cloudnativedays.no"
212+
comment="Your proposal scored highly and we'd love to include it if a slot opens up. We'll notify you as soon as possible!"
213+
socialLinks={[
214+
'https://twitter.com/cloudnativeno',
215+
'https://linkedin.com/company/cloudnativeno',
216+
]}
217+
/>
218+
</EmailPreviewFrame>
219+
</section>
220+
189221
{/* Contract Signing Email */}
190222
<section className="mb-16">
191223
<h2 className="font-space-grotesk mb-6 text-2xl font-semibold text-brand-slate-gray dark:text-white">

0 commit comments

Comments
 (0)