1
0
Files
record-shop/web/src/scan/ConfirmView.tsx

101 lines
3.5 KiB
TypeScript

import type { ReleasePreview } from '../types.js'
import Cover from '../components/Cover.js'
export default function ConfirmView({
code,
preview,
matchAlbumId,
onSetMatch,
onClearMatch,
onAdd,
adding,
addError,
}: {
code: string | null
preview: ReleasePreview
matchAlbumId: number | null
onSetMatch: (albumId: number) => void
onClearMatch: () => void
onAdd: () => void
adding: boolean
addError: string | null
}) {
const { release, duplicate, ripMatch, matchCandidates } = preview
return (
<div className="space-y-4">
<div className="flex gap-4">
<Cover src={release.coverUrl ?? release.thumbUrl} alt="" className="size-28 shrink-0" />
<div className="min-w-0">
<h2 className="text-lg font-semibold leading-tight">{release.title}</h2>
<p className="text-neutral-400">{release.artist}</p>
<p className="text-xs text-neutral-500">
{[release.year, release.formats.join(', '), release.labels[0], release.catno]
.filter(Boolean)
.join(' · ')}
</p>
{code && <p className="mt-1 text-xs text-neutral-500">Barcode {code}</p>}
</div>
</div>
{ripMatch === 'ripped' && (
<p className="rounded-xl bg-emerald-500/10 px-4 py-3 text-sm text-emerald-400">
In your digital collection
</p>
)}
{ripMatch === 'not_ripped' && (
<p className="rounded-xl bg-amber-500/10 px-4 py-3 text-sm text-amber-400">Not ripped yet</p>
)}
{ripMatch === 'ambiguous' && (
<fieldset className="rounded-xl bg-amber-500/10 px-4 py-3 text-sm text-amber-400">
<legend className="px-1">Possible matches in your library which one is it?</legend>
<div className="mt-1 space-y-2">
{matchCandidates.map((m) => (
<label key={m.id} className="flex items-center gap-2 text-neutral-200">
<input
type="radio"
name="match"
checked={matchAlbumId === m.id}
onChange={() => onSetMatch(m.id)}
/>
{m.artist} {m.title}
</label>
))}
<label className="flex items-center gap-2 text-neutral-200">
<input type="radio" name="match" checked={matchAlbumId === null} onChange={onClearMatch} />
None of these just add it
</label>
</div>
</fieldset>
)}
{duplicate && (
<p className="rounded-xl bg-red-500/10 px-4 py-3 text-sm text-red-400">
Heads up: this release is already in your collection.
</p>
)}
<details className="rounded-xl border border-neutral-800 bg-neutral-900 p-3">
<summary className="cursor-pointer text-sm text-neutral-300">Tracklist</summary>
<ol className="mt-2 space-y-1 text-sm text-neutral-400">
{release.tracklist.map((t, i) => (
<li key={i} className="flex gap-2">
<span className="w-8 shrink-0 text-neutral-600">{t.position}</span>
<span>{t.title}</span>
</li>
))}
</ol>
</details>
{addError && <p className="text-sm text-red-400">{addError}</p>}
<button
type="button"
onClick={onAdd}
disabled={adding}
className="w-full rounded-xl bg-emerald-500 py-3 font-medium text-neutral-950 disabled:opacity-50"
>
{adding ? 'Adding…' : 'Add to collection'}
</button>
</div>
)
}