implement music by time period, clean up header

This commit is contained in:
Aidan 2025-01-07 19:33:22 -05:00
parent 4b88c00919
commit 37d478d9b8
5 changed files with 161 additions and 10 deletions

View File

@ -1,17 +1,17 @@
"use client";
import { useState } from 'react'
import Link from 'next/link'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faWordpressSimple } from '@fortawesome/free-brands-svg-icons'
import { faLink, faHouse, faUser, faPhone, faBars, faTimes, faTerminal } from '@fortawesome/free-solid-svg-icons'
import { useState } from 'react';
import Link from 'next/link';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faWordpressSimple } from '@fortawesome/free-brands-svg-icons';
import { faLink, faHouse, faUser, faPhone, faBars, faTimes, faTerminal, faMusic } from '@fortawesome/free-solid-svg-icons';
export default function Header() {
const [isOpen, setIsOpen] = useState(false)
const [isOpen, setIsOpen] = useState(false);
const toggleMenu = () => {
setIsOpen(!isOpen)
}
setIsOpen(!isOpen);
};
return (
<header className="bg-gray-800">
@ -28,6 +28,7 @@ export default function Header() {
<li><Link href="/contact" className="flex items-center text-gray-300 hover:text-white hover:bg-gray-700 rounded-md px-3 py-2 transition-all"><FontAwesomeIcon icon={faPhone} className="text-md mr-2" /> Contact</Link></li>
<li><Link href="/domains" className="flex items-center text-gray-300 hover:text-white hover:bg-gray-700 rounded-md px-3 py-2 transition-all"><FontAwesomeIcon icon={faLink} className="text-md mr-2" /> Domains</Link></li>
<li><Link href="https://blog.aidxn.fun/" className="flex items-center text-gray-300 hover:text-white hover:bg-gray-700 rounded-md px-3 py-2 transition-all"><FontAwesomeIcon icon={faWordpressSimple} className="text-md mr-2" /> Blog</Link></li>
<li><Link href="/music" className="flex items-center text-gray-300 hover:text-white hover:bg-gray-700 rounded-md px-3 py-2 transition-all"><FontAwesomeIcon icon={faMusic} className="text-md mr-2" /> Music by Time</Link></li>
<li className="flex items-center">
<Link href="https://tilde.club/~lxu" className="flex items-center text-gray-300 hover:text-white hover:bg-gray-700 rounded-md px-3 py-2 transition-all">
<FontAwesomeIcon icon={faTerminal} className="text-md mr-2" /> Tilde
@ -39,5 +40,5 @@ export default function Header() {
</ul>
</nav>
</header>
)
);
}

93
app/components/Music.tsx Normal file
View File

@ -0,0 +1,93 @@
"use client";
import { useState, useEffect } from 'react';
import Image from 'next/image';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faPlay, faStepBackward, faStepForward, faArrowLeft, faArrowRight } from '@fortawesome/free-solid-svg-icons';
export default function Home() {
const [timePeriod, setTimePeriod] = useState('2020s');
const [songs, setSongs] = useState([]);
const [currentIndex, setCurrentIndex] = useState(0);
useEffect(() => {
fetch('/data/music.json')
.then(response => response.json())
.then(data => {
const selectedPeriod = data.find(period => period.timePeriod === timePeriod);
const songsList = selectedPeriod ? selectedPeriod.songs : [];
setSongs(songsList);
setCurrentIndex(Math.floor(Math.random() * songsList.length));
});
}, [timePeriod]);
useEffect(() => {
const selectElement = document.getElementById('timePeriod');
if (selectElement) {
setTimePeriod(selectElement.value);
}
}, []);
const handleNext = () => {
setCurrentIndex((currentIndex + 1) % songs.length);
};
const handlePrevious = () => {
setCurrentIndex((currentIndex - 1 + songs.length) % songs.length);
};
return (
<div className="max-w-2xl mx-auto">
<section id="music-carousel" className="mb-12">
<h2 className="text-3xl font-semibold mb-4 text-gray-200">Music By Time Period</h2>
<div className="mb-4 pb-4">
<label htmlFor="timePeriod" className="text-gray-300">Time Period:</label>
<select
id="timePeriod"
value={timePeriod}
onChange={(e) => setTimePeriod(e.target.value)}
className="ml-2 p-2 bg-gray-700 text-gray-300 rounded"
>
<option value="Summer 2024">Summer 2024</option>
</select>
</div>
{songs.length > 0 && (
<div className="relative">
<button onClick={handlePrevious} className="absolute left-0 top-1/2 transform -translate-y-1/2 text-gray-300">
<FontAwesomeIcon icon={faArrowLeft} size="2x" />
</button>
<div className="text-center">
<Image
src={songs[currentIndex].albumArt}
alt={songs[currentIndex].name}
width={300}
height={300}
className="mx-auto mb-4 rounded-lg"
/>
<h3 className="text-2xl font-bold text-gray-100">{songs[currentIndex].name}</h3>
<p className="text-gray-300">{songs[currentIndex].artist}</p>
<p className="text-gray-300">{songs[currentIndex].duration}</p>
<div className="mt-4">
<button className="mr-4 text-gray-300">
<FontAwesomeIcon icon={faStepBackward} size="2x" />
</button>
<button className="mr-4 text-gray-300" onClick={() => window.open(songs[currentIndex]?.link, '_blank')}>
<FontAwesomeIcon icon={faPlay} size="2x" />
</button>
<button className="text-gray-300">
<FontAwesomeIcon icon={faStepForward} size="2x" />
</button>
</div>
</div>
<button onClick={handleNext} className="absolute right-0 top-1/2 transform -translate-y-1/2 text-gray-300">
<FontAwesomeIcon icon={faArrowRight} size="2x" />
</button>
</div>
)}
</section>
</div>
);
}

15
app/music/page.tsx Normal file
View File

@ -0,0 +1,15 @@
import Header from '../components/Header'
import MusicWidget from '../components/Music'
import Footer from '../components/Footer'
export default function Music() {
return (
<div className="min-h-screen flex flex-col">
<Header />
<main className="flex-grow container mx-auto px-4 py-12">
<MusicWidget />
</main>
<Footer />
</div>
)
}

View File

@ -2,7 +2,7 @@ import type { NextConfig } from "next";
const nextConfig: NextConfig = {
images: {
domains: ['lastfm.freetls.fastly.net'],
domains: ['lastfm.freetls.fastly.net', 'p0ntus.com'],
},
};

42
public/data/music.json Normal file
View File

@ -0,0 +1,42 @@
[
{
"timePeriod": "Summer 2024",
"songs": [
{
"albumArt": "https://p0ntus.com/archives/img/noticeme.png",
"name": "Notice Me",
"artist": "tobi lou feat. MIA GLADSTONE",
"duration": "2:35",
"link": "https://www.last.fm/music/tobi+lou/Notice+Me"
},
{
"albumArt": "https://p0ntus.com/archives/img/comforttexas.webp",
"name": "comfort, texas",
"artist": "Buppy.",
"duration": "2:11",
"link": "https://www.last.fm/music/Buppy./comfort,+texas"
},
{
"albumArt": "https://p0ntus.com/archives/img/nonperishable.webp",
"name": "Jelly",
"artist": "tobi lou",
"duration": "1:50",
"link": "https://www.last.fm/music/tobi+lou/_/Jelly"
},
{
"albumArt": "https://p0ntus.com/archives/img/exes.webp",
"name": "exes",
"artist": "Tate McRae",
"duration": "2:39",
"link": "https://www.last.fm/music/Tate+McRae/exes/exes"
},
{
"albumArt": "https://p0ntus.com/archives/img/ick.webp",
"name": "Ick",
"artist": "Lay Bankz",
"duration": "1:55",
"link": "https://www.last.fm/music/Lay+Bankz/_/Ick"
}
]
}
]