rebours/sanity/schemas/product.ts
2026-04-11 17:42:39 +02:00

187 lines
4.8 KiB
TypeScript

import { defineType, defineField } from 'sanity'
export default defineType({
name: 'product',
title: 'Produit',
type: 'document',
orderings: [
{
title: 'Ordre d\'affichage',
name: 'sortOrder',
by: [{ field: 'sortOrder', direction: 'asc' }],
},
],
fields: [
defineField({
name: 'name',
title: 'Nom technique',
type: 'string',
description: 'Nom interne (ex: Solar_Altar)',
validation: (rule) => rule.required(),
}),
defineField({
name: 'productDisplayName',
title: 'Nom d\'affichage',
type: 'string',
description: 'Nom affiché au client (ex: Solar Altar)',
validation: (rule) => rule.required(),
}),
defineField({
name: 'slug',
title: 'Slug',
type: 'slug',
description: 'URL du produit (auto-généré depuis le nom)',
options: {
source: 'name',
slugify: (input: string) =>
input.toLowerCase()
.normalize('NFD').replace(/[\u0300-\u036f]/g, '')
.replace(/_/g, '-')
.replace(/[^a-z0-9-]/g, ''),
},
validation: (rule) => rule.required(),
}),
defineField({
name: 'sortOrder',
title: 'Ordre d\'affichage',
type: 'number',
initialValue: 0,
description: 'Plus petit = affiché en premier',
}),
defineField({
name: 'index',
title: 'Index projet',
type: 'string',
description: 'Ex: PROJET_001',
validation: (rule) => rule.required(),
}),
defineField({
name: 'type',
title: 'Type de produit',
type: 'string',
description: 'Ex: LAMPE DE TABLE',
validation: (rule) => rule.required(),
}),
defineField({
name: 'materials',
title: 'Matériaux',
type: 'string',
description: 'Ex: BÉTON TEXTURÉ + DÔME CÉRAMIQUE LAQUÉ',
validation: (rule) => rule.required(),
}),
defineField({
name: 'year',
title: 'Année',
type: 'string',
initialValue: '2026',
validation: (rule) => rule.required(),
}),
defineField({
name: 'status',
title: 'Status',
type: 'string',
description: 'Ex: PROTOTYPE [80%]',
validation: (rule) => rule.required(),
}),
defineField({
name: 'description',
title: 'Description',
type: 'text',
rows: 4,
validation: (rule) => rule.required(),
}),
defineField({
name: 'specs',
title: 'Spécifications techniques',
type: 'text',
rows: 4,
}),
defineField({
name: 'notes',
title: 'Notes de conception',
type: 'text',
rows: 4,
}),
defineField({
name: 'images',
title: 'Images produit',
type: 'array',
description: 'La première image est utilisée comme image principale',
validation: (rule) => rule.required().min(1),
of: [
{
type: 'image',
options: { hotspot: true },
fields: [
defineField({
name: 'alt',
title: 'Texte alternatif',
type: 'string',
description: 'Description de l\'image pour le SEO et l\'accessibilité',
}),
],
},
],
}),
defineField({
name: 'seoTitle',
title: 'Titre SEO',
type: 'string',
description: 'Auto: REBOURS — {Nom} | Collection 001',
}),
defineField({
name: 'seoDescription',
title: 'Description SEO',
type: 'text',
rows: 2,
description: 'Auto: tronqué depuis la description',
}),
defineField({
name: 'price',
title: 'Prix (centimes)',
type: 'number',
description: 'En centimes (180000 = 1 800 €). Laisser vide = non disponible.',
}),
defineField({
name: 'currency',
title: 'Devise',
type: 'string',
initialValue: 'EUR',
options: {
list: [
{ title: 'EUR', value: 'EUR' },
{ title: 'USD', value: 'USD' },
],
},
}),
defineField({
name: 'availability',
title: 'Disponibilité',
type: 'string',
initialValue: 'https://schema.org/PreOrder',
options: {
list: [
{ title: 'Pré-commande', value: 'https://schema.org/PreOrder' },
{ title: 'Disponible (limité)', value: 'https://schema.org/LimitedAvailability' },
{ title: 'En stock', value: 'https://schema.org/InStock' },
{ title: 'Épuisé', value: 'https://schema.org/SoldOut' },
],
},
}),
defineField({
name: 'isPublished',
title: 'Publié',
type: 'boolean',
initialValue: true,
description: 'Décocher pour masquer du site sans supprimer',
}),
],
preview: {
select: {
title: 'productDisplayName',
subtitle: 'type',
media: 'images.0',
},
},
})