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:
root
2026-03-31 08:45:02 -05:00
parent 47ab3dd847
commit 240032d972
8 changed files with 93 additions and 21 deletions

View File

@@ -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>

View File

@@ -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">