Collapse request discovery after selecting a title
Magent CI/CD / verify (push) Successful in 11m0s
Magent CI/CD / deploy-prod (push) Skipped
Magent CI/CD / deploy-beta (push) Successful in 1m11s

This commit is contained in:
2026-09-10 15:47:50 +12:00
parent df651eb312
commit 9856c7fb90
+26 -12
View File
@@ -124,6 +124,21 @@ export default function NewRequestClient() {
if (!getToken()) router.push('/login') if (!getToken()) router.push('/login')
}, [router]) }, [router])
const selectedTitleId = selected?.tmdbId
useEffect(() => {
if (selectedTitleId) configureSectionRef.current?.focus()
}, [selectedTitleId])
const changeTitle = () => {
setSelected(null)
setOptions(null)
setSelectedSeasons([])
setOperation(null)
setError(null)
setSuccess(null)
window.requestAnimationFrame(() => document.getElementById('request-title-search')?.focus())
}
const resetAfterType = (nextType: MediaType) => { const resetAfterType = (nextType: MediaType) => {
setMediaType(nextType) setMediaType(nextType)
setQuery('') setQuery('')
@@ -197,7 +212,6 @@ export default function NewRequestClient() {
setError(null) setError(null)
setSuccess(null) setSuccess(null)
if (item.requestId) { if (item.requestId) {
window.setTimeout(() => configureSectionRef.current?.scrollIntoView({ behavior: 'smooth', block: 'start' }), 80)
return return
} }
@@ -236,7 +250,6 @@ export default function NewRequestClient() {
setError(caught instanceof Error ? caught.message : 'Could not load request options.') setError(caught instanceof Error ? caught.message : 'Could not load request options.')
} finally { } finally {
setLoadingOptions(false) setLoadingOptions(false)
window.setTimeout(() => configureSectionRef.current?.scrollIntoView({ behavior: 'smooth', block: 'start' }), 80)
} }
} }
@@ -332,7 +345,7 @@ export default function NewRequestClient() {
{error && <div className="error-banner request-flow-alert">{error}</div>} {error && <div className="error-banner request-flow-alert">{error}</div>}
{success && <div className="status-banner request-flow-alert">{success}</div>} {success && <div className="status-banner request-flow-alert">{success}</div>}
<section className="request-flow-stage is-current"> {!selected && <section className="request-flow-stage is-current">
<div className="request-flow-heading"> <div className="request-flow-heading">
<span className="request-flow-number">01</span> <span className="request-flow-number">01</span>
<div><span>Start here</span><h2>What are you looking for?</h2></div> <div><span>Start here</span><h2>What are you looking for?</h2></div>
@@ -360,9 +373,9 @@ export default function NewRequestClient() {
</button> </button>
))} ))}
</div> </div>
</section> </section>}
{mediaType && ( {mediaType && !selected && (
<section ref={searchSectionRef} className="request-flow-stage is-current"> <section ref={searchSectionRef} className="request-flow-stage is-current">
<div className="request-flow-heading"> <div className="request-flow-heading">
<span className="request-flow-number">02</span> <span className="request-flow-number">02</span>
@@ -384,7 +397,7 @@ export default function NewRequestClient() {
</section> </section>
)} )}
{mediaType && searchAttempted && !searching && ( {mediaType && !selected && searchAttempted && !searching && (
<section ref={resultsSectionRef} className="request-flow-stage is-current"> <section ref={resultsSectionRef} className="request-flow-stage is-current">
<div className="request-flow-heading"> <div className="request-flow-heading">
<span className="request-flow-number">03</span> <span className="request-flow-number">03</span>
@@ -399,12 +412,11 @@ export default function NewRequestClient() {
<div className="request-result-grid"> <div className="request-result-grid">
{results.map((item) => { {results.map((item) => {
const poster = artworkUrl(item.posterPath) const poster = artworkUrl(item.posterPath)
const isSelected = selected?.tmdbId === item.tmdbId && selected.type === item.type
return ( return (
<button <button
key={`${item.type}:${item.tmdbId}`} key={`${item.type}:${item.tmdbId}`}
type="button" type="button"
className={`request-result-card ${isSelected ? 'is-selected' : ''}`} className="request-result-card"
onClick={() => void selectResult(item)} onClick={() => void selectResult(item)}
> >
<span className="request-result-poster"> <span className="request-result-poster">
@@ -414,7 +426,7 @@ export default function NewRequestClient() {
<small>{item.type === 'tv' ? 'TV show' : 'Movie'}{item.year ? ` · ${item.year}` : ''}</small> <small>{item.type === 'tv' ? 'TV show' : 'Movie'}{item.year ? ` · ${item.year}` : ''}</small>
<strong>{item.title}</strong> <strong>{item.title}</strong>
<p>{item.overview || 'Select this title to view the available request options.'}</p> <p>{item.overview || 'Select this title to view the available request options.'}</p>
<b>{item.requestId ? item.statusLabel || 'Already requested' : isSelected ? 'Selected' : 'Select title'}</b> <b>{item.requestId ? item.statusLabel || 'Already requested' : 'Select title'}</b>
</span> </span>
</button> </button>
) )
@@ -425,12 +437,14 @@ export default function NewRequestClient() {
)} )}
{selected && ( {selected && (
<section ref={configureSectionRef} className="request-flow-stage is-current request-configure-stage"> <section ref={configureSectionRef} tabIndex={-1} aria-labelledby="request-configure-title" className="request-flow-stage is-current request-configure-stage">
<div className="request-flow-heading"> <div className="request-flow-heading">
<span className="request-flow-number">04</span> <span className="request-flow-number">04</span>
<div><span>Final step</span><h2>{selected.requestId ? 'This title is already in the pipeline' : 'Configure your request'}</h2></div> <div><span>Final step</span><h2 id="request-configure-title">{selected.requestId ? 'This title is already in the pipeline' : selected.type === 'tv' ? 'Choose seasons and request' : 'Review and request'}</h2></div>
</div> </div>
<button type="button" className="ghost-button" onClick={changeTitle} disabled={loadingOptions || submitting}>Change title</button>
<div className="request-selection-summary"> <div className="request-selection-summary">
<span className="request-selection-poster"> <span className="request-selection-poster">
{selectedPoster ? <img src={selectedPoster} alt="" /> : <i>No artwork</i>} {selectedPoster ? <img src={selectedPoster} alt="" /> : <i>No artwork</i>}
@@ -448,7 +462,7 @@ export default function NewRequestClient() {
<button type="button" onClick={() => router.push(`/requests/${selected.requestId}`)}>Open request</button> <button type="button" onClick={() => router.push(`/requests/${selected.requestId}`)}>Open request</button>
</div> </div>
) : loadingOptions ? ( ) : loadingOptions ? (
<div className="request-flow-empty"><strong>Checking Seerr and {selected.type === 'tv' ? 'Sonarr' : 'Radarr'}</strong><p>Loading valid profiles and request choices.</p></div> <div className="request-flow-empty"><strong>Checking Seerr and {selected.type === 'tv' ? 'Sonarr' : 'Radarr'}</strong><p>Preparing your request options.</p></div>
) : options ? ( ) : options ? (
<div className="request-options-layout"> <div className="request-options-layout">
{selected.type === 'tv' && ( {selected.type === 'tv' && (