Skip to content

Commit 6c945c0

Browse files
committed
Refactor waitlisted proposal status handling and update related components
1 parent ccfbedd commit 6c945c0

5 files changed

Lines changed: 38 additions & 51 deletions

File tree

__tests__/lib/proposal/state-machine.test.ts

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -126,20 +126,12 @@ describe('actionStateMachine', () => {
126126

127127
describe('waitlisted status', () => {
128128
it('allows organizer to accept', () => {
129-
const result = actionStateMachine(
130-
Status.waitlisted,
131-
Action.accept,
132-
true,
133-
)
129+
const result = actionStateMachine(Status.waitlisted, Action.accept, true)
134130
expect(result).toEqual({ status: Status.accepted, isValidAction: true })
135131
})
136132

137133
it('allows organizer to reject', () => {
138-
const result = actionStateMachine(
139-
Status.waitlisted,
140-
Action.reject,
141-
true,
142-
)
134+
const result = actionStateMachine(Status.waitlisted, Action.reject, true)
143135
expect(result).toEqual({ status: Status.rejected, isValidAction: true })
144136
})
145137

@@ -153,20 +145,12 @@ describe('actionStateMachine', () => {
153145
})
154146

155147
it('prevents non-organizer from accepting', () => {
156-
const result = actionStateMachine(
157-
Status.waitlisted,
158-
Action.accept,
159-
false,
160-
)
148+
const result = actionStateMachine(Status.waitlisted, Action.accept, false)
161149
expect(result.isValidAction).toBe(false)
162150
})
163151

164152
it('prevents non-organizer from rejecting', () => {
165-
const result = actionStateMachine(
166-
Status.waitlisted,
167-
Action.reject,
168-
false,
169-
)
153+
const result = actionStateMachine(Status.waitlisted, Action.reject, false)
170154
expect(result.isValidAction).toBe(false)
171155
})
172156
})

src/components/admin/AdminActionBar.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,14 @@ export function AdminActionBar({
9595
setShowEditModal(false)
9696
}
9797

98-
const canApprove = proposal.status === 'submitted'
98+
const canApprove =
99+
proposal.status === 'submitted' || proposal.status === 'waitlisted'
99100
const canWaitlist = proposal.status === 'submitted'
100101
const canRemind = proposal.status === 'accepted'
101102
const canReject =
102-
proposal.status === 'submitted' || proposal.status === 'accepted'
103+
proposal.status === 'submitted' ||
104+
proposal.status === 'accepted' ||
105+
proposal.status === 'waitlisted'
103106

104107
// Keyboard shortcuts
105108
useEffect(() => {
@@ -157,8 +160,7 @@ export function AdminActionBar({
157160
Status:
158161
</span>
159162
<span
160-
className={`inline-flex items-center rounded-full px-2 py-1 text-xs font-medium ${
161-
proposal.status === 'accepted'
163+
className={`inline-flex items-center rounded-full px-2 py-1 text-xs font-medium ${proposal.status === 'accepted'
162164
? 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200'
163165
: proposal.status === 'waitlisted'
164166
? 'bg-orange-100 text-orange-800 dark:bg-orange-900 dark:text-orange-200'
@@ -167,7 +169,7 @@ export function AdminActionBar({
167169
: proposal.status === 'submitted'
168170
? 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200'
169171
: 'bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-200'
170-
}`}
172+
}`}
171173
>
172174
{proposal.status.charAt(0).toUpperCase() +
173175
proposal.status.slice(1)}

src/components/admin/ProposalActionModal.tsx

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ export function ProposalActionModal({
183183
)}
184184
{(action === Action.accept ||
185185
action === Action.remind ||
186+
action === Action.waitlist ||
186187
action === Action.reject) &&
187188
notify &&
188189
createLocalhostWarning(domain, 'speakers') && (
@@ -197,15 +198,15 @@ export function ProposalActionModal({
197198
<span className="font-semibold">{proposal.title}</span> by{' '}
198199
<span className="font-semibold">
199200
{proposal.speakers &&
200-
Array.isArray(proposal.speakers) &&
201-
proposal.speakers.length > 0
201+
Array.isArray(proposal.speakers) &&
202+
proposal.speakers.length > 0
202203
? proposal.speakers
203-
.map((speaker) =>
204-
typeof speaker === 'object' && 'name' in speaker
205-
? (speaker as Speaker).name
206-
: 'Unknown',
207-
)
208-
.join(', ')
204+
.map((speaker) =>
205+
typeof speaker === 'object' && 'name' in speaker
206+
? (speaker as Speaker).name
207+
: 'Unknown',
208+
)
209+
.join(', ')
209210
: 'Unknown author'}
210211
</span>
211212
?

src/components/admin/hooks/useProposalSearch.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,15 @@ const STATUS_PRIORITY: Record<Status, number> = {
1010
[Status.accepted]: 0,
1111
[Status.confirmed]: 1,
1212
[Status.submitted]: 2,
13-
[Status.draft]: 3,
14-
[Status.rejected]: 4,
15-
[Status.withdrawn]: 5,
16-
[Status.deleted]: 6,
13+
[Status.waitlisted]: 3,
14+
[Status.draft]: 4,
15+
[Status.rejected]: 5,
16+
[Status.withdrawn]: 6,
17+
[Status.deleted]: 7,
1718
} as const
1819

1920
// Default priority for unknown status values (lowest priority)
20-
const DEFAULT_STATUS_PRIORITY = 7
21+
const DEFAULT_STATUS_PRIORITY = 8
2122

2223
export function useProposalSearch() {
2324
const [isSearching, setIsSearching] = useState(false)

src/components/cfp/CompactProposalList.tsx

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,12 @@ export function CompactProposalList({
8585
const statusOrder: Record<Status, number> = {
8686
confirmed: 1,
8787
accepted: 2,
88-
submitted: 3,
89-
draft: 4,
90-
rejected: 5,
91-
withdrawn: 6,
92-
deleted: 7,
88+
waitlisted: 3,
89+
submitted: 4,
90+
draft: 5,
91+
rejected: 6,
92+
withdrawn: 7,
93+
deleted: 8,
9394
}
9495
return statusOrder[a.status] - statusOrder[b.status]
9596
})
@@ -106,8 +107,8 @@ export function CompactProposalList({
106107
const audienceFeedback = proposal.audienceFeedback
107108
const totalFeedback = audienceFeedback
108109
? audienceFeedback.greenCount +
109-
audienceFeedback.yellowCount +
110-
audienceFeedback.redCount
110+
audienceFeedback.yellowCount +
111+
audienceFeedback.redCount
111112
: 0
112113
const showFeedback =
113114
conferenceHasEnded &&
@@ -132,11 +133,10 @@ export function CompactProposalList({
132133
return (
133134
<div
134135
key={proposal._id}
135-
className={`flex flex-col gap-3 rounded-lg border px-3 py-2.5 text-sm transition-colors sm:flex-row sm:items-center sm:justify-between ${
136-
isMuted
136+
className={`flex flex-col gap-3 rounded-lg border px-3 py-2.5 text-sm transition-colors sm:flex-row sm:items-center sm:justify-between ${isMuted
137137
? 'border-gray-200/50 bg-gray-50/50 opacity-60 hover:opacity-80 dark:border-gray-700/50 dark:bg-gray-800/50'
138138
: 'border-gray-200 bg-white hover:border-gray-300 hover:shadow-sm dark:border-gray-700 dark:bg-gray-800 dark:hover:border-gray-600'
139-
}`}
139+
}`}
140140
>
141141
<div className="flex min-w-0 flex-1 items-center gap-3 overflow-hidden">
142142
{proposal.speakers && proposal.speakers.length > 0 && (
@@ -158,11 +158,10 @@ export function CompactProposalList({
158158
? `/cfp/proposal?id=${proposal._id}${queryString ? `&${queryString.slice(1)}` : ''}`
159159
: `/cfp/proposal/${proposal._id}${queryString}`
160160
}
161-
className={`flex-1 truncate font-medium hover:text-brand-cloud-blue dark:hover:text-blue-400 ${
162-
isMuted
161+
className={`flex-1 truncate font-medium hover:text-brand-cloud-blue dark:hover:text-blue-400 ${isMuted
163162
? 'text-gray-600 dark:text-gray-400'
164163
: 'text-gray-900 dark:text-white'
165-
}`}
164+
}`}
166165
>
167166
{proposal.title}
168167
</Link>

0 commit comments

Comments
 (0)