Add Bandcamp/YouTube links on all recs, Fix My Playlist, configurable rec count
- Bandcamp: match artist+song, fall back to artist-only page - YouTube fallback: if not on Bandcamp, link to YouTube music video search - Fix My Playlist: AI analyzes playlist, finds outliers, suggests replacements - User chooses recommendation count (5, 10, 15, 20)
This commit is contained in:
@@ -80,7 +80,7 @@ export default function RecommendationCard({ recommendation, onToggleSave, onDis
|
||||
</button>
|
||||
)}
|
||||
|
||||
{recommendation.bandcamp_url && (
|
||||
{recommendation.bandcamp_url ? (
|
||||
<a
|
||||
href={recommendation.bandcamp_url}
|
||||
target="_blank"
|
||||
@@ -90,7 +90,17 @@ export default function RecommendationCard({ recommendation, onToggleSave, onDis
|
||||
>
|
||||
<ExternalLink className="w-4 h-4" />
|
||||
</a>
|
||||
)}
|
||||
) : recommendation.youtube_url ? (
|
||||
<a
|
||||
href={recommendation.youtube_url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="p-2 rounded-full bg-red-50 text-red-600 hover:bg-red-100 transition-colors"
|
||||
title="Watch on YouTube"
|
||||
>
|
||||
<ExternalLink className="w-4 h-4" />
|
||||
</a>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -38,6 +38,7 @@ export default function Discover() {
|
||||
const [mode, setMode] = useState('discover')
|
||||
const [adventurousness, setAdventurousness] = useState(3)
|
||||
const [excludeGenres, setExcludeGenres] = useState('')
|
||||
const [count, setCount] = useState(5)
|
||||
|
||||
useEffect(() => {
|
||||
const load = async () => {
|
||||
@@ -71,6 +72,7 @@ export default function Discover() {
|
||||
mode,
|
||||
adventurousness,
|
||||
excludeGenres.trim() || undefined,
|
||||
count,
|
||||
)
|
||||
setResults(response.recommendations)
|
||||
setRemaining(response.remaining_this_week)
|
||||
@@ -221,6 +223,28 @@ export default function Discover() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Recommendation Count */}
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-charcoal mb-3">
|
||||
How many recommendations
|
||||
</label>
|
||||
<div className="flex gap-2">
|
||||
{[5, 10, 15, 20].map((n) => (
|
||||
<button
|
||||
key={n}
|
||||
onClick={() => setCount(n)}
|
||||
className={`px-4 py-2 rounded-full text-sm font-medium transition-all cursor-pointer border ${
|
||||
count === n
|
||||
? 'bg-purple text-white border-purple shadow-md shadow-purple/20'
|
||||
: 'bg-white text-charcoal-muted border-purple-100 hover:border-purple/30 hover:text-charcoal'
|
||||
}`}
|
||||
>
|
||||
{n}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Block Genres */}
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-charcoal mb-2">
|
||||
|
||||
Reference in New Issue
Block a user