portfolio/src/app/music/page.tsx
apatil d9f84e45da
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Make music cover show up
2025-05-07 22:34:27 +01:00

94 lines
2.9 KiB
TypeScript

'use client';
import { useEffect, useState } from 'react';
import {
Typography, List, ListItem, ListItemText, Button, Input,
ListItemButton,
ListItemIcon,
Grid,
useTheme
} from '@mui/material';
import UploadIcon from '@mui/icons-material/Upload';
import AudioPlayer from '@/components/AudioPlayer/AudioPlayer';
import AudiotrackIcon from '@mui/icons-material/Audiotrack';
export default function Home() {
const [tracks, setTracks] = useState<string[]>([]);
const [currentTrack, setCurrentTrack] = useState<string | null>(null);
const [uploading, setUploading] = useState(false);
const theme = useTheme();
useEffect(() => {
fetchTracks();
}, []);
const fetchTracks = async () => {
const res = await fetch('/api/tracks');
const data = await res.json();
setTracks(data);
};
const handleUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {
if (!e.target.files?.length) return;
const formData = new FormData();
formData.append('file', e.target.files[0]);
setUploading(true);
const res = await fetch('/api/upload', {
method: 'POST',
body: formData,
});
setUploading(false);
if (res.ok) {
fetchTracks();
} else {
console.error(res.status, res.text())
}
};
return (
<Grid container sx={{ paddingTop: 4 }} spacing={2}>
<Grid size={12}>
<Typography variant="h4" gutterBottom textAlign="center">
Music
</Typography>
</Grid>
<Grid size={12}>
<Typography variant="body1" gutterBottom textAlign="center" mx={10}>
The grizzly made some tunes while he was bored grazing the blueberry patches in the high dessert.
</Typography>
</Grid >
<Grid size={12} textAlign="center">
<AudioPlayer title={currentTrack?.split('.')[0] ?? 'click on any song from list below'} src={currentTrack ? `/api/music/${encodeURIComponent(currentTrack)}` : ''} />
</Grid>
<Grid size={12} textAlign="center" >
<label htmlFor="upload">
<Input
id="upload"
type="file"
sx={{ display: 'none' }}
inputProps={{ accept: '.mp3, .m4a, audio/mpeg, audio/mp4, audio/x-m4a' }}
onChange={handleUpload}
/>
<Button variant="contained" color='error' component="span" startIcon={<UploadIcon />} disabled={uploading}>
{uploading ? 'Uploading...' : 'Upload'}
</Button>
</label>
</Grid>
<Grid size={12}>
<List>
{tracks.map((track, idx) => (
<ListItem key={idx} onClick={() => setCurrentTrack(track)} sx={{ bgcolor: theme.palette.background.paper }}>
<ListItemButton>
<ListItemIcon>
<AudiotrackIcon color='primary' />
</ListItemIcon>
<ListItemText primary={track.split('.')[0]} />
</ListItemButton>
</ListItem>
))}
</List>
</Grid>
</Grid>
);
}