import React from 'react' import type { ArticleDraft } from '@/lib/articlePublisher' import type { ArticleCategory } from '@/types/nostr' import { ArticleField } from './ArticleField' import { ArticleFormButtons } from './ArticleFormButtons' import { CategorySelect } from './CategorySelect' import { MarkdownEditor } from './MarkdownEditor' import type { MediaRef } from '@/types/nostr' interface ArticleEditorFormProps { draft: ArticleDraft onDraftChange: (draft: ArticleDraft) => void onSubmit: (e: React.FormEvent) => void loading: boolean error: string | null onCancel?: () => void seriesOptions?: { id: string; title: string }[] | undefined onSelectSeries?: ((seriesId: string | undefined) => void) | undefined } function CategoryField({ value, onChange, }: { value: ArticleDraft['category'] onChange: (value: import('@/types/nostr').ArticleCategory | undefined) => void }) { return ( ) } function ErrorAlert({ error }: { error: string | null }) { if (!error) { return null } return (

{error}

) } function buildCategoryChangeHandler( draft: ArticleDraft, onDraftChange: (draft: ArticleDraft) => void ): (value: ArticleCategory | undefined) => void { return (value) => { if (value === 'science-fiction' || value === 'scientific-research' || value === undefined) { const nextDraft: ArticleDraft = { ...draft } if (value) { nextDraft.category = value } else { delete (nextDraft as { category?: ArticleDraft['category'] }).category } onDraftChange(nextDraft) } } } const ArticleFieldsLeft = ({ draft, onDraftChange, seriesOptions, onSelectSeries, }: { draft: ArticleDraft onDraftChange: (draft: ArticleDraft) => void seriesOptions?: { id: string; title: string }[] | undefined onSelectSeries?: ((seriesId: string | undefined) => void) | undefined }) => (
{seriesOptions && ( )}
) function ArticleTitleField({ draft, onDraftChange }: { draft: ArticleDraft; onDraftChange: (draft: ArticleDraft) => void }) { return ( onDraftChange({ ...draft, title: value as string })} required placeholder="Entrez le titre de l'article" /> ) } function ArticlePreviewField({ draft, onDraftChange, }: { draft: ArticleDraft onDraftChange: (draft: ArticleDraft) => void }) { return ( onDraftChange({ ...draft, preview: value as string })} required type="textarea" rows={4} placeholder="Cet aperçu sera visible par tous gratuitement" helpText="Ce contenu sera visible par tous" /> ) } function SeriesSelect({ draft, onDraftChange, seriesOptions, onSelectSeries, }: { draft: ArticleDraft onDraftChange: (draft: ArticleDraft) => void seriesOptions: { id: string; title: string }[] onSelectSeries?: ((seriesId: string | undefined) => void) | undefined }) { const handleChange = buildSeriesChangeHandler(draft, onDraftChange, onSelectSeries) return (
) } function buildSeriesChangeHandler( draft: ArticleDraft, onDraftChange: (draft: ArticleDraft) => void, onSelectSeries?: ((seriesId: string | undefined) => void) | undefined ) { return (e: React.ChangeEvent) => { const value = e.target.value || undefined const nextDraft = { ...draft } if (value) { nextDraft.seriesId = value } else { delete (nextDraft as { seriesId?: string }).seriesId } onDraftChange(nextDraft) onSelectSeries?.(value) } } const ArticleFieldsRight = ({ draft, onDraftChange, }: { draft: ArticleDraft onDraftChange: (draft: ArticleDraft) => void }) => (
Contenu complet (Privé) — Markdown + preview
onDraftChange({ ...draft, content: value })} onMediaAdd={(media: MediaRef) => { const nextMedia = [...(draft.media ?? []), media] onDraftChange({ ...draft, media: nextMedia }) }} onBannerChange={(url: string) => { onDraftChange({ ...draft, bannerUrl: url }) }} />

Les médias sont uploadés via NIP-95 (images ≤5Mo, vidéos ≤45Mo) et insérés comme URL. Le contenu reste chiffré pour les acheteurs.

onDraftChange({ ...draft, zapAmount: value as number })} required type="number" min={1} helpText="Montant en satoshis pour débloquer le contenu complet" />
) export function ArticleEditorForm({ draft, onDraftChange, onSubmit, loading, error, onCancel, seriesOptions, onSelectSeries, }: ArticleEditorFormProps) { return (

Publier un nouvel article

) }