181 lines
4.6 KiB
TypeScript
181 lines
4.6 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: 'image',
|
|
title: 'Image produit',
|
|
type: 'image',
|
|
options: { hotspot: true },
|
|
validation: (rule) => rule.required(),
|
|
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: 'image',
|
|
},
|
|
},
|
|
})
|