All files / Bandstand/src/components NewSongForm.tsx

0% Statements 0/67
100% Branches 1/1
100% Functions 1/1
0% Lines 0/67

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79                                                                                                                                                             
'use client'
 
import Link from 'next/link'
import {useRouter} from 'next/navigation'
import {useState} from 'react'
 
export default function NewSongForm() {
  const router = useRouter()
  const [title, setTitle] = useState('')
  const [writer, setWriter] = useState('')
  const [leadSinger, setLeadSinger] = useState('')
  const [busy, setBusy] = useState(false)
  const [error, setError] = useState<string | null>(null)
 
  async function create(e: React.FormEvent) {
    e.preventDefault()
    setBusy(true)
    setError(null)
    const r = await fetch('/api/songs', {
      method: 'POST',
      headers: {'Content-Type': 'application/json'},
      body: JSON.stringify({title, writer, leadSinger}),
    })
    if (!r.ok) {
      setError('Could not add the song.')
      setBusy(false)
      return
    }
    const {id} = await r.json()
    router.push(`/songs/${id}/edit`)
  }
 
  return (
    <main className="mx-auto max-w-xl px-4 pt-5">
      <Link
        href="/songs"
        className="text-sm text-muted no-underline hover:text-text"
      >
        ‹ All songs
      </Link>
      <h1 className="mt-1 text-3xl font-extrabold">Add a song</h1>
      <form onSubmit={create} className="mt-5 flex flex-col gap-4">
        {(
          [
            ['Title', title, setTitle, true],
            ['Written by', writer, setWriter, false],
            ['Lead singer', leadSinger, setLeadSinger, false],
          ] as const
        ).map(([label, value, set, required]) => (
          <label key={label} className="flex flex-col gap-1 text-sm text-muted">
            {label}
            <input
              value={value}
              required={required}
              onChange={(e) => set(e.target.value)}
              className="min-h-11 rounded-lg border border-line-2 bg-panel px-3 text-base text-text"
            />
          </label>
        ))}
        <p className="text-sm text-muted">
          You can paste the chart on the next screen.
        </p>
        <button
          type="submit"
          disabled={busy || !title.trim()}
          className="min-h-12 rounded-lg bg-accent font-bold text-on-accent disabled:opacity-40"
        >
          {busy ? 'Adding…' : 'Add and write the chart'}
        </button>
        {error && (
          <p role="alert" className="text-bad">
            {error}
          </p>
        )}
      </form>
    </main>
  )
}