import React, {useEffect, useRef, useState} from 'react'; import {postJson} from '../api'; import CropPicker from './CropPicker'; import Modal from './Modal'; import Steps from './Steps'; const FIELD_NAMES = {crop: 'Crop', garden: 'Garden'}; const STEPS = ['Choose a crop', 'Confirm']; function humanize(field) { return FIELD_NAMES[field] || field.replace(/_/g, ' ').replace(/^./, (c) => c.toUpperCase()); } function errorMessages(status, data) { if (status === 422 && data && data.errors) { const messages = Object.entries(data.errors).flatMap(([field, list]) => list.map((m) => `${humanize(field)} ${m}`)); if (messages.length > 0) return messages; } if (status === 403) return ['You can\'t plant in this garden.']; if (status === 401) return ['Please sign in again to plant something.']; return ['Something went wrong saving that. Please try again.']; } // "Add planting", as a dialog over the garden cards. Two steps: search // for a crop and choose it, then confirm what you chose and it is planted in the // card's garden (today, with no other details; those can be added later). On // success it hands back the garden's updated card. export default function PlantSomethingModal({garden, iconUrl, onClose, onCreated}) { const [crop, setCrop] = useState(null); // chosen, waiting for confirmation const [saving, setSaving] = useState(false); const [errors, setErrors] = useState([]); const confirmButton = useRef(null); // Once a crop is chosen the search goes away; Enter then confirms. useEffect(() => { if (crop && confirmButton.current) confirmButton.current.focus(); }, [crop]); async function confirm() { setSaving(true); setErrors([]); try { const {ok, status, data} = await postJson('/plantings.json', {planting: {garden_id: garden.id, crop_id: crop.id}}); if (ok) { onCreated(data.garden, crop); // closes this dialog return; } setErrors(errorMessages(status, data)); } catch (error) { setErrors(['Couldn\'t reach the server. Please try again.']); } setSaving(false); } const title = ( <> {iconUrl && } Plant something in {garden.name} ); return (
{errors.length > 0 && (