feat: i18n

This commit is contained in:
Senko-san
2026-06-06 15:23:07 +03:00
parent bbd59cc225
commit e45bcef3a5
21 changed files with 613 additions and 163 deletions
@@ -1,4 +1,5 @@
import { useParams, useNavigate } from 'react-router';
import { useTranslation } from 'react-i18next';
import { ScrollArea, IconButton, Button } from '@olly/modern-sk';
import {
useGetPlaylistQuery,
@@ -13,6 +14,7 @@ import { setQueue } from '../../store/slices/queue';
import { formatDuration } from '../../lib/format';
export function PlaylistDetailPage() {
const { t } = useTranslation();
const { playlistId } = useParams<{ playlistId: string }>();
const navigate = useNavigate();
const dispatch = useAppDispatch();
@@ -35,7 +37,7 @@ export function PlaylistDetailPage() {
if (playlistQuery.isError) {
return (
<ErrorState
message="Failed to load playlist"
message={t('playlist.error')}
onRetry={() => playlistQuery.refetch()}
/>
);
@@ -79,7 +81,7 @@ export function PlaylistDetailPage() {
variant="ghost"
size="sm"
onClick={() => navigate(-1)}
aria-label="Back"
aria-label={t('common.back')}
>
</IconButton>
@@ -93,7 +95,7 @@ export function PlaylistDetailPage() {
letterSpacing: '0.05em',
}}
>
Playlist
{t('playlist.type')}
</p>
<h1
style={{ margin: '0.25rem 0', fontSize: '1.5rem', fontWeight: 700 }}
@@ -119,7 +121,7 @@ export function PlaylistDetailPage() {
}}
>
{playlist &&
`${playlist.trackCount} tracks · ${formatDuration(playlist.totalDurationMs)}`}
`${playlist.trackCount} · ${formatDuration(playlist.totalDurationMs)}`}
</p>
</div>
<Button
@@ -127,7 +129,7 @@ export function PlaylistDetailPage() {
onClick={handlePlayAll}
disabled={!tracks.length}
>
Play
{t('playlist.play')}
</Button>
</div>
@@ -135,7 +137,7 @@ export function PlaylistDetailPage() {
{tracksQuery.isLoading && <LoadingSkeleton rows={10} />}
{tracksQuery.isError && (
<ErrorState
message="Failed to load tracks"
message={t('playlist.tracksError')}
onRetry={() => tracksQuery.refetch()}
/>
)}
@@ -144,8 +146,8 @@ export function PlaylistDetailPage() {
tracks.length === 0 && (
<EmptyState
icon="♫"
title="Empty playlist"
description="This playlist has no tracks yet."
title={t('playlist.empty.title')}
description={t('playlist.empty.description')}
/>
)}
{tracks.map((track, i) => (