import React, {useState} from 'react'; import {postJson} from '../api'; import {daysBefore, localToday} from '../dates'; import {errorMessages} from '../errors'; import CropDetails from './CropDetails'; import CropPicker from './CropPicker'; import Modal from './Modal'; import SeedPacket from './SeedPacket'; import SeedPacketList from './SeedPacketList'; import Steps from './Steps'; import WhenPicker from './WhenPicker'; const STEPS = ['Which seeds', 'Where and when', 'Notes']; const SOURCES = [['mine', 'From my seeds'], ['new', 'New seeds'], ['seedlings', 'Seedlings I got']]; // A row of radio pills, the same look as the "when" choice. function Choices({id, legend, choices, value, onChange}) { return (
{legend}
{choices.map(([choice, label]) => ( onChange(choice)} /> ))}
); } // "Sow seeds", in steps: which seeds (a packet of your own, new seeds, or // seedlings you were given), then where and when, then any notes. Choosing the // seeds goes straight on to the next step. Sowing from a packet takes the seeds // out of it. export default function SowSeedsModal({nursery, gardens, seeds, onClose, onSown}) { const [step, setStep] = useState(1); const [source, setSource] = useState(seeds.length > 0 ? 'mine' : 'new'); const [search, setSearch] = useState(''); const [seed, setSeed] = useState(null); const [crop, setCrop] = useState(null); const [when, setWhen] = useState('today'); const [customDate, setCustomDate] = useState(''); const [where, setWhere] = useState('nursery'); const [gardenId, setGardenId] = useState(gardens.length > 0 ? String(gardens[0].id) : ''); const [quantity, setQuantity] = useState(6); const [note, setNote] = useState(''); const [saving, setSaving] = useState(false); const [errors, setErrors] = useState([]); const [sown, setSown] = useState(null); const [placing, setPlacing] = useState(null); // sown straight into a garden: offer to place it on the layout const today = localToday(); const sownOn = {today, yesterday: daysBefore(today, 1), other: customDate}[when]; const garden = where === 'nursery' ? nursery : gardens.find((g) => String(g.id) === gardenId); const cropId = source === 'mine' ? seed && seed.crop_id : crop && crop.id; const cropName = source === 'mine' ? seed && seed.name : crop && crop.name; const target = where === 'nursery' ? 'the nursery' : (garden ? garden.name : 'a garden'); const quantityLabel = source === 'seedlings' ? 'How many seedlings?' : 'How many seeds?'; const detailsReady = Boolean(garden) && quantity > 0 && Boolean(sownOn) && sownOn <= today; function chooseSource(choice) { setSource(choice); setSeed(null); setCrop(null); } function chooseSeed(packet) { setSeed(packet); setStep(2); } function chooseCrop(chosen) { setCrop(chosen); setStep(2); } // Back to choosing the seeds, for the next sowing. function startAgain() { setSeed(null); setCrop(null); setNote(''); setStep(1); } async function save(addAnother) { setSaving(true); setErrors([]); try { const planting = { garden_id: garden.id, crop_id: cropId, quantity, planted_from: source === 'seedlings' ? 'seedling' : 'seed', ...(source === 'mine' ? {parent_seed_id: seed.id} : {}), planted_at: sownOn, ...(note.trim() ? {description: note.trim()} : {}), }; const {ok, status, data} = await postJson('/plantings.json', {planting, ...(source === 'mine' ? {use_seeds: 1} : {})}); if (!ok) { setErrors(errorMessages(status, data, {forbidden: 'You can\'t sow into that garden.', signedOut: 'Please sign in again to sow seeds.'})); } else if (addAnother) { setSown(`Sowed ${quantity} ${cropName}.`); startAgain(); } else if (where === 'garden') { setPlacing({quantity, name: cropName, garden, saved: data}); } else { await onSown(data); // keeps saying so until the page shows it return; } } catch (error) { setErrors(['Couldn\'t reach the server. Please try again.']); } setSaving(false); } // What was chosen, as a packet or a crop, with a way back to change it. const chosen = () => ( <> {source === 'mine' ? : } ); if (placing) { return ( onSown(placing.saved)}>
Sowed {placing.quantity} {placing.name} into {placing.garden.name}.

Where in the garden did you put them?

Add it to the garden layout to remember where it is. You can do this later from the garden.

Place on the garden layout{' '}
); } return (
{errors.length > 0 && (
That didn’t work.
    {errors.map((message) =>
  • {message}
  • )}
)} {sown &&
{sown} Sow another below.
} {step === 1 && ( <>
{source === 'mine' ? ( ) : ( )}
)} {step === 2 && (
{ setWhen(choice); if (choice === 'other' && !customDate) setCustomDate(today); }} date={customDate} onDate={(event) => setCustomDate(event.target.value)} hint={sownOn > today ? 'Seeds can only be sown up to today.' : sownOn} />

{where === 'nursery' ? 'They stay in the nursery as seedlings until you transplant them.' : 'They go in as a planting, with no nursery stage.'}

{where === 'garden' && ( gardens.length > 0 ? ( <> ) :

You don’t have another garden yet.

)} setQuantity(Math.max(0, parseInt(event.target.value, 10) || 0))} /> {source === 'mine' && seed.quantity != null && (

That packet goes from {seed.quantity} to {Math.max(0, seed.quantity - quantity)}.

)}
{chosen()}
)} {step === 3 && ( <>

Sowing {quantity} {cropName} into {target}{sownOn === today ? ' today' : ` on ${sownOn}`}.