import React, {useEffect, useState} from 'react'; import {getJson, patchJson, postJson} from '../api'; import {errorMessages} from '../errors'; import Modal from './Modal'; // The same fields as the garden form page, in a dialog over the page. Given a // garden it edits it: loads the current values from /gardens/:slug/edit.json // and saves with PATCH. Given none it adds one: loads /gardens/new.json and // saves with POST. Either way it hands the garden's card to onSaved, so a list // updates in place and the page is never left. export default function GardenFormModal({garden = null, onClose, onSaved}) { const isNew = !garden; const [form, setForm] = useState(null); // {garden, area_units, garden_types, location_help, ...} const [values, setValues] = useState(null); const [loadError, setLoadError] = useState(false); const [saving, setSaving] = useState(false); const [errors, setErrors] = useState([]); useEffect(() => { const controller = new AbortController(); (async () => { try { const {ok, data} = await getJson(isNew ? '/gardens/new.json' : `${garden.url}/edit.json`, {signal: controller.signal}); if (!ok) throw new Error('load failed'); setForm(data); setValues(data.garden); } catch (error) { if (error.name !== 'AbortError') setLoadError(true); } })(); return () => controller.abort(); }, [isNew, garden && garden.url]); const set = (field) => (event) => { const {type, checked, value} = event.target; setValues((current) => ({...current, [field]: type === 'checkbox' ? checked : value})); }; async function save(event) { event.preventDefault(); setSaving(true); setErrors([]); const {name, description, area, area_unit: areaUnit, garden_type_id: gardenTypeId, active} = values; try { const body = {garden: {name, description, area, area_unit: areaUnit, garden_type_id: gardenTypeId, active}}; const {ok, status, data} = isNew ? await postJson('/gardens.json', body) : await patchJson(garden.url, body); if (ok) { onSaved(data.garden); // closes this dialog return; } setErrors(errorMessages(status, data, {signedOut: 'Please sign in again to save this garden.', forbidden: 'You can\'t change this garden.'})); } catch (error) { setErrors(['Couldn\'t reach the server. Please try again.']); } setSaving(false); } return ( {loadError && (
Couldn’t load this garden. Please close this and try again.
)} {!loadError && !values && (