Nicolas Cantu 3000872dbc refactoring
- **Motivations :** Assurer passage du lint strict et clarifier la logique paiements/publications.

- **Root causes :** Fonctions trop longues, promesses non gérées et typages WebLN/Nostr incomplets.

- **Correctifs :** Refactor PaymentModal (handlers void), extraction helpers articlePublisher, simplification polling sponsoring/zap, corrections curly et awaits.

- **Evolutions :** Nouveau module articlePublisherHelpers pour présentation/aiguillage contenu privé.

- **Page affectées :** components/PaymentModal.tsx, lib/articlePublisher.ts, lib/articlePublisherHelpers.ts, lib/paymentPolling.ts, lib/sponsoring.ts, lib/nostrZapVerification.ts et dépendances liées.
2025-12-22 17:56:00 +01:00

119 lines
2.4 KiB
TypeScript

import React from 'react'
interface ArticleFieldProps {
id: string
label: string
value: string | number
onChange: (value: string | number) => void
required?: boolean
type?: 'text' | 'textarea' | 'number'
rows?: number
placeholder?: string
helpText?: string
min?: number
}
function NumberOrTextInput({
id,
type,
value,
placeholder,
required,
min,
onChange,
className,
}: {
id: string
type: 'text' | 'number'
value: string | number
placeholder?: string
required: boolean
min?: number
className: string
onChange: (value: string | number) => void
}) {
return (
<input
id={id}
type={type}
value={value}
onChange={(e) => onChange(type === 'number' ? Number(e.target.value) || 0 : e.target.value)}
className={className}
placeholder={placeholder}
min={min}
required={required}
/>
)
}
function TextAreaInput({
id,
value,
placeholder,
required,
rows,
className,
onChange,
}: {
id: string
value: string | number
placeholder?: string
required: boolean
rows?: number
className: string
onChange: (value: string | number) => void
}) {
return (
<textarea
id={id}
value={value}
onChange={(e) => onChange(e.target.value)}
className={className}
rows={rows}
placeholder={placeholder}
required={required}
/>
)
}
export function ArticleField(props: ArticleFieldProps) {
const { id, label, value, onChange, required = false, type = 'text', rows, placeholder, helpText, min } =
props
const inputClass =
'w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500'
const input =
type === 'textarea' ? (
<TextAreaInput
id={id}
value={value}
placeholder={placeholder}
required={required}
rows={rows}
className={inputClass}
onChange={onChange}
/>
) : (
<NumberOrTextInput
id={id}
type={type}
value={value}
placeholder={placeholder}
required={required}
min={min}
className={inputClass}
onChange={onChange}
/>
)
return (
<div>
<label htmlFor={id} className="block text-sm font-medium text-gray-700 mb-1">
{label} {required && '*'}
</label>
{input}
{helpText && <p className="text-xs text-gray-500 mt-1">{helpText}</p>}
</div>
)
}