import { lazy, type ComponentType, type LazyExoticComponent } from 'react'; import { Palette, SprayCan, Music, Gavel, Brush, Dumbbell, Tent, Sparkles, Shirt, } from 'lucide-react'; import { pickRateUnits } from '@/lib/labExtras'; import type { CraftFormConfig } from '@/components/CraftProfileForm'; import { SKATE_ARTIST_KIND, ARTIST_SERVICE_LABELS, ARTIST_MEDIUM_LABELS, ARTIST_TOOL_LABELS, SKATE_GRAFFITI_KIND, GRAFFITI_STYLE_LABELS, GRAFFITI_MEDIUM_LABELS, GRAFFITI_CONTEXT_LABELS, SKATE_MUSICIAN_KIND, MUSICIAN_GENRE_LABELS, MUSICIAN_INSTRUMENT_LABELS, SKATE_JUDGE_KIND, JUDGE_FORMAT_LABELS, JUDGE_SPECIALTY_LABELS, JUDGE_LEVEL_LABELS, SKATE_ORGANIZER_KIND, ORGANIZER_EVENT_LABELS, ORGANIZER_SERVICE_LABELS, ORGANIZER_SCALE_LABELS, SKATE_TATTOO_KIND, TATTOO_STYLE_LABELS, TATTOO_METHOD_LABELS, SKATE_TRAINER_KIND, TRAINER_FOCUS_LABELS, TRAINER_INJURY_LABELS, TRAINER_CREDENTIAL_LABELS, SKATE_BARBER_KIND, BARBER_SERVICE_LABELS, BARBER_STYLE_LABELS, BARBER_SETTING_LABELS, SKATE_DESIGNER_KIND, DESIGNER_SERVICE_LABELS, DESIGNER_METHOD_LABELS, DESIGNER_MATERIAL_LABELS, } from '@/lib/types'; import { ARTIST_SERVICE_KEYS, ARTIST_MEDIUM_KEYS, ARTIST_TOOL_KEYS, GRAFFITI_STYLE_KEYS, GRAFFITI_MEDIUM_KEYS, GRAFFITI_CONTEXT_KEYS, MUSICIAN_GENRE_KEYS, MUSICIAN_INSTRUMENT_KEYS, JUDGE_FORMAT_KEYS, JUDGE_SPECIALTY_KEYS, JUDGE_LEVEL_KEYS, ORGANIZER_EVENT_KEYS, ORGANIZER_SERVICE_KEYS, ORGANIZER_SCALE_KEYS, TATTOO_STYLE_KEYS, TATTOO_METHOD_KEYS, TRAINER_FOCUS_KEYS, TRAINER_INJURY_KEYS, TRAINER_CREDENTIAL_KEYS, BARBER_SERVICE_KEYS, BARBER_STYLE_KEYS, BARBER_SETTING_KEYS, DESIGNER_SERVICE_KEYS, DESIGNER_METHOD_KEYS, DESIGNER_MATERIAL_KEYS, } from '@/lib/labelKeys'; /** * Single source of truth for every "become a …" role. * * There are two flavours: * 1. `craft` roles — thin config over the shared . All the * per-role difference lives here in data, not in 7 near-identical files. * 2. `page` roles — genuinely bespoke pages (Coach, Filmer, Editor, * Photographer, Skater, Builder) that carry extra machinery * (SpotPicker, wallet/Pro logic, geohashing, etc.). Forcing these into a * config would create a monster; instead they stay as their own lazy * components and are simply *routed* through the same /become/:role slug. * * The router uses this map so the whole feature is one param route + redirects * from the legacy /become- URLs, instead of 12 hardcoded route lines. */ interface CraftRole { kind: 'craft'; seoTitle: string; seoDescription: string; /** Optional i18n keys (take precedence over the raw English fallbacks). */ seoTitleKey?: string; seoDescriptionKey?: string; config: CraftFormConfig; } interface PageRole { kind: 'page'; /** Lazily-loaded bespoke page component (default export). */ component: LazyExoticComponent; } export type BecomeRole = CraftRole | PageRole; export const BECOME_ROLES: Record = { // ── Bespoke pages (unchanged — just registered here for routing) ── coach: { kind: 'page', component: lazy(() => import('@/pages/BecomeCoachPage')) }, filmer: { kind: 'page', component: lazy(() => import('@/pages/BecomeFilmerPage')) }, editor: { kind: 'page', component: lazy(() => import('@/pages/BecomeEditorPage')) }, photographer: { kind: 'page', component: lazy(() => import('@/pages/BecomePhotographerPage')) }, builder: { kind: 'page', component: lazy(() => import('@/pages/BecomeBuilderPage')) }, skater: { kind: 'page', component: lazy(() => import('@/pages/BecomeSkaterPage')) }, // ── Craft roles (data-driven over CraftProfileForm) ── artist: { kind: 'craft', seoTitle: 'Become a Designer / Artist - SkateSpots', seoDescription: 'List your skate design & art — board graphics, logos, posters, merch and more.', seoTitleKey: 'becomeRolesUi.artist.seoTitle', seoDescriptionKey: 'becomeRolesUi.artist.seoDescription', config: { kind: SKATE_ARTIST_KIND, selfTag: 'skateartist', identifier: 'artist-profile', heading: 'Designer / Artist', headingKey: 'becomeRolesUi.artist.heading', tagline: 'Board graphics, logos, posters, merch — put your art on the scene', taglineKey: 'becomeRolesUi.artist.tagline', noun: 'artist', nounKey: 'becomeRolesUi.artist.noun', accentText: 'text-fuchsia-400', accentBg: 'bg-fuchsia-600', accentChip: 'bg-fuchsia-600 text-white border-fuchsia-600', accentChipHover: 'hover:border-fuchsia-500/60 hover:text-fuchsia-400', icon: Palette, rateUnits: pickRateUnits('piece', 'project', 'hour', 'day'), extraFields: [ { tag: 'deliverables', label: 'Deliverables', labelKey: 'labUi.craftFields.deliverables', placeholder: 'e.g. print-ready files, source files, deck graphics', placeholderKey: 'becomeRolesUi.artist.deliverablesPlaceholder' }, { tag: 'turnaround', label: 'Turnaround', labelKey: 'labUi.craftFields.turnaround', placeholder: 'e.g. 3–5 days', placeholderKey: 'becomeRolesUi.artist.turnaroundPlaceholder' }, ], rateLabel: 'Rate', rateLabelKey: 'becomeRolesUi.artist.rateLabel', portfolioLabel: 'Portfolio / Shop link', portfolioLabelKey: 'becomeRolesUi.artist.portfolioLabel', skillSections: [ { title: 'What You Make', titleKey: 'becomeRolesUi.artist.sectionWhatYouMake', entries: Object.entries(ARTIST_SERVICE_LABELS), keyMap: ARTIST_SERVICE_KEYS, required: true }, { title: 'Medium', titleKey: 'becomeRolesUi.artist.sectionMedium', entries: Object.entries(ARTIST_MEDIUM_LABELS), keyMap: ARTIST_MEDIUM_KEYS }, { title: 'Software & Tools', titleKey: 'becomeRolesUi.artist.sectionSoftwareTools', entries: Object.entries(ARTIST_TOOL_LABELS), keyMap: ARTIST_TOOL_KEYS }, ], }, }, graffiti: { kind: 'craft', seoTitle: 'Offer Graffiti / Murals - SkateSpots', seoDescription: 'List your graffiti & mural work — pieces, murals, skatepark art and more.', seoTitleKey: 'becomeRolesUi.graffiti.seoTitle', seoDescriptionKey: 'becomeRolesUi.graffiti.seoDescription', config: { kind: SKATE_GRAFFITI_KIND, selfTag: 'skategraffiti', identifier: 'graffiti-profile', heading: 'Graffiti / Mural Artist', headingKey: 'becomeRolesUi.graffiti.heading', tagline: 'Pieces, murals, skatepark art — paint the scene', taglineKey: 'becomeRolesUi.graffiti.tagline', noun: 'graffiti artist', nounKey: 'becomeRolesUi.graffiti.noun', accentText: 'text-lime-400', accentBg: 'bg-lime-500', accentChip: 'bg-lime-500 text-black border-lime-500', accentChipHover: 'hover:border-lime-500/60 hover:text-lime-400', icon: SprayCan, rateUnits: pickRateUnits('piece', 'project', 'day', 'hour'), rateLabel: 'Rate', rateLabelKey: 'becomeRolesUi.graffiti.rateLabel', portfolioLabel: 'Portfolio link (IG, site)', portfolioLabelKey: 'becomeRolesUi.graffiti.portfolioLabel', skillSections: [ { title: 'Style', titleKey: 'becomeRolesUi.graffiti.sectionStyle', entries: Object.entries(GRAFFITI_STYLE_LABELS), keyMap: GRAFFITI_STYLE_KEYS, required: true }, { title: 'Medium', titleKey: 'becomeRolesUi.graffiti.sectionMedium', entries: Object.entries(GRAFFITI_MEDIUM_LABELS), keyMap: GRAFFITI_MEDIUM_KEYS }, { title: 'Work Context', titleKey: 'becomeRolesUi.graffiti.sectionWorkContext', entries: Object.entries(GRAFFITI_CONTEXT_LABELS), keyMap: GRAFFITI_CONTEXT_KEYS }, ], extraFields: [ { tag: 'crew', label: 'Graffiti Crew', labelKey: 'becomeRolesUi.graffiti.crewLabel', placeholder: 'Your writing crew (optional)', placeholderKey: 'becomeRolesUi.graffiti.crewPlaceholder', helper: 'Separate from your skate crew — the writers you paint with.', helperKey: 'becomeRolesUi.graffiti.crewHelper' }, { tag: 'surfaces', label: 'Surfaces / Walls', labelKey: 'labUi.craftFields.surfaces', placeholder: 'e.g. concrete, brick, permitted walls', placeholderKey: 'becomeRolesUi.graffiti.surfacesPlaceholder' }, { tag: 'max_size', label: 'Max Size', labelKey: 'labUi.craftFields.maxSize', placeholder: 'e.g. up to 10 m', placeholderKey: 'becomeRolesUi.graffiti.maxSizePlaceholder' }, ], }, }, musician: { kind: 'craft', seoTitle: 'Add a Music Profile - SkateSpots', seoDescription: 'Skate and make music? List your band or solo project — genres, instruments and links.', seoTitleKey: 'becomeRolesUi.musician.seoTitle', seoDescriptionKey: 'becomeRolesUi.musician.seoDescription', config: { kind: SKATE_MUSICIAN_KIND, selfTag: 'skatemusician', identifier: 'musician-profile', heading: 'Musician / Band', headingKey: 'becomeRolesUi.musician.heading', tagline: 'Skate and make music? Get booked for demos, jams & after-parties', taglineKey: 'becomeRolesUi.musician.tagline', noun: 'musician', nounKey: 'becomeRolesUi.musician.noun', accentText: 'text-sky-400', accentBg: 'bg-sky-500', accentChip: 'bg-sky-500 text-white border-sky-500', accentChipHover: 'hover:border-sky-500/60 hover:text-sky-400', icon: Music, rateUnits: pickRateUnits('gig', 'event', 'hour', 'day'), rateLabel: 'Booking Rate', rateLabelKey: 'becomeRolesUi.musician.rateLabel', portfolioLabel: 'Website / EPK link', portfolioLabelKey: 'becomeRolesUi.musician.portfolioLabel', skillSections: [ { title: 'Genre', titleKey: 'becomeRolesUi.musician.sectionGenre', entries: Object.entries(MUSICIAN_GENRE_LABELS), keyMap: MUSICIAN_GENRE_KEYS, required: true }, { title: 'Instruments & Role', titleKey: 'becomeRolesUi.musician.sectionInstruments', entries: Object.entries(MUSICIAN_INSTRUMENT_LABELS), keyMap: MUSICIAN_INSTRUMENT_KEYS }, ], extraFields: [ { tag: 'act', label: 'Act Type', labelKey: 'becomeRolesUi.musician.actLabel', placeholder: 'solo / band / dj / producer', placeholderKey: 'becomeRolesUi.musician.actPlaceholder' }, { tag: 'spotify', label: 'Spotify', labelKey: 'becomeRolesUi.musician.spotifyLabel', type: 'url', placeholder: 'https://open.spotify.com/…', placeholderKey: 'becomeRolesUi.musician.spotifyPlaceholder' }, { tag: 'bandcamp', label: 'Bandcamp', labelKey: 'becomeRolesUi.musician.bandcampLabel', type: 'url', placeholder: 'https://…bandcamp.com', placeholderKey: 'becomeRolesUi.musician.bandcampPlaceholder' }, { tag: 'soundcloud', label: 'SoundCloud', labelKey: 'becomeRolesUi.musician.soundcloudLabel', type: 'url', placeholder: 'https://soundcloud.com/…', placeholderKey: 'becomeRolesUi.musician.soundcloudPlaceholder' }, { tag: 'youtube', label: 'YouTube', labelKey: 'becomeRolesUi.musician.youtubeLabel', type: 'url', placeholder: 'https://youtube.com/…', placeholderKey: 'becomeRolesUi.musician.youtubePlaceholder' }, { tag: 'set_length', label: 'Set Length', labelKey: 'labUi.craftFields.setLength', placeholder: 'e.g. 30–45 min', placeholderKey: 'becomeRolesUi.musician.setLengthPlaceholder' }, { tag: 'tech_rider', label: 'Tech Rider', labelKey: 'labUi.craftFields.techRider', placeholder: 'e.g. PA, mics, backline', placeholderKey: 'becomeRolesUi.musician.techRiderPlaceholder' }, ], }, }, judge: { kind: 'craft', seoTitle: 'Judge Skate Events - SkateSpots', seoDescription: 'List yourself as a skate event judge — Game of S.K.A.T.E., best trick jams, contests, am series and world tour stops. Get booked to run fair, credible events.', seoTitleKey: 'becomeRolesUi.judge.seoTitle', seoDescriptionKey: 'becomeRolesUi.judge.seoDescription', config: { kind: SKATE_JUDGE_KIND, selfTag: 'skatejudge', identifier: 'judge-profile', heading: 'Skate Event Judge', headingKey: 'becomeRolesUi.judge.heading', tagline: 'From flat-ground Game of S.K.A.T.E. to the World Destruction Tour — run it fair, run it credible', taglineKey: 'becomeRolesUi.judge.tagline', noun: 'judge', nounKey: 'becomeRolesUi.judge.noun', accentText: 'text-yellow-400', accentBg: 'bg-yellow-500', accentChip: 'bg-yellow-500 text-black border-yellow-500', accentChipHover: 'hover:border-yellow-500/60 hover:text-yellow-400', icon: Gavel, rateUnits: pickRateUnits('event', 'day', 'hour'), rateLabel: 'Day Rate / Fee', rateLabelKey: 'becomeRolesUi.judge.rateLabel', portfolioLabel: 'Results archive / profile link', portfolioLabelKey: 'becomeRolesUi.judge.portfolioLabel', skillSections: [ { title: 'Event Formats', titleKey: 'becomeRolesUi.judge.sectionEventFormats', entries: Object.entries(JUDGE_FORMAT_LABELS), keyMap: JUDGE_FORMAT_KEYS, required: true }, { title: 'Specialty', titleKey: 'becomeRolesUi.judge.sectionSpecialty', entries: Object.entries(JUDGE_SPECIALTY_LABELS), keyMap: JUDGE_SPECIALTY_KEYS }, { title: 'Level / Circuit', titleKey: 'becomeRolesUi.judge.sectionLevelCircuit', entries: Object.entries(JUDGE_LEVEL_LABELS), keyMap: JUDGE_LEVEL_KEYS }, ], extraFields: [ { tag: 'events_judged', label: 'Events Judged', labelKey: 'becomeRolesUi.judge.eventsJudgedLabel', placeholder: 'e.g. 40+ contests, 3 World Tour stops', placeholderKey: 'becomeRolesUi.judge.eventsJudgedPlaceholder', helper: 'Notable events, comps or tours you have officiated.', helperKey: 'becomeRolesUi.judge.eventsJudgedHelper' }, { tag: 'travel', label: 'Travel', labelKey: 'labUi.craftFields.travel', placeholder: 'e.g. regional / nationwide / international', placeholderKey: 'becomeRolesUi.judge.travelPlaceholder' }, { tag: 'certifications', label: 'Certifications', labelKey: 'labUi.craftFields.certifications', placeholder: 'e.g. national judging course', placeholderKey: 'becomeRolesUi.judge.certificationsPlaceholder' }, ], }, }, organizer: { kind: 'craft', seoTitle: 'Organize Skate Events - SkateSpots', seoDescription: 'List yourself as a skate event organizer — street jams, best trick, contests, meetups, demos and tour stops. Get discovered and booked to run the session.', seoTitleKey: 'becomeRolesUi.organizer.seoTitle', seoDescriptionKey: 'becomeRolesUi.organizer.seoDescription', config: { kind: SKATE_ORGANIZER_KIND, selfTag: 'skateorganizer', identifier: 'organizer-profile', heading: 'Event Organizer', headingKey: 'becomeRolesUi.organizer.heading', tagline: 'Jams, contests, meetups & demos — put on the session and bring the scene together', taglineKey: 'becomeRolesUi.organizer.tagline', noun: 'organizer', nounKey: 'becomeRolesUi.organizer.noun', accentText: 'text-teal-400', accentBg: 'bg-teal-600', accentChip: 'bg-teal-600 text-white border-teal-600', accentChipHover: 'hover:border-teal-500/60 hover:text-teal-400', icon: Tent, rateUnits: pickRateUnits('event', 'day', 'project'), rateLabel: 'Event Fee / Budget', rateLabelKey: 'becomeRolesUi.organizer.rateLabel', portfolioLabel: 'Past events / results link', portfolioLabelKey: 'becomeRolesUi.organizer.portfolioLabel', skillSections: [ { title: 'Event Types', titleKey: 'becomeRolesUi.organizer.sectionEventTypes', entries: Object.entries(ORGANIZER_EVENT_LABELS), keyMap: ORGANIZER_EVENT_KEYS, required: true }, { title: 'What You Handle', titleKey: 'becomeRolesUi.organizer.sectionWhatYouHandle', entries: Object.entries(ORGANIZER_SERVICE_LABELS), keyMap: ORGANIZER_SERVICE_KEYS }, { title: 'Scale', titleKey: 'becomeRolesUi.organizer.sectionScale', entries: Object.entries(ORGANIZER_SCALE_LABELS), keyMap: ORGANIZER_SCALE_KEYS }, ], extraFields: [ { tag: 'events_hosted', label: 'Events Organized', labelKey: 'becomeRolesUi.organizer.eventsHostedLabel', placeholder: 'e.g. 25 jams, 3 city comps', placeholderKey: 'becomeRolesUi.organizer.eventsHostedPlaceholder', helper: 'Notable events, comps or meetups you have run.', helperKey: 'becomeRolesUi.organizer.eventsHostedHelper' }, { tag: 'insurance', label: 'Insurance', labelKey: 'labUi.craftFields.insurance', placeholder: 'e.g. public liability included', placeholderKey: 'becomeRolesUi.organizer.insurancePlaceholder' }, { tag: 'permits', label: 'Permits', labelKey: 'labUi.craftFields.permits', placeholder: 'e.g. council permits handled', placeholderKey: 'becomeRolesUi.organizer.permitsPlaceholder' }, ], }, }, tattoo: { kind: 'craft', seoTitle: 'Become a Tattoo Artist - SkateSpots', seoDescription: 'List your tattoo work for the skate scene — styles, flash, custom and more.', seoTitleKey: 'becomeRolesUi.tattoo.seoTitle', seoDescriptionKey: 'becomeRolesUi.tattoo.seoDescription', config: { kind: SKATE_TATTOO_KIND, selfTag: 'skatetattoo', identifier: 'tattoo-profile', heading: 'Tattoo Artist', headingKey: 'becomeRolesUi.tattoo.heading', tagline: 'Ink for the scene — flash, custom, fine line & more', taglineKey: 'becomeRolesUi.tattoo.tagline', noun: 'tattoo artist', nounKey: 'becomeRolesUi.tattoo.noun', accentText: 'text-rose-400', accentBg: 'bg-rose-600', accentChip: 'bg-rose-600 text-white border-rose-600', accentChipHover: 'hover:border-rose-500/60 hover:text-rose-400', icon: Brush, rateUnits: pickRateUnits('hour', 'piece', 'session'), rateLabel: 'Rate / Hourly', rateLabelKey: 'becomeRolesUi.tattoo.rateLabel', portfolioLabel: 'Portfolio link (IG, site)', portfolioLabelKey: 'becomeRolesUi.tattoo.portfolioLabel', skillSections: [ { title: 'Styles', titleKey: 'becomeRolesUi.tattoo.sectionStyles', entries: Object.entries(TATTOO_STYLE_LABELS), keyMap: TATTOO_STYLE_KEYS, required: true }, { title: 'Method', titleKey: 'becomeRolesUi.tattoo.sectionMethod', entries: Object.entries(TATTOO_METHOD_LABELS), keyMap: TATTOO_METHOD_KEYS }, ], extraFields: [ { tag: 'studio', label: 'Studio / Shop', labelKey: 'becomeRolesUi.tattoo.studioLabel', placeholder: 'Studio name (optional)', placeholderKey: 'becomeRolesUi.tattoo.studioPlaceholder' }, { tag: 'books_open', label: 'Books Open', labelKey: 'becomeRolesUi.tattoo.booksOpenLabel', type: 'toggle', helper: 'Are you currently taking bookings?', helperKey: 'becomeRolesUi.tattoo.booksOpenHelper' }, { tag: 'deposit', label: 'Deposit', labelKey: 'labUi.craftFields.deposit', placeholder: 'e.g. 50 EUR non-refundable', placeholderKey: 'becomeRolesUi.tattoo.depositPlaceholder' }, { tag: 'minimum', label: 'Minimum', labelKey: 'labUi.craftFields.minimum', placeholder: 'e.g. 80 EUR', placeholderKey: 'becomeRolesUi.tattoo.minimumPlaceholder' }, ], }, }, trainer: { kind: 'craft', seoTitle: 'Become a Trainer / Physio - SkateSpots', seoDescription: 'Help skaters get strong and stay healthy — strength, mobility, injury prevention and recovery.', seoTitleKey: 'becomeRolesUi.trainer.seoTitle', seoDescriptionKey: 'becomeRolesUi.trainer.seoDescription', config: { kind: SKATE_TRAINER_KIND, selfTag: 'skatetrainer', identifier: 'trainer-profile', heading: 'Trainer / Physio', headingKey: 'becomeRolesUi.trainer.heading', tagline: 'Strength, mobility, injury prevention & recovery for skaters', taglineKey: 'becomeRolesUi.trainer.tagline', noun: 'trainer', nounKey: 'becomeRolesUi.trainer.noun', accentText: 'text-emerald-400', accentBg: 'bg-emerald-600', accentChip: 'bg-emerald-600 text-white border-emerald-600', accentChipHover: 'hover:border-emerald-500/60 hover:text-emerald-400', icon: Dumbbell, rateUnits: pickRateUnits('session', 'month', 'hour'), rateLabel: 'Rate / Session', rateLabelKey: 'becomeRolesUi.trainer.rateLabel', portfolioLabel: 'Profile / booking link', portfolioLabelKey: 'becomeRolesUi.trainer.portfolioLabel', skillSections: [ { title: 'Focus', titleKey: 'becomeRolesUi.trainer.sectionFocus', entries: Object.entries(TRAINER_FOCUS_LABELS), keyMap: TRAINER_FOCUS_KEYS, required: true }, { title: 'Injuries You Work With', titleKey: 'becomeRolesUi.trainer.sectionInjuries', entries: Object.entries(TRAINER_INJURY_LABELS), keyMap: TRAINER_INJURY_KEYS }, { title: 'Credentials & Setting', titleKey: 'becomeRolesUi.trainer.sectionCredentialsSetting', entries: Object.entries(TRAINER_CREDENTIAL_LABELS), keyMap: TRAINER_CREDENTIAL_KEYS }, ], extraFields: [ { tag: 'credentials', label: 'Certifications', labelKey: 'labUi.craftFields.certifications', placeholder: 'e.g. BSc Physiotherapy, CSCS…', placeholderKey: 'becomeRolesUi.trainer.credentialsPlaceholder', helper: 'List real qualifications — skaters trust verifiable credentials.', helperKey: 'becomeRolesUi.trainer.credentialsHelper' }, { tag: 'remote', label: 'Remote / Online', labelKey: 'becomeRolesUi.trainer.remoteLabel', type: 'toggle', helper: 'Do you offer online coaching or consultations?', helperKey: 'becomeRolesUi.trainer.remoteHelper' }, { tag: 'modalities', label: 'Modalities', labelKey: 'labUi.craftFields.modalities', placeholder: 'e.g. hands-on, S&C, dry needling', placeholderKey: 'becomeRolesUi.trainer.modalitiesPlaceholder' }, ], }, }, barber: { kind: 'craft', seoTitle: 'Become a Barber / Hairstylist - SkateSpots', seoDescription: 'List your barbershop or chair for the skate scene — cuts, fades, beard trims, colour and more. Get booked by skaters.', seoTitleKey: 'becomeRolesUi.barber.seoTitle', seoDescriptionKey: 'becomeRolesUi.barber.seoDescription', config: { kind: SKATE_BARBER_KIND, selfTag: 'skatebarber', identifier: 'barber-profile', heading: 'Barber / Hairstylist', headingKey: 'becomeRolesUi.barber.heading', tagline: 'Cuts, fades & beard trims for the scene — shop chair or mobile', taglineKey: 'becomeRolesUi.barber.tagline', noun: 'barber', nounKey: 'becomeRolesUi.barber.noun', accentText: 'text-cyan-400', accentBg: 'bg-cyan-600', accentChip: 'bg-cyan-600 text-white border-cyan-600', accentChipHover: 'hover:border-cyan-500/60 hover:text-cyan-400', icon: Sparkles, rateUnits: pickRateUnits('cut', 'hour', 'session'), rateLabel: 'Price / Cut', rateLabelKey: 'becomeRolesUi.barber.rateLabel', portfolioLabel: 'Cuts gallery / IG link', portfolioLabelKey: 'becomeRolesUi.barber.portfolioLabel', skillSections: [ { title: 'What You Offer', titleKey: 'becomeRolesUi.barber.sectionWhatYouOffer', entries: Object.entries(BARBER_SERVICE_LABELS), keyMap: BARBER_SERVICE_KEYS, required: true }, { title: 'Signature Styles', titleKey: 'becomeRolesUi.barber.sectionSignatureStyles', entries: Object.entries(BARBER_STYLE_LABELS), keyMap: BARBER_STYLE_KEYS }, { title: 'Setting', titleKey: 'becomeRolesUi.barber.sectionSetting', entries: Object.entries(BARBER_SETTING_LABELS), keyMap: BARBER_SETTING_KEYS }, ], extraFields: [ { tag: 'studio', label: 'Shop / Studio', labelKey: 'becomeRolesUi.barber.studioLabel', placeholder: 'Shop or studio name (optional)', placeholderKey: 'becomeRolesUi.barber.studioPlaceholder' }, { tag: 'books_open', label: 'Books Open', labelKey: 'becomeRolesUi.barber.booksOpenLabel', type: 'toggle', helper: 'Are you currently taking bookings?', helperKey: 'becomeRolesUi.barber.booksOpenHelper' }, { tag: 'duration', label: 'Appointment Length', labelKey: 'labUi.craftFields.duration', placeholder: 'e.g. 30–45 min', placeholderKey: 'becomeRolesUi.barber.durationPlaceholder' }, ], }, }, clothing: { kind: 'craft', seoTitle: 'Become a Clothing Designer - SkateSpots', seoDescription: 'Custom clothes, team kits & apparel for the scene.', seoTitleKey: 'becomeRolesUi.clothing.seoTitle', seoDescriptionKey: 'becomeRolesUi.clothing.seoDescription', config: { kind: SKATE_DESIGNER_KIND, selfTag: 'skateclothing', identifier: 'clothing-profile', heading: 'Clothing Designer', headingKey: 'becomeRolesUi.clothing.heading', tagline: 'Custom clothes, team kits & apparel for the scene', taglineKey: 'becomeRolesUi.clothing.tagline', noun: 'clothing designer', nounKey: 'becomeRolesUi.clothing.noun', accentText: 'text-violet-400', accentBg: 'bg-violet-600', accentChip: 'bg-violet-600 text-white border-violet-600', accentChipHover: 'hover:border-violet-500/60 hover:text-violet-400', icon: Shirt, rateUnits: pickRateUnits('piece', 'project', 'hour', 'day'), extraFields: [ { tag: 'minimum', label: 'Minimum', labelKey: 'labUi.craftFields.minimum', placeholder: 'e.g. 10 pieces', placeholderKey: 'becomeRolesUi.clothing.minimumPlaceholder' }, { tag: 'turnaround', label: 'Turnaround', labelKey: 'labUi.craftFields.turnaround', placeholder: 'e.g. 2-3 weeks', placeholderKey: 'becomeRolesUi.clothing.turnaroundPlaceholder' }, { tag: 'sizing', label: 'Size Range', labelKey: 'labUi.craftFields.sizing', placeholder: 'e.g. XS-3XL / made to measure', placeholderKey: 'becomeRolesUi.clothing.sizingPlaceholder' }, { tag: 'samples', label: 'Samples / Prototypes', labelKey: 'labUi.craftFields.samples', type: 'toggle', helper: 'Do you offer samples or prototypes before a full run?', helperKey: 'becomeRolesUi.clothing.samplesHelper' }, { tag: 'customization', label: 'Customisation', labelKey: 'labUi.craftFields.customization', placeholder: 'e.g. names, numbers, graphics', placeholderKey: 'becomeRolesUi.clothing.customizationPlaceholder' }, ], rateLabel: 'Rate', rateLabelKey: 'becomeRolesUi.clothing.rateLabel', portfolioLabel: 'Shop / portfolio link', portfolioLabelKey: 'becomeRolesUi.clothing.portfolioLabel', skillSections: [ { title: 'What You Make', titleKey: 'becomeRolesUi.clothing.sectionWhatYouMake', entries: Object.entries(DESIGNER_SERVICE_LABELS), keyMap: DESIGNER_SERVICE_KEYS, required: true }, { title: 'How You Make It', titleKey: 'becomeRolesUi.clothing.sectionHowYouMake', entries: Object.entries(DESIGNER_METHOD_LABELS), keyMap: DESIGNER_METHOD_KEYS }, { title: 'Materials', titleKey: 'becomeRolesUi.clothing.sectionMaterials', entries: Object.entries(DESIGNER_MATERIAL_LABELS), keyMap: DESIGNER_MATERIAL_KEYS }, ], }, }, }; export function getBecomeRole(slug: string | undefined): BecomeRole | undefined { if (!slug) return undefined; return BECOME_ROLES[slug.toLowerCase()]; }