trptk-sanity/schemaTypes/concert-type.ts
2026-02-24 12:22:46 +01:00

126 lines
3 KiB
TypeScript

import {defineArrayMember, defineField, defineType} from 'sanity'
import {CalendarIcon} from '@sanity/icons'
import {countryList} from './country-list'
import {CountryInput} from '../components/CountryInput'
export const concertType = defineType({
name: 'concert',
title: 'Concert',
type: 'document',
icon: CalendarIcon,
fieldsets: [{name: 'details', title: 'Details', options: {columns: 2}}],
fields: [
defineField({
name: 'title',
title: 'Title',
type: 'string',
}),
defineField({
name: 'subtitle',
title: 'Subtitle',
type: 'string',
}),
defineField({
name: 'date',
title: 'Date',
type: 'date',
fieldset: 'details',
validation: (Rule) => Rule.required(),
}),
defineField({
name: 'time',
title: 'Time',
type: 'string',
fieldset: 'details',
description: '24-hour format, e.g. 20:00',
validation: (Rule) =>
Rule.required().custom((value) => {
if (typeof value !== 'string') return 'Time is required'
return /^([01]\d|2[0-3]):[0-5]\d$/.test(value.trim())
? true
: 'Use HH:mm in 24-hour format (e.g. 14:30, 20:00)'
}),
}),
defineField({
name: 'locationName',
title: 'Location',
type: 'string',
fieldset: 'details',
description: 'e.g. "Concertgebouw"',
validation: (Rule) => Rule.required(),
}),
defineField({
name: 'city',
title: 'City',
type: 'string',
fieldset: 'details',
description: 'e.g. "Amsterdam"',
validation: (Rule) => Rule.required(),
}),
defineField({
name: 'country',
title: 'Country',
type: 'string',
fieldset: 'details',
components: {input: CountryInput},
options: {
list: countryList,
},
validation: (Rule) => Rule.required(),
}),
defineField({
name: 'artists',
title: 'Related Artist(s)',
type: 'array',
of: [defineArrayMember({type: 'reference', to: [{type: 'artist'}]})],
}),
defineField({
name: 'ticketUrl',
title: 'Ticket URL',
type: 'url',
}),
],
orderings: [
{
title: 'Date (Asc.)',
name: 'dateAsc',
by: [
{field: 'date', direction: 'asc'},
{field: 'time', direction: 'asc'},
],
},
{
title: 'Date (Desc.)',
name: 'dateDesc',
by: [
{field: 'date', direction: 'desc'},
{field: 'time', direction: 'desc'},
],
},
],
preview: {
select: {
title: 'title',
date: 'date',
time: 'time',
locationName: 'locationName',
city: 'city',
},
prepare({title, date, time, locationName, city}) {
const parts = [locationName, city].filter(Boolean).join(', ')
const when = [date, time].filter(Boolean).join(' · ')
return {
title: title || parts || '(Untitled concert)',
subtitle: [when, title ? parts : null].filter(Boolean).join(' • '),
}
},
},
})