135 lines
3.7 KiB
TypeScript
135 lines
3.7 KiB
TypeScript
import { defineField, defineType } from 'sanity'
|
|
|
|
export const eventType = defineType({
|
|
name: 'event',
|
|
title: 'Событие',
|
|
type: 'document',
|
|
icon: () => '📅',
|
|
fields: [
|
|
defineField({
|
|
name: 'title',
|
|
title: 'Название',
|
|
type: 'string',
|
|
validation: (Rule) => Rule.required().min(5).max(200),
|
|
}),
|
|
defineField({
|
|
name: 'slug',
|
|
title: 'Slug',
|
|
type: 'slug',
|
|
options: {
|
|
source: 'title',
|
|
maxLength: 96,
|
|
},
|
|
validation: (Rule) => Rule.required(),
|
|
}),
|
|
defineField({
|
|
name: 'eventType',
|
|
title: 'Тип события',
|
|
type: 'string',
|
|
options: {
|
|
list: [
|
|
{ title: 'Собрание', value: 'meeting' },
|
|
{ title: 'Воркшоп', value: 'workshop' },
|
|
{ title: 'Конференция', value: 'conference' },
|
|
{ title: 'Конкурс', value: 'contest' },
|
|
{ title: 'Праздник', value: 'celebration' },
|
|
{ title: 'Другое', value: 'other' },
|
|
],
|
|
layout: 'dropdown',
|
|
},
|
|
initialValue: 'other',
|
|
}),
|
|
defineField({
|
|
name: 'date',
|
|
title: 'Дата начала',
|
|
type: 'datetime',
|
|
validation: (Rule) => Rule.required(),
|
|
}),
|
|
defineField({
|
|
name: 'endDate',
|
|
title: 'Дата окончания',
|
|
type: 'datetime',
|
|
description: 'Оставьте пустым для однодневных событий',
|
|
}),
|
|
defineField({
|
|
name: 'location',
|
|
title: 'Место проведения',
|
|
type: 'string',
|
|
description: 'Например: Ауд. 4-01, Корпус ИМИТ',
|
|
}),
|
|
defineField({
|
|
name: 'image',
|
|
title: 'Изображение',
|
|
type: 'image',
|
|
options: {
|
|
hotspot: true,
|
|
},
|
|
fields: [
|
|
{
|
|
name: 'alt',
|
|
type: 'string',
|
|
title: 'Альтернативный текст',
|
|
},
|
|
],
|
|
}),
|
|
defineField({
|
|
name: 'description',
|
|
title: 'Описание',
|
|
type: 'blockContent',
|
|
}),
|
|
defineField({
|
|
name: 'isHighlighted',
|
|
title: 'Выделить событие',
|
|
type: 'boolean',
|
|
description: 'Выделенные события отображаются на главной странице',
|
|
initialValue: false,
|
|
}),
|
|
defineField({
|
|
name: 'registrationLink',
|
|
title: 'Ссылка на регистрацию',
|
|
type: 'url',
|
|
description: 'Внешняя ссылка для регистрации на событие',
|
|
}),
|
|
],
|
|
preview: {
|
|
select: {
|
|
title: 'title',
|
|
date: 'date',
|
|
eventType: 'eventType',
|
|
media: 'image',
|
|
isHighlighted: 'isHighlighted',
|
|
},
|
|
prepare({ title, date, eventType, media, isHighlighted }) {
|
|
const eventTypeLabels: Record<string, string> = {
|
|
meeting: 'Собрание',
|
|
workshop: 'Воркшоп',
|
|
conference: 'Конференция',
|
|
contest: 'Конкурс',
|
|
celebration: 'Праздник',
|
|
other: 'Событие',
|
|
}
|
|
const formattedDate = date
|
|
? new Date(date).toLocaleDateString('ru-RU')
|
|
: 'Дата не указана'
|
|
const highlight = isHighlighted ? '⭐ ' : ''
|
|
return {
|
|
title: `${highlight}${title}`,
|
|
subtitle: `${eventTypeLabels[eventType] || 'Событие'} • ${formattedDate}`,
|
|
media,
|
|
}
|
|
},
|
|
},
|
|
orderings: [
|
|
{
|
|
title: 'Дата (ближайшие)',
|
|
name: 'dateAsc',
|
|
by: [{ field: 'date', direction: 'asc' }],
|
|
},
|
|
{
|
|
title: 'Дата (прошедшие)',
|
|
name: 'dateDesc',
|
|
by: [{ field: 'date', direction: 'desc' }],
|
|
},
|
|
],
|
|
})
|