@@ -5,6 +5,22 @@ import { zodResolver } from '@hookform/resolvers/zod';
55import { z } from 'zod' ;
66import FormInput from './FormInput' ;
77import ErrorSummary from './ErrorSummary' ;
8+ import { TagSelector } from '@/components/ui/atoms' ;
9+
10+ const TAG_SUGGESTIONS = [
11+ 'Web3' ,
12+ 'Blockchain' ,
13+ 'Stellar' ,
14+ 'Soroban' ,
15+ 'Hackathon' ,
16+ 'Workshop' ,
17+ 'Networking' ,
18+ 'Startup' ,
19+ 'AI' ,
20+ 'DeFi' ,
21+ 'Community' ,
22+ 'Technology' ,
23+ ] ;
824
925// ─── Schema ───────────────────────────────────────────────────────────────────
1026const createEventSchema = z . object ( {
@@ -29,6 +45,12 @@ const createEventSchema = z.object({
2945 category : z . enum ( [ 'conference' , 'workshop' , 'concert' , 'hackathon' , 'meetup' , '' ] , {
3046 errorMap : ( ) => ( { message : 'Please select a category' } ) ,
3147 } ) . refine ( v => v !== '' , { message : 'Please select a category' } ) ,
48+ tags : z
49+ . array ( z . string ( ) . trim ( ) . min ( 1 ) . max ( 20 , 'Tag cannot exceed 20 characters' ) )
50+ . max ( 10 , 'You can add up to 10 tags' )
51+ . refine ( ( tags ) => new Set ( tags . map ( ( tag ) => tag . toLowerCase ( ) ) ) . size === tags . length , {
52+ message : 'Duplicate tags are not allowed' ,
53+ } ) ,
3254 isPublic : z . boolean ( ) ,
3355 websiteUrl : z
3456 . string ( )
@@ -46,6 +68,7 @@ const FIELD_LABELS: Record<string, string> = {
4668 ticketPrice : 'Ticket Price' ,
4769 maxAttendees : 'Max Attendees' ,
4870 category : 'Category' ,
71+ tags : 'Tags' ,
4972 isPublic : 'Visibility' ,
5073 websiteUrl : 'Website URL' ,
5174} ;
@@ -101,6 +124,7 @@ export default function CreateEventForm() {
101124 ticketPrice : '0' ,
102125 maxAttendees : '100' ,
103126 category : '' ,
127+ tags : [ ] ,
104128 isPublic : true ,
105129 websiteUrl : '' ,
106130 } ,
@@ -193,6 +217,23 @@ export default function CreateEventForm() {
193217 < option value = "meetup" > Meetup</ option >
194218 </ FormInput >
195219
220+ { /* Tags */ }
221+ < Controller
222+ name = "tags"
223+ control = { control }
224+ render = { ( { field } ) => (
225+ < TagSelector
226+ label = "Tags"
227+ name = { field . name }
228+ value = { field . value }
229+ onChange = { field . onChange }
230+ suggestions = { TAG_SUGGESTIONS }
231+ hint = "Press Enter or comma to add tags. Backspace removes the last tag."
232+ error = { errors . tags }
233+ />
234+ ) }
235+ />
236+
196237 { /* Price + Attendees side by side */ }
197238 < div className = "grid grid-cols-2 gap-4" >
198239 < FormInput
@@ -268,7 +309,7 @@ export default function CreateEventForm() {
268309 role = "switch"
269310 aria-checked = { field . value }
270311 onClick = { ( ) => field . onChange ( ! field . value ) }
271- className = { `relative w-11 h-6 rounded-full transition-all duration-200 flex- shrink-0 ${
312+ className = { `relative w-11 h-6 rounded-full transition-all duration-200 shrink-0 ${
272313 field . value ? 'bg-[#3d5afe]' : 'bg-[#1e2333]'
273314 } `}
274315 >
0 commit comments