feat(04-02): Unsplash API key in types e pagina Settings
- Aggiunto unsplash_api_key a interface Settings - Aggiunto unsplash_api_key_configured a interface SettingsStatus - Aggiunta sezione 'Immagini' in Settings con campo API Key Unsplash - Toggle visibilita' showUnsplashKey separato da showApiKey - Helper text condizionale: messaggio diverso se key configurata o no - Logica submit: unsplash_api_key vuota non sovrascrive quella esistente - Reset campo dopo salvataggio come per api_key Claude
This commit is contained in:
@@ -30,6 +30,7 @@ export function Settings() {
|
||||
|
||||
const [form, setForm] = useState<Partial<SettingsType>>({})
|
||||
const [showApiKey, setShowApiKey] = useState(false)
|
||||
const [showUnsplashKey, setShowUnsplashKey] = useState(false)
|
||||
const [saved, setSaved] = useState(false)
|
||||
|
||||
// Popola il form quando i settings arrivano dal backend
|
||||
@@ -37,6 +38,7 @@ export function Settings() {
|
||||
if (settings) {
|
||||
setForm({
|
||||
api_key: '', // Non pre-populare l'API key (mascherata)
|
||||
unsplash_api_key: '', // Non pre-populare la Unsplash key (mascherata)
|
||||
llm_model: settings.llm_model,
|
||||
nicchie_attive: settings.nicchie_attive,
|
||||
lingua: settings.lingua,
|
||||
@@ -62,16 +64,20 @@ export function Settings() {
|
||||
async function handleSubmit(e: React.FormEvent) {
|
||||
e.preventDefault()
|
||||
|
||||
// Prepara il payload: non inviare api_key se vuota (evita sovrascrittura)
|
||||
// Prepara il payload: non inviare api_key/unsplash_api_key se vuote (evita sovrascrittura)
|
||||
const payload: Partial<SettingsType> = { ...form }
|
||||
if (!payload.api_key || payload.api_key.trim() === '') {
|
||||
delete payload.api_key
|
||||
}
|
||||
if (!payload.unsplash_api_key || payload.unsplash_api_key.trim() === '') {
|
||||
delete payload.unsplash_api_key
|
||||
}
|
||||
|
||||
try {
|
||||
await updateMutation.mutateAsync(payload)
|
||||
setSaved(true)
|
||||
setForm((prev) => ({ ...prev, api_key: '' })) // Reset campo API key dopo salvataggio
|
||||
// Reset campi API key dopo salvataggio
|
||||
setForm((prev) => ({ ...prev, api_key: '', unsplash_api_key: '' }))
|
||||
setTimeout(() => setSaved(false), 3000)
|
||||
} catch {
|
||||
// L'errore è gestito da updateMutation.error
|
||||
@@ -141,6 +147,37 @@ export function Settings() {
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Immagini / Unsplash */}
|
||||
<section className="space-y-4">
|
||||
<h2 className="text-xs font-semibold text-stone-500 uppercase tracking-wider">Immagini</h2>
|
||||
<div className="space-y-1.5">
|
||||
<label className="block text-sm font-medium text-stone-300">
|
||||
API Key Unsplash <span className="text-stone-600 font-normal">(opzionale)</span>
|
||||
</label>
|
||||
<div className="relative">
|
||||
<input
|
||||
type={showUnsplashKey ? 'text' : 'password'}
|
||||
value={form.unsplash_api_key ?? ''}
|
||||
onChange={(e) => setForm((p) => ({ ...p, unsplash_api_key: e.target.value }))}
|
||||
placeholder={settings?.unsplash_api_key ? '••••••••••••••••' : 'Incolla la tua Access Key Unsplash'}
|
||||
className="w-full px-3 py-2 pr-10 rounded-lg bg-stone-800 border border-stone-700 text-stone-100 text-sm placeholder-stone-600 focus:outline-none focus:ring-2 focus:ring-amber-500/50 focus:border-amber-500/50"
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setShowUnsplashKey((v) => !v)}
|
||||
className="absolute right-2.5 top-1/2 -translate-y-1/2 text-stone-500 hover:text-stone-300 transition-colors"
|
||||
>
|
||||
{showUnsplashKey ? <EyeOff size={16} /> : <Eye size={16} />}
|
||||
</button>
|
||||
</div>
|
||||
<p className="text-xs text-stone-600">
|
||||
{settings?.unsplash_api_key
|
||||
? 'API key Unsplash configurata. Le keyword verranno risolte in URL immagini reali nel CSV.'
|
||||
: 'Opzionale. Registrati su unsplash.com/developers per ottenere una Access Key gratuita (50 req/h).'}
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Brand */}
|
||||
<section className="space-y-4">
|
||||
<h2 className="text-xs font-semibold text-stone-500 uppercase tracking-wider">Brand</h2>
|
||||
|
||||
@@ -146,11 +146,13 @@ export interface Settings {
|
||||
frequenza_post: number
|
||||
brand_name?: string | null
|
||||
tono?: string | null
|
||||
unsplash_api_key?: string | null
|
||||
}
|
||||
|
||||
export interface SettingsStatus {
|
||||
api_key_configured: boolean
|
||||
llm_model: string
|
||||
unsplash_api_key_configured: boolean
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user