Skip to content

Commit

Permalink
feat(site): Mise à jour du formulaire de contact (#3339)
Browse files Browse the repository at this point in the history
  • Loading branch information
mariheck authored Oct 16, 2024
1 parent 58fa6ef commit 7aa0105
Show file tree
Hide file tree
Showing 6 changed files with 184 additions and 155 deletions.
263 changes: 149 additions & 114 deletions packages/site/app/contact/ContactForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,16 @@ import classNames from 'classnames';
import { useEffect, useState } from 'react';
import { supabase } from '../initSupabase';
import { options } from './data';
import { Button, useEventTracker } from '@tet/ui';
import {
Button,
Field,
FormSectionGrid,
Input,
OptionValue,
Select,
Textarea,
useEventTracker,
} from '@tet/ui';
import { useRouter, useSearchParams } from 'next/navigation';

type FormData = {
Expand All @@ -14,6 +23,7 @@ type FormData = {
prenom: string;
nom: string;
email: string;
tel: string;
message: string;
};

Expand All @@ -23,12 +33,14 @@ const initFormData: FormData = {
prenom: '',
nom: '',
email: '',
tel: '',
message: '',
};

const ContactForm = () => {
const [formData, setFormData] = useState<FormData>(initFormData);
const [status, setStatus] = useState<'success' | 'error' | null>(null);
const [isError, setIsError] = useState(false);

const searchParams = useSearchParams();
const router = useRouter();
Expand All @@ -47,44 +59,54 @@ const ContactForm = () => {
});
};

const handleChangeSelect = (event: React.ChangeEvent<HTMLSelectElement>) => {
const option = event.target.options[event.target.selectedIndex];
const categorie = option.closest('optgroup')?.label ?? '';
const handleChangeSelect = (value: OptionValue) => {
const categorie = options.find((opt) =>
opt.options.some((o) => o.value === value)
);
const option = categorie?.options.find((opt) => opt.value === value);

setFormData((prevState) => ({
...prevState,
categorie,
objet: { value: event.target.value, label: option.innerText },
categorie: categorie?.title ?? '',
objet: option ?? { value: '', label: '' },
}));
};

const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();

const sentData = {
...formData,
objet: formData.objet.label,
};

const { data, error } = await supabase.functions.invoke(
'site_send_message',
{
body: sentData,
}
);

if (data) {
setStatus('success');
setFormData(initFormData);
if (objet !== null) {
router.push('/contact');
}
} else if (error) {
console.error(error);
setStatus('error');
if (
!formData.objet ||
!formData.nom ||
!formData.prenom ||
!formData.email
) {
setIsError(true);
} else {
console.error('site_send_message : aucune donnée reçue');
setStatus('error');
setIsError(false);
const sentData = {
...formData,
objet: formData.objet.label,
};
const { data, error } = await supabase.functions.invoke(
'site_send_message',
{
body: sentData,
}
);
if (data) {
setStatus('success');
setFormData(initFormData);
if (objet !== null) {
router.push('/contact');
}
} else if (error) {
console.error(error);
setStatus('error');
} else {
console.error('site_send_message : aucune donnée reçue');
setStatus('error');
}
}
};

Expand All @@ -105,7 +127,7 @@ const ContactForm = () => {
if (optionGroup && option) {
setFormData((prevState) => ({
...prevState,
categorie: optionGroup.group,
categorie: optionGroup.title,
objet: option,
message:
objet === 'panier'
Expand All @@ -124,97 +146,110 @@ const ContactForm = () => {
handleSubmit(event);
tracker('envoyer_message', {});
}}
className="border border-grey-4 rounded-lg max-md:p-4 md:max-lg:p-10 p-20"
>
<div className="fr-input-group">
<label className="fr-label" htmlFor="input-objet">
Objet de votre message
</label>
<select
className="fr-select"
id="objet"
name="objet"
required
onChange={handleChangeSelect}
value={formData.objet.value}
disabled={objet !== null}
<FormSectionGrid>
<Field
title="Objet de votre message *"
className="col-span-2"
state={isError && !formData.objet.value ? 'error' : 'default'}
message={
isError && !formData.objet.value
? 'Ce champ est obligatoire'
: undefined
}
>
<option value="" disabled hidden>
Selectionnez une option
</option>
{options.map((group) => (
<optgroup key={group.group} label={group.group}>
{group.options.map((opt) => (
<option key={opt.value} value={opt.value}>
{opt.label}
</option>
))}
</optgroup>
))}
</select>
</div>
<Select
options={options}
onChange={handleChangeSelect}
values={formData.objet.value}
disabled={objet !== null}
/>
</Field>

<div className="fr-input-group">
<label className="fr-label" htmlFor="input-name">
Votre prénom
</label>
<input
className="fr-input"
type="text"
id="prenom"
name="prenom"
required
onChange={handleChange}
value={formData.prenom}
/>
</div>
<Field
title="Votre prénom *"
className="max-md:col-span-2"
state={isError && !formData.prenom ? 'error' : 'default'}
message={
isError && !formData.prenom
? 'Ce champ est obligatoire'
: undefined
}
>
<Input
type="text"
id="prenom"
name="prenom"
onChange={handleChange}
value={formData.prenom}
/>
</Field>

<div className="fr-input-group">
<label className="fr-label" htmlFor="input-surname">
Votre nom
</label>
<input
className="fr-input"
type="text"
id="nom"
name="nom"
required
onChange={handleChange}
value={formData.nom}
/>
</div>
<Field
title="Votre nom *"
className="max-md:col-span-2"
state={isError && !formData.nom ? 'error' : 'default'}
message={
isError && !formData.nom ? 'Ce champ est obligatoire' : undefined
}
>
<Input
type="text"
id="nom"
name="nom"
onChange={handleChange}
value={formData.nom}
/>
</Field>

<div className="fr-input-group">
<label className="fr-label" htmlFor="input-email">
Votre adresse email professionnelle
</label>
<input
className="fr-input"
type="email"
id="email"
name="email"
required
onChange={handleChange}
value={formData.email}
/>
</div>
<Field
title="Votre adresse email professionnelle *"
className="max-md:col-span-2"
state={isError && !formData.email ? 'error' : 'default'}
message={
isError && !formData.email
? 'Ce champ est obligatoire'
: undefined
}
>
<Input
type="text"
id="email"
name="email"
onChange={handleChange}
value={formData.email}
/>
</Field>

<div className="fr-input-group">
<label className="fr-label" htmlFor="input-message">
Votre message
</label>
<textarea
className="fr-input"
id="message"
name="message"
required
onChange={handleChange}
value={formData.message}
/>
</div>
<Field
title="Votre numéro de téléphone"
className="max-md:col-span-2"
message="Ce champ nous permet de vous recontacter plus rapidement en fonction de votre demande"
>
<Input
type="tel"
id="tel"
name="tel"
onChange={handleChange}
value={formData.tel}
/>
</Field>

<div className="flex justify-end">
<Button>Envoyer</Button>
</div>
<Field title="Votre message" className="col-span-2">
<Textarea
id="message"
name="message"
onChange={handleChange}
value={formData.message}
rows={5}
/>
</Field>
</FormSectionGrid>

<Button type="submit" className="ml-auto mt-6">
Envoyer
</Button>
</form>

<ToastFloater
Expand Down
6 changes: 3 additions & 3 deletions packages/site/app/contact/data.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export const options = [
{
group:
title:
'Questions relatives au programme Territoire Engagé Transition Écologique',
options: [
{
Expand All @@ -23,7 +23,7 @@ export const options = [
],
},
{
group: 'Questions relatives à la plateforme Territoires en transitions',
title: 'Questions relatives à la plateforme Territoires en transitions',
options: [
{
value: 5,
Expand All @@ -44,7 +44,7 @@ export const options = [
],
},
{
group: 'Aucun de ces sujets ?',
title: 'Aucun de ces sujets ?',
options: [
{
value: 9,
Expand Down
Loading

0 comments on commit 7aa0105

Please sign in to comment.