2026-03-09 00:52:56 +00:00
|
|
|
/**
|
|
|
|
|
* Discover Page - v0.10.1 F351-F355
|
|
|
|
|
* Browse tracks by genre or tag
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
import { useCallback, useEffect, useRef } from 'react';
|
feat: frontend pages and feature modules polish
Update dashboard (stats, recent tracks/activity), discover, distribution,
education, feed, subscription, support, search, settings, live, cloud,
analytics, auth, chat, social, tracks, playlists, presence, upload,
and library manager. Consistent UI patterns and error handling.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 14:46:21 +00:00
|
|
|
import { useSearchParams, useNavigate } from 'react-router-dom';
|
2026-03-09 00:52:56 +00:00
|
|
|
import { useInfiniteQuery, useQuery } from '@tanstack/react-query';
|
feat: frontend pages and feature modules polish
Update dashboard (stats, recent tracks/activity), discover, distribution,
education, feed, subscription, support, search, settings, live, cloud,
analytics, auth, chat, social, tracks, playlists, presence, upload,
and library manager. Consistent UI patterns and error handling.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 14:46:21 +00:00
|
|
|
import { usePlayerStore } from '@/features/player/store/playerStore';
|
feat(web): update all features, stories, e2e tests, and auth interceptor
Update auth, playlists, tracks, search, profile, dashboard, player,
settings, and social features. Add e2e audit specs for all major pages.
Update ESLint config, vitest config, and route configuration.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 17:16:36 +00:00
|
|
|
import { useTranslation } from '@/hooks/useTranslation';
|
2026-03-09 00:52:56 +00:00
|
|
|
import { ContentFadeIn } from '@/components/ui/ContentFadeIn';
|
|
|
|
|
import { TrackGrid } from '@/features/tracks/components/TrackGrid';
|
|
|
|
|
import { TrackCardSkeleton } from '@/features/tracks/components/TrackCardSkeleton';
|
|
|
|
|
import { ErrorDisplay } from '@/components/ui/ErrorDisplay';
|
|
|
|
|
import { discoverService, type Genre } from '@/services/discoverService';
|
2026-03-09 15:49:05 +00:00
|
|
|
import { PlaylistCard } from '@/features/playlists/components/PlaylistCard';
|
|
|
|
|
import { PlaylistCardSkeleton } from '@/features/playlists/components/PlaylistCardSkeleton';
|
feat: frontend improvements — UI polish, player bar, auth flow, i18n
- Header, Sidebar, Toast, Dropdown, EmptyState component refinements
- Auth flow: LoginPage, RegisterPage, AuthInput, AuthLayout improvements
- Player bar: glass effect, progress, track info, controls enhancements
- Dashboard, Discover, Search pages updates
- PlaylistCard, TrackCard component improvements
- Auth store and API interceptors hardening
- i18n: updated en/es/fr locale files
- CSS additions in index.css
- Package.json and vite config updates
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 10:35:44 +00:00
|
|
|
import { Music2, Loader2, ChevronLeft, Compass } from 'lucide-react';
|
2026-03-09 00:52:56 +00:00
|
|
|
import { Button } from '@/components/ui/button';
|
feat: frontend improvements — UI polish, player bar, auth flow, i18n
- Header, Sidebar, Toast, Dropdown, EmptyState component refinements
- Auth flow: LoginPage, RegisterPage, AuthInput, AuthLayout improvements
- Player bar: glass effect, progress, track info, controls enhancements
- Dashboard, Discover, Search pages updates
- PlaylistCard, TrackCard component improvements
- Auth store and API interceptors hardening
- i18n: updated en/es/fr locale files
- CSS additions in index.css
- Package.json and vite config updates
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 10:35:44 +00:00
|
|
|
import { cn } from '@/lib/utils';
|
|
|
|
|
|
feat: frontend pages and feature modules polish
Update dashboard (stats, recent tracks/activity), discover, distribution,
education, feed, subscription, support, search, settings, live, cloud,
analytics, auth, chat, social, tracks, playlists, presence, upload,
and library manager. Consistent UI patterns and error handling.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 14:46:21 +00:00
|
|
|
// Spotify-style genre gradient colors — rich, two-tone gradients
|
feat: frontend improvements — UI polish, player bar, auth flow, i18n
- Header, Sidebar, Toast, Dropdown, EmptyState component refinements
- Auth flow: LoginPage, RegisterPage, AuthInput, AuthLayout improvements
- Player bar: glass effect, progress, track info, controls enhancements
- Dashboard, Discover, Search pages updates
- PlaylistCard, TrackCard component improvements
- Auth store and API interceptors hardening
- i18n: updated en/es/fr locale files
- CSS additions in index.css
- Package.json and vite config updates
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 10:35:44 +00:00
|
|
|
const GENRE_GRADIENTS = [
|
feat: frontend pages and feature modules polish
Update dashboard (stats, recent tracks/activity), discover, distribution,
education, feed, subscription, support, search, settings, live, cloud,
analytics, auth, chat, social, tracks, playlists, presence, upload,
and library manager. Consistent UI patterns and error handling.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 14:46:21 +00:00
|
|
|
'from-[#e13300] to-[#ff6b3d]',
|
|
|
|
|
'from-[#8400e7] to-[#b44dff]',
|
|
|
|
|
'from-[#1e3264] to-[#3d5a9e]',
|
|
|
|
|
'from-[#e8115b] to-[#ff4d8d]',
|
|
|
|
|
'from-[#148a08] to-[#2cc41a]',
|
|
|
|
|
'from-[#e91429] to-[#ff5c6e]',
|
|
|
|
|
'from-[#477d95] to-[#6ab0cc]',
|
|
|
|
|
'from-[#8c67ab] to-[#b896d6]',
|
|
|
|
|
'from-[#ba5d07] to-[#e89234]',
|
|
|
|
|
'from-[#1e3264] to-[#608108]',
|
|
|
|
|
'from-[#dc148c] to-[#ff4db8]',
|
|
|
|
|
'from-[#186962] to-[#2aaa9e]',
|
|
|
|
|
'from-[#7358ff] to-[#a18dff]',
|
|
|
|
|
'from-[#c84040] to-[#e87070]',
|
|
|
|
|
'from-[#0d73ec] to-[#4da3ff]',
|
feat: frontend improvements — UI polish, player bar, auth flow, i18n
- Header, Sidebar, Toast, Dropdown, EmptyState component refinements
- Auth flow: LoginPage, RegisterPage, AuthInput, AuthLayout improvements
- Player bar: glass effect, progress, track info, controls enhancements
- Dashboard, Discover, Search pages updates
- PlaylistCard, TrackCard component improvements
- Auth store and API interceptors hardening
- i18n: updated en/es/fr locale files
- CSS additions in index.css
- Package.json and vite config updates
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 10:35:44 +00:00
|
|
|
];
|
2026-03-09 00:52:56 +00:00
|
|
|
|
|
|
|
|
export function DiscoverPage() {
|
|
|
|
|
const [searchParams, setSearchParams] = useSearchParams();
|
|
|
|
|
const genreFromQuery = searchParams.get('genre');
|
|
|
|
|
const tagFromQuery = searchParams.get('tag');
|
feat: frontend pages and feature modules polish
Update dashboard (stats, recent tracks/activity), discover, distribution,
education, feed, subscription, support, search, settings, live, cloud,
analytics, auth, chat, social, tracks, playlists, presence, upload,
and library manager. Consistent UI patterns and error handling.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 14:46:21 +00:00
|
|
|
const play = usePlayerStore((s) => s.play);
|
|
|
|
|
const navigate = useNavigate();
|
2026-03-09 00:52:56 +00:00
|
|
|
const loadMoreRef = useRef<HTMLDivElement>(null);
|
feat(web): update all features, stories, e2e tests, and auth interceptor
Update auth, playlists, tracks, search, profile, dashboard, player,
settings, and social features. Add e2e audit specs for all major pages.
Update ESLint config, vitest config, and route configuration.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 17:16:36 +00:00
|
|
|
const { t } = useTranslation();
|
2026-03-09 00:52:56 +00:00
|
|
|
|
|
|
|
|
const browseGenre = genreFromQuery;
|
|
|
|
|
const browseTag = tagFromQuery;
|
|
|
|
|
|
|
|
|
|
const { data: genres, isLoading: genresLoading } = useQuery({
|
|
|
|
|
queryKey: ['discoverGenres'],
|
|
|
|
|
queryFn: () => discoverService.getGenres(),
|
|
|
|
|
});
|
|
|
|
|
|
2026-03-09 15:49:05 +00:00
|
|
|
const { data: editorialData, isLoading: editorialLoading } = useQuery({
|
|
|
|
|
queryKey: ['discoverEditorialPlaylists'],
|
|
|
|
|
queryFn: () => discoverService.getEditorialPlaylists({ limit: 20 }),
|
|
|
|
|
});
|
|
|
|
|
|
2026-03-09 00:52:56 +00:00
|
|
|
const {
|
|
|
|
|
data: genreTracksData,
|
|
|
|
|
fetchNextPage: fetchNextGenre,
|
|
|
|
|
hasNextPage: hasNextGenre,
|
|
|
|
|
isFetchingNextPage: isFetchingGenre,
|
|
|
|
|
isLoading: genreTracksLoading,
|
|
|
|
|
error: genreTracksError,
|
|
|
|
|
refetch: refetchGenre,
|
|
|
|
|
} = useInfiniteQuery({
|
|
|
|
|
queryKey: ['discoverGenre', browseGenre],
|
refactor(web): zero out 3 ESLint warning buckets (storybook + react-refresh + non-null-assertion)
Three rules cleaned in parallel passes — 187 fewer warnings, 0 TS
errors, 0 behaviour change beyond one incidental auth bugfix
flagged below.
storybook/no-redundant-story-name (23 → 0) — 14 stories files
Storybook v7+ infers the story name from the variable name, so
`name: 'Default'` next to `export const Default: Story = …` is
pure noise. Removed only when the name was redundant ;
preserved when the label was a French translation
('Par défaut', 'Chargement', 'Avec erreur', etc.) since those
are intentional.
react-refresh/only-export-components (25 → 0) — 21 files
Each warning marks a file that exports a React component AND a
hook / context / constant / barrel re-export. Suppressed
per-line with the suppression-with-justification pattern :
// eslint-disable-next-line react-refresh/only-export-components -- <kind>; refactor would split a tightly-coupled API
The justification matters — every comment names the specific
thing being co-located (hook / context / CVA constant / lazy
registry / route config / test util / backward-compat barrel).
Splitting these would create 21 new files for a HMR-only DX
win that's already a non-issue in practice.
@typescript-eslint/no-non-null-assertion (139 → 0) — 43 files
Distribution of fixes :
~85 cases : refactored to explicit guard
`if (!x) throw new Error('invariant: …')`
or hoisted into local with narrowing.
~36 cases : helper extraction (one tooltip test had 16
`wrapper!` patterns reduced to a single
`getWrapper()` helper).
~18 cases : suppressed with specific reason :
static literal arrays where index is provably
in bounds, mock fixtures with structural
guarantees, filter-then-map patterns where the
filter excludes the null branch.
One incidental find : services/api/auth.ts threw on missing
tokens but didn't guard `user` ; added the missing check while
refactoring the `user!` to a guard.
baseline post-commit : 921 warnings, 0 errors, 0 TS errors.
The remaining buckets are no-restricted-syntax (757, design-system
guardrail), no-explicit-any (115), exhaustive-deps (49).
CI --max-warnings will be lowered to 921 in the follow-up commit.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 21:30:22 +00:00
|
|
|
queryFn: ({ pageParam }) => {
|
|
|
|
|
if (!browseGenre) throw new Error('browseGenre required');
|
|
|
|
|
return discoverService.getTracksByGenre(browseGenre, {
|
2026-03-09 00:52:56 +00:00
|
|
|
cursor: pageParam,
|
|
|
|
|
limit: 20,
|
refactor(web): zero out 3 ESLint warning buckets (storybook + react-refresh + non-null-assertion)
Three rules cleaned in parallel passes — 187 fewer warnings, 0 TS
errors, 0 behaviour change beyond one incidental auth bugfix
flagged below.
storybook/no-redundant-story-name (23 → 0) — 14 stories files
Storybook v7+ infers the story name from the variable name, so
`name: 'Default'` next to `export const Default: Story = …` is
pure noise. Removed only when the name was redundant ;
preserved when the label was a French translation
('Par défaut', 'Chargement', 'Avec erreur', etc.) since those
are intentional.
react-refresh/only-export-components (25 → 0) — 21 files
Each warning marks a file that exports a React component AND a
hook / context / constant / barrel re-export. Suppressed
per-line with the suppression-with-justification pattern :
// eslint-disable-next-line react-refresh/only-export-components -- <kind>; refactor would split a tightly-coupled API
The justification matters — every comment names the specific
thing being co-located (hook / context / CVA constant / lazy
registry / route config / test util / backward-compat barrel).
Splitting these would create 21 new files for a HMR-only DX
win that's already a non-issue in practice.
@typescript-eslint/no-non-null-assertion (139 → 0) — 43 files
Distribution of fixes :
~85 cases : refactored to explicit guard
`if (!x) throw new Error('invariant: …')`
or hoisted into local with narrowing.
~36 cases : helper extraction (one tooltip test had 16
`wrapper!` patterns reduced to a single
`getWrapper()` helper).
~18 cases : suppressed with specific reason :
static literal arrays where index is provably
in bounds, mock fixtures with structural
guarantees, filter-then-map patterns where the
filter excludes the null branch.
One incidental find : services/api/auth.ts threw on missing
tokens but didn't guard `user` ; added the missing check while
refactoring the `user!` to a guard.
baseline post-commit : 921 warnings, 0 errors, 0 TS errors.
The remaining buckets are no-restricted-syntax (757, design-system
guardrail), no-explicit-any (115), exhaustive-deps (49).
CI --max-warnings will be lowered to 921 in the follow-up commit.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 21:30:22 +00:00
|
|
|
});
|
|
|
|
|
},
|
2026-03-09 00:52:56 +00:00
|
|
|
getNextPageParam: (last) => last.next_cursor ?? undefined,
|
|
|
|
|
initialPageParam: undefined as string | undefined,
|
|
|
|
|
enabled: !!browseGenre,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const {
|
|
|
|
|
data: tagTracksData,
|
|
|
|
|
fetchNextPage: fetchNextTag,
|
|
|
|
|
hasNextPage: hasNextTag,
|
|
|
|
|
isFetchingNextPage: isFetchingTag,
|
|
|
|
|
isLoading: tagTracksLoading,
|
|
|
|
|
error: tagTracksError,
|
|
|
|
|
refetch: refetchTag,
|
|
|
|
|
} = useInfiniteQuery({
|
|
|
|
|
queryKey: ['discoverTag', browseTag],
|
refactor(web): zero out 3 ESLint warning buckets (storybook + react-refresh + non-null-assertion)
Three rules cleaned in parallel passes — 187 fewer warnings, 0 TS
errors, 0 behaviour change beyond one incidental auth bugfix
flagged below.
storybook/no-redundant-story-name (23 → 0) — 14 stories files
Storybook v7+ infers the story name from the variable name, so
`name: 'Default'` next to `export const Default: Story = …` is
pure noise. Removed only when the name was redundant ;
preserved when the label was a French translation
('Par défaut', 'Chargement', 'Avec erreur', etc.) since those
are intentional.
react-refresh/only-export-components (25 → 0) — 21 files
Each warning marks a file that exports a React component AND a
hook / context / constant / barrel re-export. Suppressed
per-line with the suppression-with-justification pattern :
// eslint-disable-next-line react-refresh/only-export-components -- <kind>; refactor would split a tightly-coupled API
The justification matters — every comment names the specific
thing being co-located (hook / context / CVA constant / lazy
registry / route config / test util / backward-compat barrel).
Splitting these would create 21 new files for a HMR-only DX
win that's already a non-issue in practice.
@typescript-eslint/no-non-null-assertion (139 → 0) — 43 files
Distribution of fixes :
~85 cases : refactored to explicit guard
`if (!x) throw new Error('invariant: …')`
or hoisted into local with narrowing.
~36 cases : helper extraction (one tooltip test had 16
`wrapper!` patterns reduced to a single
`getWrapper()` helper).
~18 cases : suppressed with specific reason :
static literal arrays where index is provably
in bounds, mock fixtures with structural
guarantees, filter-then-map patterns where the
filter excludes the null branch.
One incidental find : services/api/auth.ts threw on missing
tokens but didn't guard `user` ; added the missing check while
refactoring the `user!` to a guard.
baseline post-commit : 921 warnings, 0 errors, 0 TS errors.
The remaining buckets are no-restricted-syntax (757, design-system
guardrail), no-explicit-any (115), exhaustive-deps (49).
CI --max-warnings will be lowered to 921 in the follow-up commit.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 21:30:22 +00:00
|
|
|
queryFn: ({ pageParam }) => {
|
|
|
|
|
if (!browseTag) throw new Error('browseTag required');
|
|
|
|
|
return discoverService.getTracksByTag(browseTag, {
|
2026-03-09 00:52:56 +00:00
|
|
|
cursor: pageParam,
|
|
|
|
|
limit: 20,
|
refactor(web): zero out 3 ESLint warning buckets (storybook + react-refresh + non-null-assertion)
Three rules cleaned in parallel passes — 187 fewer warnings, 0 TS
errors, 0 behaviour change beyond one incidental auth bugfix
flagged below.
storybook/no-redundant-story-name (23 → 0) — 14 stories files
Storybook v7+ infers the story name from the variable name, so
`name: 'Default'` next to `export const Default: Story = …` is
pure noise. Removed only when the name was redundant ;
preserved when the label was a French translation
('Par défaut', 'Chargement', 'Avec erreur', etc.) since those
are intentional.
react-refresh/only-export-components (25 → 0) — 21 files
Each warning marks a file that exports a React component AND a
hook / context / constant / barrel re-export. Suppressed
per-line with the suppression-with-justification pattern :
// eslint-disable-next-line react-refresh/only-export-components -- <kind>; refactor would split a tightly-coupled API
The justification matters — every comment names the specific
thing being co-located (hook / context / CVA constant / lazy
registry / route config / test util / backward-compat barrel).
Splitting these would create 21 new files for a HMR-only DX
win that's already a non-issue in practice.
@typescript-eslint/no-non-null-assertion (139 → 0) — 43 files
Distribution of fixes :
~85 cases : refactored to explicit guard
`if (!x) throw new Error('invariant: …')`
or hoisted into local with narrowing.
~36 cases : helper extraction (one tooltip test had 16
`wrapper!` patterns reduced to a single
`getWrapper()` helper).
~18 cases : suppressed with specific reason :
static literal arrays where index is provably
in bounds, mock fixtures with structural
guarantees, filter-then-map patterns where the
filter excludes the null branch.
One incidental find : services/api/auth.ts threw on missing
tokens but didn't guard `user` ; added the missing check while
refactoring the `user!` to a guard.
baseline post-commit : 921 warnings, 0 errors, 0 TS errors.
The remaining buckets are no-restricted-syntax (757, design-system
guardrail), no-explicit-any (115), exhaustive-deps (49).
CI --max-warnings will be lowered to 921 in the follow-up commit.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 21:30:22 +00:00
|
|
|
});
|
|
|
|
|
},
|
2026-03-09 00:52:56 +00:00
|
|
|
getNextPageParam: (last) => last.next_cursor ?? undefined,
|
|
|
|
|
initialPageParam: undefined as string | undefined,
|
|
|
|
|
enabled: !!browseTag,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const genreTracks = genreTracksData?.pages.flatMap((p) => p.items) ?? [];
|
|
|
|
|
const tagTracks = tagTracksData?.pages.flatMap((p) => p.items) ?? [];
|
|
|
|
|
const tracks = browseGenre ? genreTracks : browseTag ? tagTracks : [];
|
|
|
|
|
const isLoadingTracks = browseGenre ? genreTracksLoading : tagTracksLoading;
|
|
|
|
|
const error = browseGenre ? genreTracksError : tagTracksError;
|
|
|
|
|
const hasNext = browseGenre ? hasNextGenre : hasNextTag;
|
|
|
|
|
const isFetchingNext = browseGenre ? isFetchingGenre : isFetchingTag;
|
|
|
|
|
const fetchNext = browseGenre ? fetchNextGenre : fetchNextTag;
|
|
|
|
|
const refetch = browseGenre ? refetchGenre : refetchTag;
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (!hasNext || isFetchingNext) return;
|
|
|
|
|
const el = loadMoreRef.current;
|
|
|
|
|
if (!el) return;
|
|
|
|
|
const observer = new IntersectionObserver(
|
|
|
|
|
(entries) => {
|
|
|
|
|
if (entries[0]?.isIntersecting) fetchNext();
|
|
|
|
|
},
|
|
|
|
|
{ rootMargin: '200px', threshold: 0 }
|
|
|
|
|
);
|
|
|
|
|
observer.observe(el);
|
|
|
|
|
return () => observer.disconnect();
|
|
|
|
|
}, [hasNext, isFetchingNext, fetchNext]);
|
|
|
|
|
|
|
|
|
|
const handlePlay = useCallback(
|
|
|
|
|
(track: { id: string; title: string; artist?: string; duration: number; url: string; cover?: string }) => {
|
feat: frontend pages and feature modules polish
Update dashboard (stats, recent tracks/activity), discover, distribution,
education, feed, subscription, support, search, settings, live, cloud,
analytics, auth, chat, social, tracks, playlists, presence, upload,
and library manager. Consistent UI patterns and error handling.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 14:46:21 +00:00
|
|
|
play(track);
|
2026-03-09 00:52:56 +00:00
|
|
|
},
|
feat: frontend pages and feature modules polish
Update dashboard (stats, recent tracks/activity), discover, distribution,
education, feed, subscription, support, search, settings, live, cloud,
analytics, auth, chat, social, tracks, playlists, presence, upload,
and library manager. Consistent UI patterns and error handling.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 14:46:21 +00:00
|
|
|
[play]
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const handleTrackClick = useCallback(
|
|
|
|
|
(track: { id: string }) => {
|
|
|
|
|
navigate(`/tracks/${track.id}`);
|
|
|
|
|
},
|
|
|
|
|
[navigate],
|
2026-03-09 00:52:56 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const handleGenreClick = (genre: Genre) => {
|
|
|
|
|
setSearchParams({ genre: genre.slug });
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const goBack = () => {
|
|
|
|
|
setSearchParams({});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const showGenreList = !browseGenre && !browseTag;
|
|
|
|
|
|
|
|
|
|
if (genresLoading && showGenreList) {
|
|
|
|
|
return (
|
2026-03-25 07:35:44 +00:00
|
|
|
<ContentFadeIn className="min-h-layout-page pb-36">
|
2026-03-09 00:52:56 +00:00
|
|
|
<div className="flex items-center gap-3">
|
|
|
|
|
<Music2 className="w-8 h-8 text-primary" />
|
feat(web): update all features, stories, e2e tests, and auth interceptor
Update auth, playlists, tracks, search, profile, dashboard, player,
settings, and social features. Add e2e audit specs for all major pages.
Update ESLint config, vitest config, and route configuration.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 17:16:36 +00:00
|
|
|
<h1 className="text-2xl font-heading font-bold">{t('discover.title')}</h1>
|
2026-03-09 00:52:56 +00:00
|
|
|
</div>
|
feat: frontend pages and feature modules polish
Update dashboard (stats, recent tracks/activity), discover, distribution,
education, feed, subscription, support, search, settings, live, cloud,
analytics, auth, chat, social, tracks, playlists, presence, upload,
and library manager. Consistent UI patterns and error handling.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 14:46:21 +00:00
|
|
|
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-3 mt-6">
|
2026-03-09 00:52:56 +00:00
|
|
|
{Array.from({ length: 12 }).map((_, i) => (
|
|
|
|
|
<div
|
|
|
|
|
key={i}
|
feat: frontend pages and feature modules polish
Update dashboard (stats, recent tracks/activity), discover, distribution,
education, feed, subscription, support, search, settings, live, cloud,
analytics, auth, chat, social, tracks, playlists, presence, upload,
and library manager. Consistent UI patterns and error handling.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 14:46:21 +00:00
|
|
|
className="min-h-[7.5rem] rounded-2xl bg-muted/40 animate-pulse"
|
|
|
|
|
style={{ animationDelay: `${i * 50}ms` }}
|
2026-03-09 00:52:56 +00:00
|
|
|
/>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
</ContentFadeIn>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
feat(web): update all features, stories, e2e tests, and auth interceptor
Update auth, playlists, tracks, search, profile, dashboard, player,
settings, and social features. Add e2e audit specs for all major pages.
Update ESLint config, vitest config, and route configuration.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 17:16:36 +00:00
|
|
|
const hasEditorialPlaylists = editorialData?.items && editorialData.items.length > 0;
|
|
|
|
|
|
2026-03-09 00:52:56 +00:00
|
|
|
return (
|
2026-03-25 07:35:44 +00:00
|
|
|
<ContentFadeIn className="min-h-layout-page pb-36">
|
feat: frontend improvements — UI polish, player bar, auth flow, i18n
- Header, Sidebar, Toast, Dropdown, EmptyState component refinements
- Auth flow: LoginPage, RegisterPage, AuthInput, AuthLayout improvements
- Player bar: glass effect, progress, track info, controls enhancements
- Dashboard, Discover, Search pages updates
- PlaylistCard, TrackCard component improvements
- Auth store and API interceptors hardening
- i18n: updated en/es/fr locale files
- CSS additions in index.css
- Package.json and vite config updates
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 10:35:44 +00:00
|
|
|
<div className="space-y-8">
|
|
|
|
|
{/* Header */}
|
|
|
|
|
<div className="flex items-center gap-4">
|
2026-03-09 00:52:56 +00:00
|
|
|
{browseGenre || browseTag ? (
|
|
|
|
|
<Button
|
|
|
|
|
variant="ghost"
|
|
|
|
|
size="sm"
|
|
|
|
|
onClick={goBack}
|
feat: frontend improvements — UI polish, player bar, auth flow, i18n
- Header, Sidebar, Toast, Dropdown, EmptyState component refinements
- Auth flow: LoginPage, RegisterPage, AuthInput, AuthLayout improvements
- Player bar: glass effect, progress, track info, controls enhancements
- Dashboard, Discover, Search pages updates
- PlaylistCard, TrackCard component improvements
- Auth store and API interceptors hardening
- i18n: updated en/es/fr locale files
- CSS additions in index.css
- Package.json and vite config updates
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 10:35:44 +00:00
|
|
|
className="-ml-2 hover:bg-[var(--sumi-bg-hover)]"
|
feat(web): update all features, stories, e2e tests, and auth interceptor
Update auth, playlists, tracks, search, profile, dashboard, player,
settings, and social features. Add e2e audit specs for all major pages.
Update ESLint config, vitest config, and route configuration.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 17:16:36 +00:00
|
|
|
aria-label={t('discover.back')}
|
2026-03-09 00:52:56 +00:00
|
|
|
>
|
|
|
|
|
<ChevronLeft className="w-5 h-5" />
|
feat(web): update all features, stories, e2e tests, and auth interceptor
Update auth, playlists, tracks, search, profile, dashboard, player,
settings, and social features. Add e2e audit specs for all major pages.
Update ESLint config, vitest config, and route configuration.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 17:16:36 +00:00
|
|
|
{t('discover.back')}
|
2026-03-09 00:52:56 +00:00
|
|
|
</Button>
|
|
|
|
|
) : null}
|
feat: frontend improvements — UI polish, player bar, auth flow, i18n
- Header, Sidebar, Toast, Dropdown, EmptyState component refinements
- Auth flow: LoginPage, RegisterPage, AuthInput, AuthLayout improvements
- Player bar: glass effect, progress, track info, controls enhancements
- Dashboard, Discover, Search pages updates
- PlaylistCard, TrackCard component improvements
- Auth store and API interceptors hardening
- i18n: updated en/es/fr locale files
- CSS additions in index.css
- Package.json and vite config updates
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 10:35:44 +00:00
|
|
|
<div className="w-12 h-12 rounded-2xl bg-gradient-to-br from-primary/30 to-primary/10 flex items-center justify-center">
|
|
|
|
|
<Compass className="w-6 h-6 text-primary" />
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
|
|
|
|
<h1 className="text-2xl font-heading font-bold tracking-tight">
|
|
|
|
|
{browseGenre
|
|
|
|
|
? genres?.find((g) => g.slug === browseGenre)?.name ?? browseGenre
|
|
|
|
|
: browseTag
|
|
|
|
|
? browseTag
|
feat(web): update all features, stories, e2e tests, and auth interceptor
Update auth, playlists, tracks, search, profile, dashboard, player,
settings, and social features. Add e2e audit specs for all major pages.
Update ESLint config, vitest config, and route configuration.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 17:16:36 +00:00
|
|
|
: t('discover.title')}
|
feat: frontend improvements — UI polish, player bar, auth flow, i18n
- Header, Sidebar, Toast, Dropdown, EmptyState component refinements
- Auth flow: LoginPage, RegisterPage, AuthInput, AuthLayout improvements
- Player bar: glass effect, progress, track info, controls enhancements
- Dashboard, Discover, Search pages updates
- PlaylistCard, TrackCard component improvements
- Auth store and API interceptors hardening
- i18n: updated en/es/fr locale files
- CSS additions in index.css
- Package.json and vite config updates
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 10:35:44 +00:00
|
|
|
</h1>
|
|
|
|
|
{showGenreList && (
|
feat(web): update all features, stories, e2e tests, and auth interceptor
Update auth, playlists, tracks, search, profile, dashboard, player,
settings, and social features. Add e2e audit specs for all major pages.
Update ESLint config, vitest config, and route configuration.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 17:16:36 +00:00
|
|
|
<p className="text-sm text-muted-foreground mt-0.5">{t('discover.subtitle')}</p>
|
feat: frontend improvements — UI polish, player bar, auth flow, i18n
- Header, Sidebar, Toast, Dropdown, EmptyState component refinements
- Auth flow: LoginPage, RegisterPage, AuthInput, AuthLayout improvements
- Player bar: glass effect, progress, track info, controls enhancements
- Dashboard, Discover, Search pages updates
- PlaylistCard, TrackCard component improvements
- Auth store and API interceptors hardening
- i18n: updated en/es/fr locale files
- CSS additions in index.css
- Package.json and vite config updates
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 10:35:44 +00:00
|
|
|
)}
|
|
|
|
|
</div>
|
2026-03-09 00:52:56 +00:00
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{showGenreList && genres ? (
|
feat(web): update all features, stories, e2e tests, and auth interceptor
Update auth, playlists, tracks, search, profile, dashboard, player,
settings, and social features. Add e2e audit specs for all major pages.
Update ESLint config, vitest config, and route configuration.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 17:16:36 +00:00
|
|
|
<section className="space-y-4" aria-label={t('discover.byGenre')}>
|
feat: frontend pages and feature modules polish
Update dashboard (stats, recent tracks/activity), discover, distribution,
education, feed, subscription, support, search, settings, live, cloud,
analytics, auth, chat, social, tracks, playlists, presence, upload,
and library manager. Consistent UI patterns and error handling.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 14:46:21 +00:00
|
|
|
<h2 className="text-lg font-heading font-semibold tracking-tight">
|
feat(web): update all features, stories, e2e tests, and auth interceptor
Update auth, playlists, tracks, search, profile, dashboard, player,
settings, and social features. Add e2e audit specs for all major pages.
Update ESLint config, vitest config, and route configuration.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 17:16:36 +00:00
|
|
|
{t('discover.byGenre')}
|
2026-03-09 00:52:56 +00:00
|
|
|
</h2>
|
feat: frontend pages and feature modules polish
Update dashboard (stats, recent tracks/activity), discover, distribution,
education, feed, subscription, support, search, settings, live, cloud,
analytics, auth, chat, social, tracks, playlists, presence, upload,
and library manager. Consistent UI patterns and error handling.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 14:46:21 +00:00
|
|
|
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-3">
|
feat: frontend improvements — UI polish, player bar, auth flow, i18n
- Header, Sidebar, Toast, Dropdown, EmptyState component refinements
- Auth flow: LoginPage, RegisterPage, AuthInput, AuthLayout improvements
- Player bar: glass effect, progress, track info, controls enhancements
- Dashboard, Discover, Search pages updates
- PlaylistCard, TrackCard component improvements
- Auth store and API interceptors hardening
- i18n: updated en/es/fr locale files
- CSS additions in index.css
- Package.json and vite config updates
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 10:35:44 +00:00
|
|
|
{genres.map((g, i) => (
|
2026-03-09 00:52:56 +00:00
|
|
|
<button
|
|
|
|
|
key={g.slug}
|
|
|
|
|
onClick={() => handleGenreClick(g)}
|
feat(web): update all features, stories, e2e tests, and auth interceptor
Update auth, playlists, tracks, search, profile, dashboard, player,
settings, and social features. Add e2e audit specs for all major pages.
Update ESLint config, vitest config, and route configuration.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 17:16:36 +00:00
|
|
|
aria-label={t('discover.browseGenre', { genre: g.name })}
|
feat: frontend improvements — UI polish, player bar, auth flow, i18n
- Header, Sidebar, Toast, Dropdown, EmptyState component refinements
- Auth flow: LoginPage, RegisterPage, AuthInput, AuthLayout improvements
- Player bar: glass effect, progress, track info, controls enhancements
- Dashboard, Discover, Search pages updates
- PlaylistCard, TrackCard component improvements
- Auth store and API interceptors hardening
- i18n: updated en/es/fr locale files
- CSS additions in index.css
- Package.json and vite config updates
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 10:35:44 +00:00
|
|
|
className={cn(
|
feat: frontend pages and feature modules polish
Update dashboard (stats, recent tracks/activity), discover, distribution,
education, feed, subscription, support, search, settings, live, cloud,
analytics, auth, chat, social, tracks, playlists, presence, upload,
and library manager. Consistent UI patterns and error handling.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 14:46:21 +00:00
|
|
|
'relative overflow-hidden rounded-2xl min-h-[7.5rem] p-4 pb-5 text-left',
|
feat: frontend improvements — UI polish, player bar, auth flow, i18n
- Header, Sidebar, Toast, Dropdown, EmptyState component refinements
- Auth flow: LoginPage, RegisterPage, AuthInput, AuthLayout improvements
- Player bar: glass effect, progress, track info, controls enhancements
- Dashboard, Discover, Search pages updates
- PlaylistCard, TrackCard component improvements
- Auth store and API interceptors hardening
- i18n: updated en/es/fr locale files
- CSS additions in index.css
- Package.json and vite config updates
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 10:35:44 +00:00
|
|
|
'bg-gradient-to-br',
|
|
|
|
|
GENRE_GRADIENTS[i % GENRE_GRADIENTS.length],
|
feat: frontend pages and feature modules polish
Update dashboard (stats, recent tracks/activity), discover, distribution,
education, feed, subscription, support, search, settings, live, cloud,
analytics, auth, chat, social, tracks, playlists, presence, upload,
and library manager. Consistent UI patterns and error handling.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 14:46:21 +00:00
|
|
|
'hover:scale-[1.04] hover:shadow-xl hover:shadow-black/20 active:scale-[0.97]',
|
feat: frontend improvements — UI polish, player bar, auth flow, i18n
- Header, Sidebar, Toast, Dropdown, EmptyState component refinements
- Auth flow: LoginPage, RegisterPage, AuthInput, AuthLayout improvements
- Player bar: glass effect, progress, track info, controls enhancements
- Dashboard, Discover, Search pages updates
- PlaylistCard, TrackCard component improvements
- Auth store and API interceptors hardening
- i18n: updated en/es/fr locale files
- CSS additions in index.css
- Package.json and vite config updates
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 10:35:44 +00:00
|
|
|
'transition-all duration-[var(--sumi-duration-normal)] ease-[var(--sumi-ease-out)]',
|
feat: frontend pages and feature modules polish
Update dashboard (stats, recent tracks/activity), discover, distribution,
education, feed, subscription, support, search, settings, live, cloud,
analytics, auth, chat, social, tracks, playlists, presence, upload,
and library manager. Consistent UI patterns and error handling.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 14:46:21 +00:00
|
|
|
'group animate-card-enter',
|
feat: frontend improvements — UI polish, player bar, auth flow, i18n
- Header, Sidebar, Toast, Dropdown, EmptyState component refinements
- Auth flow: LoginPage, RegisterPage, AuthInput, AuthLayout improvements
- Player bar: glass effect, progress, track info, controls enhancements
- Dashboard, Discover, Search pages updates
- PlaylistCard, TrackCard component improvements
- Auth store and API interceptors hardening
- i18n: updated en/es/fr locale files
- CSS additions in index.css
- Package.json and vite config updates
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 10:35:44 +00:00
|
|
|
)}
|
|
|
|
|
style={{ animationDelay: `${i * 40}ms` }}
|
2026-03-09 00:52:56 +00:00
|
|
|
>
|
feat: frontend pages and feature modules polish
Update dashboard (stats, recent tracks/activity), discover, distribution,
education, feed, subscription, support, search, settings, live, cloud,
analytics, auth, chat, social, tracks, playlists, presence, upload,
and library manager. Consistent UI patterns and error handling.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 14:46:21 +00:00
|
|
|
<span className="relative z-10 font-heading font-bold text-white text-base drop-shadow-md">
|
feat: frontend improvements — UI polish, player bar, auth flow, i18n
- Header, Sidebar, Toast, Dropdown, EmptyState component refinements
- Auth flow: LoginPage, RegisterPage, AuthInput, AuthLayout improvements
- Player bar: glass effect, progress, track info, controls enhancements
- Dashboard, Discover, Search pages updates
- PlaylistCard, TrackCard component improvements
- Auth store and API interceptors hardening
- i18n: updated en/es/fr locale files
- CSS additions in index.css
- Package.json and vite config updates
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 10:35:44 +00:00
|
|
|
{g.name}
|
|
|
|
|
</span>
|
|
|
|
|
{'count' in g && (g as Genre & { count?: number }).count != null && (
|
feat: frontend pages and feature modules polish
Update dashboard (stats, recent tracks/activity), discover, distribution,
education, feed, subscription, support, search, settings, live, cloud,
analytics, auth, chat, social, tracks, playlists, presence, upload,
and library manager. Consistent UI patterns and error handling.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 14:46:21 +00:00
|
|
|
<span className="relative z-10 block mt-1 text-xs text-white/60 font-medium">
|
feat(web): update all features, stories, e2e tests, and auth interceptor
Update auth, playlists, tracks, search, profile, dashboard, player,
settings, and social features. Add e2e audit specs for all major pages.
Update ESLint config, vitest config, and route configuration.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 17:16:36 +00:00
|
|
|
{t('discover.trackCount', { count: (g as Genre & { count?: number }).count })}
|
feat: frontend improvements — UI polish, player bar, auth flow, i18n
- Header, Sidebar, Toast, Dropdown, EmptyState component refinements
- Auth flow: LoginPage, RegisterPage, AuthInput, AuthLayout improvements
- Player bar: glass effect, progress, track info, controls enhancements
- Dashboard, Discover, Search pages updates
- PlaylistCard, TrackCard component improvements
- Auth store and API interceptors hardening
- i18n: updated en/es/fr locale files
- CSS additions in index.css
- Package.json and vite config updates
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 10:35:44 +00:00
|
|
|
</span>
|
|
|
|
|
)}
|
feat: frontend pages and feature modules polish
Update dashboard (stats, recent tracks/activity), discover, distribution,
education, feed, subscription, support, search, settings, live, cloud,
analytics, auth, chat, social, tracks, playlists, presence, upload,
and library manager. Consistent UI patterns and error handling.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 14:46:21 +00:00
|
|
|
{/* Decorative circles */}
|
|
|
|
|
<div className="absolute -bottom-3 -right-3 w-24 h-24 rounded-full bg-white/10 rotate-12 group-hover:scale-125 transition-transform duration-500 ease-out" />
|
|
|
|
|
<div className="absolute -top-4 -right-6 w-16 h-16 rounded-full bg-white/[0.07] group-hover:scale-110 transition-transform duration-700" />
|
|
|
|
|
{/* Bottom highlight */}
|
|
|
|
|
<div className="absolute inset-x-0 bottom-0 h-1/2 bg-gradient-to-t from-black/15 to-transparent pointer-events-none" />
|
2026-03-09 00:52:56 +00:00
|
|
|
</button>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
</section>
|
|
|
|
|
) : null}
|
|
|
|
|
|
2026-03-09 15:49:05 +00:00
|
|
|
{showGenreList ? (
|
feat(web): update all features, stories, e2e tests, and auth interceptor
Update auth, playlists, tracks, search, profile, dashboard, player,
settings, and social features. Add e2e audit specs for all major pages.
Update ESLint config, vitest config, and route configuration.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 17:16:36 +00:00
|
|
|
<section className="space-y-4" aria-label={t('discover.editorialPlaylists')}>
|
feat: frontend pages and feature modules polish
Update dashboard (stats, recent tracks/activity), discover, distribution,
education, feed, subscription, support, search, settings, live, cloud,
analytics, auth, chat, social, tracks, playlists, presence, upload,
and library manager. Consistent UI patterns and error handling.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 14:46:21 +00:00
|
|
|
<div className="section-divider my-2" />
|
|
|
|
|
<h2 className="text-lg font-heading font-semibold tracking-tight">
|
feat(web): update all features, stories, e2e tests, and auth interceptor
Update auth, playlists, tracks, search, profile, dashboard, player,
settings, and social features. Add e2e audit specs for all major pages.
Update ESLint config, vitest config, and route configuration.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 17:16:36 +00:00
|
|
|
{t('discover.editorialPlaylists')}
|
2026-03-09 15:49:05 +00:00
|
|
|
</h2>
|
|
|
|
|
{editorialLoading ? (
|
|
|
|
|
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-4">
|
|
|
|
|
{Array.from({ length: 6 }).map((_, i) => (
|
|
|
|
|
<PlaylistCardSkeleton key={i} />
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
feat(web): update all features, stories, e2e tests, and auth interceptor
Update auth, playlists, tracks, search, profile, dashboard, player,
settings, and social features. Add e2e audit specs for all major pages.
Update ESLint config, vitest config, and route configuration.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 17:16:36 +00:00
|
|
|
) : hasEditorialPlaylists ? (
|
2026-03-09 15:49:05 +00:00
|
|
|
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-4">
|
|
|
|
|
{editorialData.items.map((pl) => (
|
|
|
|
|
<PlaylistCard
|
|
|
|
|
key={pl.id}
|
|
|
|
|
playlist={{
|
|
|
|
|
id: pl.id,
|
|
|
|
|
user_id: pl.user?.id ?? '',
|
|
|
|
|
title: pl.title,
|
|
|
|
|
description: pl.description,
|
|
|
|
|
is_public: true,
|
|
|
|
|
track_count: pl.track_count,
|
|
|
|
|
cover_url: pl.cover_url,
|
|
|
|
|
created_at: '',
|
|
|
|
|
updated_at: '',
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
feat(web): update all features, stories, e2e tests, and auth interceptor
Update auth, playlists, tracks, search, profile, dashboard, player,
settings, and social features. Add e2e audit specs for all major pages.
Update ESLint config, vitest config, and route configuration.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 17:16:36 +00:00
|
|
|
) : (
|
|
|
|
|
<p className="text-sm text-muted-foreground py-4">
|
|
|
|
|
{t('discover.noEditorialPlaylists')}
|
|
|
|
|
</p>
|
|
|
|
|
)}
|
2026-03-09 15:49:05 +00:00
|
|
|
</section>
|
|
|
|
|
) : null}
|
|
|
|
|
|
2026-03-09 00:52:56 +00:00
|
|
|
{browseGenre || browseTag ? (
|
|
|
|
|
<>
|
|
|
|
|
{isLoadingTracks ? (
|
|
|
|
|
<div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4">
|
|
|
|
|
{Array.from({ length: 8 }).map((_, i) => (
|
|
|
|
|
<TrackCardSkeleton key={i} />
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
) : error ? (
|
feat: frontend improvements — UI polish, player bar, auth flow, i18n
- Header, Sidebar, Toast, Dropdown, EmptyState component refinements
- Auth flow: LoginPage, RegisterPage, AuthInput, AuthLayout improvements
- Player bar: glass effect, progress, track info, controls enhancements
- Dashboard, Discover, Search pages updates
- PlaylistCard, TrackCard component improvements
- Auth store and API interceptors hardening
- i18n: updated en/es/fr locale files
- CSS additions in index.css
- Package.json and vite config updates
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 10:35:44 +00:00
|
|
|
<ErrorDisplay error={error} variant="card" onRetry={() => { refetch(); }} />
|
2026-03-09 00:52:56 +00:00
|
|
|
) : (
|
|
|
|
|
<>
|
|
|
|
|
<TrackGrid
|
|
|
|
|
tracks={tracks}
|
feat(web): update all features, stories, e2e tests, and auth interceptor
Update auth, playlists, tracks, search, profile, dashboard, player,
settings, and social features. Add e2e audit specs for all major pages.
Update ESLint config, vitest config, and route configuration.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 17:16:36 +00:00
|
|
|
emptyMessage={t('discover.noTracksInGenre')}
|
2026-03-09 00:52:56 +00:00
|
|
|
onTrackPlay={handlePlay}
|
feat: frontend pages and feature modules polish
Update dashboard (stats, recent tracks/activity), discover, distribution,
education, feed, subscription, support, search, settings, live, cloud,
analytics, auth, chat, social, tracks, playlists, presence, upload,
and library manager. Consistent UI patterns and error handling.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 14:46:21 +00:00
|
|
|
onTrackClick={handleTrackClick}
|
2026-03-09 00:52:56 +00:00
|
|
|
gap="md"
|
|
|
|
|
/>
|
|
|
|
|
<div ref={loadMoreRef} className="flex justify-center py-8">
|
|
|
|
|
{isFetchingNext && (
|
|
|
|
|
<Loader2 className="w-8 h-8 animate-spin text-muted-foreground" />
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
</>
|
|
|
|
|
)}
|
|
|
|
|
</>
|
|
|
|
|
) : null}
|
|
|
|
|
</div>
|
|
|
|
|
</ContentFadeIn>
|
|
|
|
|
);
|
|
|
|
|
}
|