Skip to content

Commit 3e09b1e

Browse files
CopilotStarefossen
andcommitted
Add prerequisites field for workshops in schema, types, forms, and display
Co-authored-by: Starefossen <968267+Starefossen@users.noreply.github.com>
1 parent 94fd37a commit 3e09b1e

6 files changed

Lines changed: 70 additions & 1 deletion

File tree

sanity/schemaTypes/talk.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,23 @@ export default defineType({
212212
return true
213213
}),
214214
}),
215+
defineField({
216+
name: 'prerequisites',
217+
title: 'Prerequisites',
218+
type: 'text',
219+
description:
220+
'Prerequisites for workshop participants (e.g., "Bring a computer with Docker installed")',
221+
hidden: ({ document }) => {
222+
const format = document?.format as string | undefined
223+
const prerequisites = document?.prerequisites as string | undefined
224+
const isWorkshop =
225+
format === 'workshop_120' || format === 'workshop_240'
226+
return !(
227+
isWorkshop ||
228+
(prerequisites !== undefined && prerequisites !== null)
229+
)
230+
},
231+
}),
215232
defineField({
216233
name: 'audienceFeedback',
217234
title: 'Audience Feedback',

src/components/cfp/ProposalForm.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ export function ProposalForm({
169169
audiences: proposal.audiences,
170170
tos: proposal.tos,
171171
capacity: proposal.capacity,
172+
prerequisites: proposal.prerequisites,
172173
topics: topicRefs,
173174
speakers: allSpeakers.map((id) => ({
174175
_type: 'reference' as const,

src/components/program/TalkCard.tsx

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
XMarkIcon,
1111
} from '@heroicons/react/24/outline'
1212
import { TrackTalk } from '@/lib/conference/types'
13-
import { Status } from '@/lib/proposal/types'
13+
import { isWorkshopFormat, Status } from '@/lib/proposal/types'
1414
import { SpeakerAvatars } from '@/components/SpeakerAvatars'
1515
import { ClickableSpeakerNames } from '@/components/ClickableSpeakerNames'
1616
import { BookmarkButton } from '@/components/BookmarkButton'
@@ -436,6 +436,21 @@ export function TalkCard({
436436
</div>
437437
)}
438438

439+
{!compact &&
440+
isConfirmed &&
441+
talkData.format &&
442+
isWorkshopFormat(talkData.format) &&
443+
talkData.prerequisites && (
444+
<div className="rounded-md border border-blue-200 bg-blue-50 p-4 dark:border-blue-800/50 dark:bg-blue-900/20">
445+
<h4 className="text-sm font-semibold text-blue-900 dark:text-blue-200">
446+
Prerequisites
447+
</h4>
448+
<p className="mt-1 whitespace-pre-wrap text-sm text-blue-800 dark:text-blue-300">
449+
{talkData.prerequisites}
450+
</p>
451+
</div>
452+
)}
453+
439454
{!compact && !isConfirmed && !isWithdrawnOrRejected && (
440455
<div className="flex-1">
441456
<div className="text-sm text-gray-400 italic dark:text-gray-500">

src/components/proposal/ProposalDetailsForm.tsx

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
audiences as audiencesMap,
77
Format,
88
formats,
9+
isWorkshopFormat,
910
Language,
1011
languages,
1112
Level,
@@ -57,6 +58,9 @@ export function ProposalDetailsForm({
5758
)
5859
const [outline, setOutline] = useState(proposal?.outline ?? '')
5960
const [tos, setTos] = useState(proposal?.tos ?? false)
61+
const [prerequisites, setPrerequisites] = useState(
62+
proposal?.prerequisites ?? '',
63+
)
6064

6165
// Push local state changes to parent
6266
useEffect(() => {
@@ -70,6 +74,7 @@ export function ProposalDetailsForm({
7074
topics,
7175
outline,
7276
tos,
77+
prerequisites,
7378
})
7479
}, [
7580
title,
@@ -81,6 +86,7 @@ export function ProposalDetailsForm({
8186
topics,
8287
outline,
8388
tos,
89+
prerequisites,
8490
setProposal,
8591
])
8692

@@ -202,6 +208,17 @@ export function ProposalDetailsForm({
202208
{outline || 'No outline provided'}
203209
</p>
204210
</div>
211+
212+
{isWorkshopFormat(format) && (
213+
<div>
214+
<label className="block text-sm font-medium text-gray-900 dark:text-white">
215+
Prerequisites
216+
</label>
217+
<p className="mt-2 whitespace-pre-wrap text-gray-900 dark:text-white">
218+
{prerequisites || 'No prerequisites specified'}
219+
</p>
220+
</div>
221+
)}
205222
</div>
206223
) : (
207224
<div className="mt-10 grid grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-6">
@@ -315,6 +332,23 @@ export function ProposalDetailsForm({
315332
</HelpText>
316333
</div>
317334

335+
{isWorkshopFormat(format) && (
336+
<div className="col-span-full">
337+
<Textarea
338+
name="prerequisites"
339+
label="Prerequisites"
340+
rows={3}
341+
value={prerequisites}
342+
setValue={setPrerequisites}
343+
/>
344+
<HelpText>
345+
List any prerequisites participants should meet before attending
346+
your workshop (e.g., &quot;Bring a computer with Docker
347+
installed&quot;, &quot;Basic knowledge of Kubernetes&quot;).
348+
</HelpText>
349+
</div>
350+
)}
351+
318352
<div className="col-span-full">
319353
<Checkbox
320354
name="tos"

src/lib/proposal/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ interface Proposal {
8484
tos: boolean
8585
video?: string
8686
capacity?: number
87+
prerequisites?: string
8788
audienceFeedback?: AudienceFeedback
8889
attachments?: Attachment[]
8990
}

src/server/schemas/proposal.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ const ProposalInputBaseSchema = z.object({
5151
}),
5252
video: z.string().nullable().optional().transform(nullToUndefined),
5353
capacity: z.number().nullable().optional().transform(nullToUndefined),
54+
prerequisites: z.string().nullable().optional().transform(nullToUndefined),
5455
speakers: z
5556
.array(ReferenceSchema)
5657
.nullable()

0 commit comments

Comments
 (0)