// ContributeRequestForm.jsx — roadmap #28 Part 3. // // The "ask to contribute" popover, opened from an `rfc-pending` affordance // in LinkedText (App reads `?contribute=&term=`). It loads the // contribution target (RFC title + owner display + the viewer's // eligibility), shows the framing line " is working on an RFC for // ''", and collects the three #15/#26-vocabulary fields: // // * Who I am (required, free-text) // * Why I'm asking (required, free-text) // * What I'd use it for (optional, mirrors #26) // // Submitting POSTs the request, which lands in each owner's §15 inbox. // When the viewer isn't eligible (anonymous, already a collaborator, or // has a pending ask) the form shows the backend's reason instead. import { useEffect, useState } from 'react' import { contributionTarget, requestContribution } from '../api' export default function ContributeRequestForm({ slug, term, onClose }) { const [target, setTarget] = useState(null) const [loadError, setLoadError] = useState(null) const [whoIAm, setWhoIAm] = useState('') const [why, setWhy] = useState('') const [useCase, setUseCase] = useState('') const [submitting, setSubmitting] = useState(false) const [error, setError] = useState(null) const [done, setDone] = useState(false) useEffect(() => { let live = true contributionTarget(slug) .then(t => { if (live) setTarget(t) }) .catch(err => { if (live) setLoadError(err.message || 'Could not load this RFC.') }) return () => { live = false } }, [slug]) async function handleSubmit(e) { e.preventDefault() if (!whoIAm.trim() || !why.trim()) return setSubmitting(true) setError(null) try { await requestContribution(slug, { matchedTerm: term || target?.title || slug, whoIAm: whoIAm.trim(), why: why.trim(), useCase: useCase.trim() || null, }) setDone(true) } catch (err) { setError(err.message || 'Could not send your request.') } finally { setSubmitting(false) } } const owner = target?.owner || 'The owner' const label = term || target?.title || slug return (
{ if (e.target === e.currentTarget) onClose() }}>

Ask to contribute

{loadError && (

{loadError}

)} {!loadError && done && ( <>

Your request has been sent to {owner}. You'll hear back in your inbox; if it's accepted you'll get an invitation by email to join the RFC.

)} {!loadError && !done && target && !target.eligible && ( <>

{owner} is working on an RFC for '{label}'.

{target.already_requested ? "You've already asked to contribute to this RFC — the owner has your request." : (target.reason || 'You cannot ask to contribute to this RFC right now.')}

)} {!loadError && !done && target && target.eligible && (

{owner} is working on an RFC for '{label}'. Tell them a little about why you'd like to contribute.