Checkpoint: Suppression du cron RSS indépendant. La lecture des flux RSS est désormais intégrée dans le cron d'import quotidien (import_time dans Paramètres). Le panneau de planification RSS dans RssFeeds affiche maintenant l'heure configurée et redirige vers Paramètres pour la modifier. 0 erreur TypeScript.

This commit is contained in:
Manus
2026-06-26 10:38:49 -04:00
parent 6b8b3ce9d7
commit 9eb5849504
3 changed files with 34 additions and 182 deletions

View File

@@ -539,127 +539,31 @@ function FeedCard({
// ─── Panneau de configuration ─────────────────────────────────────────────────
function SettingsPanel({ isAdmin }: { isAdmin: boolean }) {
const { data: settings, refetch } = trpc.rss.getSettings.useQuery();
const saveMutation = trpc.rss.saveSettings.useMutation({
onSuccess: () => {
toast.success("Paramètres RSS sauvegardés");
refetch();
},
onError: (e) => toast.error("Erreur", { description: e.message }),
});
const [fetchMode, setFetchMode] = useState<"interval" | "scheduled">(settings?.fetchMode ?? "scheduled");
const [fetchIntervalMinutes, setFetchIntervalMinutes] = useState(settings?.fetchIntervalMinutes ?? 360);
const [scheduledTime, setScheduledTime] = useState(settings?.scheduledTime ?? "06:00");
const [autoFetchEnabled, setAutoFetchEnabled] = useState(settings?.autoFetchEnabled ?? true);
// Sync state when settings load
if (settings && settings.fetchMode !== fetchMode && !saveMutation.isPending) {
setFetchMode(settings.fetchMode);
setFetchIntervalMinutes(settings.fetchIntervalMinutes);
setScheduledTime(settings.scheduledTime ?? "06:00");
setAutoFetchEnabled(settings.autoFetchEnabled);
}
const handleSave = () => {
saveMutation.mutate({
fetchMode,
fetchIntervalMinutes,
scheduledTime,
autoFetchEnabled,
});
};
function SettingsPanel({ isAdmin: _isAdmin }: { isAdmin: boolean }) {
const { data: settings } = trpc.rss.getSettings.useQuery();
const importTime = settings?.scheduledTime ?? "06:00";
return (
<Card className="border-2 border-dashed border-primary/20">
<CardHeader className="pb-3">
<CardTitle className="flex items-center gap-2 text-base">
<Settings2 className="h-4 w-4 text-primary" />
Paramètres de lecture automatique
Planification de la lecture RSS
</CardTitle>
<CardDescription>
Configurez la fréquence et le mode de lecture des flux RSS.
La lecture des flux RSS est déclenchée automatiquement par le cron dimport quotidien.
</CardDescription>
</CardHeader>
<CardContent className="space-y-5">
{/* Activation */}
<div className="flex items-center justify-between p-3 bg-muted/50 rounded-lg">
<CardContent>
<div className="flex items-center gap-3 p-4 rounded-lg bg-muted/50 border border-border">
<Clock className="h-5 w-5 text-primary flex-shrink-0" />
<div>
<p className="font-medium text-sm">Lecture automatique</p>
<p className="text-xs text-muted-foreground">Active la récupération périodique des flux</p>
</div>
<Switch
checked={autoFetchEnabled}
onCheckedChange={setAutoFetchEnabled}
disabled={!isAdmin}
/>
</div>
{/* Mode */}
<div className="space-y-2">
<Label className="text-sm font-medium">Mode de planification</Label>
<div className="grid grid-cols-2 gap-3">
{(["scheduled", "interval"] as const).map((mode) => (
<button
key={mode}
type="button"
disabled={!isAdmin}
onClick={() => setFetchMode(mode)}
className={cn(
"flex items-center gap-2 p-3 rounded-lg border-2 text-left transition-all text-sm",
fetchMode === mode ? "border-primary bg-primary/5" : "border-border hover:border-primary/40",
!isAdmin && "opacity-50 cursor-not-allowed"
)}
>
<Clock className={cn("h-4 w-4", fetchMode === mode ? "text-primary" : "text-muted-foreground")} />
<div>
<p className="font-medium">{mode === "scheduled" ? "Heure fixe" : "Intervalle"}</p>
<p className="text-xs text-muted-foreground">{mode === "scheduled" ? "Chaque jour à une heure précise" : "Toutes les N minutes"}</p>
</div>
</button>
))}
<p className="font-medium text-sm">Lecture automatique chaque jour à <span className="text-primary font-bold">{importTime}</span></p>
<p className="text-xs text-muted-foreground mt-0.5">
Pour modifier lheure, rendez-vous dans <strong>Paramètres → Import &amp; Planification</strong>.
</p>
</div>
</div>
{/* Paramètre selon le mode */}
{fetchMode === "scheduled" ? (
<div className="space-y-1.5">
<Label className="text-sm">Heure de lecture quotidienne</Label>
<Input
type="time"
value={scheduledTime}
onChange={(e) => setScheduledTime(e.target.value)}
disabled={!isAdmin}
className="w-36"
/>
</div>
) : (
<div className="space-y-1.5">
<Label className="text-sm">Intervalle de lecture</Label>
<Select
value={String(fetchIntervalMinutes)}
onValueChange={(v) => setFetchIntervalMinutes(Number(v))}
disabled={!isAdmin}
>
<SelectTrigger className="w-48">
<SelectValue />
</SelectTrigger>
<SelectContent>
{INTERVAL_OPTIONS.map((opt) => (
<SelectItem key={opt.value} value={String(opt.value)}>{opt.label}</SelectItem>
))}
</SelectContent>
</Select>
</div>
)}
{isAdmin && (
<Button onClick={handleSave} disabled={saveMutation.isPending} size="sm" className="gap-2">
<Save className="h-3.5 w-3.5" />
{saveMutation.isPending ? "Enregistrement…" : "Sauvegarder les paramètres"}
</Button>
)}
</CardContent>
</Card>
);