81 lines
2.5 KiB
TypeScript
81 lines
2.5 KiB
TypeScript
|
|
import { useEffect, useState } from "react";
|
||
|
|
import { Cloud, Loader2 } from "lucide-react";
|
||
|
|
import PageHeader from "../components/PageHeader";
|
||
|
|
import FormField, { TextInput } from "../components/FormField";
|
||
|
|
import IntegrationForm from "../components/IntegrationForm";
|
||
|
|
import { getIntegration, type Integration } from "../api";
|
||
|
|
|
||
|
|
export default function WeatherSettings() {
|
||
|
|
const [integration, setIntegration] = useState<Integration | null>(null);
|
||
|
|
const [loading, setLoading] = useState(true);
|
||
|
|
const [error, setError] = useState("");
|
||
|
|
|
||
|
|
useEffect(() => {
|
||
|
|
loadIntegration();
|
||
|
|
}, []);
|
||
|
|
|
||
|
|
const loadIntegration = async () => {
|
||
|
|
try {
|
||
|
|
const data = await getIntegration("weather");
|
||
|
|
setIntegration(data);
|
||
|
|
} catch (err: any) {
|
||
|
|
setError(err.message);
|
||
|
|
} finally {
|
||
|
|
setLoading(false);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
if (loading) {
|
||
|
|
return (
|
||
|
|
<div className="flex items-center justify-center py-20">
|
||
|
|
<Loader2 className="w-5 h-5 text-slate-400 animate-spin" />
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (error || !integration) {
|
||
|
|
return (
|
||
|
|
<div>
|
||
|
|
<PageHeader icon={Cloud} title="Wetter" description="Wetteranbieter konfigurieren" />
|
||
|
|
<div className="glass-card p-6">
|
||
|
|
<p className="text-sm text-red-400">{error || "Integration nicht gefunden"}</p>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
return (
|
||
|
|
<div>
|
||
|
|
<PageHeader
|
||
|
|
icon={Cloud}
|
||
|
|
title="Wetter"
|
||
|
|
description="Standorte für die Wettervorhersage konfigurieren (wttr.in)"
|
||
|
|
/>
|
||
|
|
|
||
|
|
<div className="glass-card p-6">
|
||
|
|
<IntegrationForm integration={integration} onSaved={setIntegration}>
|
||
|
|
{(config, setConfig) => (
|
||
|
|
<>
|
||
|
|
<FormField label="Primärer Standort" description="Stadt oder Koordinaten für die Hauptanzeige">
|
||
|
|
<TextInput
|
||
|
|
value={(config.primary_location as string) || ""}
|
||
|
|
onChange={(v) => setConfig("primary_location", v)}
|
||
|
|
placeholder="z.B. Berlin oder 52.52,13.405"
|
||
|
|
/>
|
||
|
|
</FormField>
|
||
|
|
|
||
|
|
<FormField label="Sekundärer Standort" description="Zweiter Standort für den Vergleich">
|
||
|
|
<TextInput
|
||
|
|
value={(config.secondary_location as string) || ""}
|
||
|
|
onChange={(v) => setConfig("secondary_location", v)}
|
||
|
|
placeholder="z.B. München oder 48.137,11.576"
|
||
|
|
/>
|
||
|
|
</FormField>
|
||
|
|
</>
|
||
|
|
)}
|
||
|
|
</IntegrationForm>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|