Files
Momento/memento-note/components/structured-views/add-property-dialog.tsx
Antigravity 83110200d5
Some checks failed
CI / Lint, Unit Tests & Build (push) Failing after 1m31s
CI / Deploy production (on server) (push) Has been skipped
feat: calculs tableaux Structured Views + Link Preview + fixes
- Calculs en pied de tableau : Somme/Moyenne/Min/Max/Compte, cliquable pour changer
- Link Preview : métadonnées persistées + texte indexable pour recherche/embeddings
- Fix: bg-memento-paper → bg-card (dark mode) sur dialogs Structured Views
- Fix: bouton Ajouter un champ → brand-accent au lieu de primary
- Calendar view retiré du sélecteur (non pertinent)
2026-06-14 17:56:54 +00:00

129 lines
4.6 KiB
TypeScript

'use client'
import { useState } from 'react'
import { X } from 'lucide-react'
import { Button } from '@/components/ui/button'
import { useLanguage } from '@/lib/i18n'
import type { PropertyType } from '@/lib/structured-views/types'
import { PROPERTY_TYPES } from '@/lib/structured-views/types'
import { cn } from '@/lib/utils'
type AddPropertyDialogProps = {
open: boolean
onClose: () => void
onSubmit: (name: string, type: PropertyType, options: string[]) => Promise<void>
}
export function AddPropertyDialog({ open, onClose, onSubmit }: AddPropertyDialogProps) {
const { t } = useLanguage()
const [name, setName] = useState('')
const [type, setType] = useState<PropertyType>('text')
const [optionsText, setOptionsText] = useState('')
const [saving, setSaving] = useState(false)
if (!open) return null
const needsOptions = type === 'select' || type === 'multiselect'
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault()
const trimmed = name.trim()
if (!trimmed) return
const options = needsOptions
? optionsText.split('\n').map((l) => l.trim()).filter(Boolean)
: []
if (needsOptions && options.length === 0) return
setSaving(true)
try {
await onSubmit(trimmed, type, options)
setName('')
setType('text')
setOptionsText('')
onClose()
} finally {
setSaving(false)
}
}
return (
<div className="fixed inset-0 z-[200] flex items-center justify-center p-4 bg-black/40 backdrop-blur-sm">
<div
role="dialog"
aria-modal
className="w-full max-w-md rounded-2xl border border-border bg-card shadow-xl p-6 space-y-5"
>
<div className="flex items-center justify-between">
<h2 className="font-memento-serif text-lg">{t('structuredViews.addPropertyTitle')}</h2>
<button type="button" onClick={onClose} className="p-1 rounded-lg hover:bg-foreground/5">
<X size={18} />
</button>
</div>
<form onSubmit={handleSubmit} className="space-y-4">
<p className="text-[12px] leading-relaxed text-muted-foreground rounded-lg bg-foreground/[0.03] px-3 py-2">
{t('structuredViews.addPropertyHint')}
</p>
<div>
<label className="text-[10px] uppercase tracking-widest font-bold text-muted-foreground">
{t('structuredViews.propertyName')}
</label>
<input
value={name}
onChange={(e) => setName(e.target.value)}
className="mt-1 w-full rounded-lg border border-border bg-background px-3 py-2 text-sm"
autoFocus
/>
</div>
<div>
<label className="text-[10px] uppercase tracking-widest font-bold text-muted-foreground">
{t('structuredViews.propertyType')}
</label>
<div className="mt-2 flex flex-wrap gap-2">
{PROPERTY_TYPES.map((pt) => (
<button
key={pt}
type="button"
onClick={() => setType(pt)}
className={cn(
'px-3 py-1 rounded-full text-[10px] font-bold uppercase tracking-wider border transition-colors',
type === pt
? 'bg-foreground text-background border-foreground'
: 'border-border text-muted-foreground hover:border-foreground/30',
)}
>
{t(`structuredViews.propertyTypes.${pt}`)}
</button>
))}
</div>
</div>
{needsOptions && (
<div>
<label className="text-[10px] uppercase tracking-widest font-bold text-muted-foreground">
{t('structuredViews.selectOptions')}
</label>
<textarea
value={optionsText}
onChange={(e) => setOptionsText(e.target.value)}
placeholder={t('structuredViews.selectOptionsPlaceholder')}
rows={4}
className="mt-1 w-full rounded-lg border border-border bg-background px-3 py-2 text-sm resize-none"
/>
</div>
)}
<div className="flex justify-end gap-2 pt-2">
<Button type="button" variant="ghost" onClick={onClose}>
{t('general.cancel')}
</Button>
<Button type="submit" disabled={saving || !name.trim()} className="bg-brand-accent text-white hover:bg-brand-accent/90">
{t('structuredViews.addProperty')}
</Button>
</div>
</form>
</div>
</div>
)
}