Files
workshop-manager/src/app/weather/new/page.tsx
Julien Froidefond e8ffccd286
Some checks failed
Deploy with Docker Compose / deploy (push) Has been cancelled
refactor: streamline date and title handling in NewWeatherPage and NewWeeklyCheckInPage components for improved user experience
2026-02-04 11:02:52 +01:00

148 lines
4.8 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client';
import { useState } from 'react';
import { useRouter } from 'next/navigation';
import {
Card,
CardHeader,
CardTitle,
CardDescription,
CardContent,
Button,
Input,
} from '@/components/ui';
import { createWeatherSession } from '@/actions/weather';
import { getWeekYearLabel } from '@/lib/date-utils';
export default function NewWeatherPage() {
const router = useRouter();
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const [selectedDate, setSelectedDate] = useState(new Date().toISOString().split('T')[0]);
const [title, setTitle] = useState(() => getWeekYearLabel(new Date(new Date().toISOString().split('T')[0])));
const [isTitleManuallyEdited, setIsTitleManuallyEdited] = useState(false);
async function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
setError(null);
setLoading(true);
const date = selectedDate ? new Date(selectedDate) : undefined;
if (!title) {
setError('Veuillez remplir le titre');
setLoading(false);
return;
}
const result = await createWeatherSession({ title, date });
if (!result.success) {
setError(result.error || 'Une erreur est survenue');
setLoading(false);
return;
}
router.push(`/weather/${result.data?.id}`);
}
function handleDateChange(e: React.ChangeEvent<HTMLInputElement>) {
const newDate = e.target.value;
setSelectedDate(newDate);
// Only update title if user hasn't manually modified it
if (!isTitleManuallyEdited) {
setTitle(getWeekYearLabel(new Date(newDate)));
}
}
function handleTitleChange(e: React.ChangeEvent<HTMLInputElement>) {
setTitle(e.target.value);
setIsTitleManuallyEdited(true);
}
return (
<main className="mx-auto max-w-2xl px-4 py-8">
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<span>🌤</span>
Nouvelle Météo
</CardTitle>
<CardDescription>
Créez une météo personnelle pour faire le point sur 4 axes clés et partagez-la avec votre équipe
</CardDescription>
</CardHeader>
<CardContent>
<form onSubmit={handleSubmit} className="space-y-6">
{error && (
<div className="rounded-lg border border-destructive/20 bg-destructive/10 p-3 text-sm text-destructive">
{error}
</div>
)}
<Input
label="Titre de la météo"
name="title"
placeholder="Ex: Météo S05 - 2026"
value={title}
onChange={handleTitleChange}
required
/>
<div>
<label htmlFor="date" className="block text-sm font-medium text-foreground mb-1">
Date de la météo
</label>
<input
id="date"
name="date"
type="date"
value={selectedDate}
onChange={handleDateChange}
required
className="w-full rounded-lg border border-border bg-input px-3 py-2 text-foreground outline-none focus:border-primary focus:ring-2 focus:ring-primary/20"
/>
</div>
<div className="rounded-lg border border-border bg-card-hover p-4">
<h3 className="font-medium text-foreground mb-2">Comment ça marche ?</h3>
<ol className="text-sm text-muted space-y-1 list-decimal list-inside">
<li>
<strong>Performance</strong> : Comment évaluez-vous votre performance personnelle ?
</li>
<li>
<strong>Moral</strong> : Quel est votre moral actuel ?
</li>
<li>
<strong>Flux</strong> : Comment se passe votre flux de travail personnel ?
</li>
<li>
<strong>Création de valeur</strong> : Comment évaluez-vous votre création de valeur ?
</li>
</ol>
<p className="text-sm text-muted mt-2">
💡 <strong>Astuce</strong> : Partagez votre météo avec votre équipe pour qu&apos;ils puissent voir votre état. Chaque membre peut créer sa propre météo et la partager !
</p>
</div>
<div className="flex gap-3 pt-4">
<Button
type="button"
variant="outline"
onClick={() => router.back()}
disabled={loading}
>
Annuler
</Button>
<Button type="submit" loading={loading} className="flex-1">
Créer la météo
</Button>
</div>
</form>
</CardContent>
</Card>
</main>
);
}