bug fixes, cleanup unmaintained pages, content changes, design improvements
This commit is contained in:
parent
1e44e329ba
commit
db86ce3277
21 changed files with 614 additions and 714 deletions
|
@ -2,7 +2,18 @@
|
|||
|
||||
import React, { useState, useRef, useEffect } from 'react'
|
||||
import Link from 'next/link'
|
||||
import { House, Link as LinkIcon, User, Phone, BookOpen, Music, Rss, X, Menu, Globe, ChevronDown } from 'lucide-react'
|
||||
import {
|
||||
House,
|
||||
Link as LinkIcon,
|
||||
User,
|
||||
Phone,
|
||||
BookOpen,
|
||||
Rss,
|
||||
X,
|
||||
Menu,
|
||||
Globe,
|
||||
ChevronDown
|
||||
} from 'lucide-react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
interface NavItemProps {
|
||||
|
@ -25,7 +36,7 @@ const LanguageSelector = () => {
|
|||
const [isOpen, setIsOpen] = useState(false);
|
||||
const [isMobile, setIsMobile] = useState(false);
|
||||
const dropdownRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
|
||||
const languages = [
|
||||
{ code: 'en-US', name: 'English' },
|
||||
];
|
||||
|
@ -34,7 +45,7 @@ const LanguageSelector = () => {
|
|||
const checkMobile = () => {
|
||||
setIsMobile(window.innerWidth < 1024);
|
||||
};
|
||||
|
||||
|
||||
checkMobile();
|
||||
window.addEventListener('resize', checkMobile);
|
||||
return () => window.removeEventListener('resize', checkMobile);
|
||||
|
@ -77,7 +88,7 @@ const LanguageSelector = () => {
|
|||
|
||||
return (
|
||||
<div className="relative" ref={dropdownRef}>
|
||||
<button
|
||||
<button
|
||||
onClick={() => setIsOpen(!isOpen)}
|
||||
onKeyDown={handleKeyDown}
|
||||
className={`flex items-center text-gray-300 hover:text-white hover:bg-gray-700 rounded-md px-3 py-2 transition-all duration-300 ${isMobile ? 'w-full' : ''}`}
|
||||
|
@ -87,10 +98,10 @@ const LanguageSelector = () => {
|
|||
{buttonContent}
|
||||
</button>
|
||||
{isOpen && (
|
||||
<div
|
||||
<div
|
||||
className={`${
|
||||
isMobile
|
||||
? 'relative mt-1 w-full bg-gray-800 rounded-md shadow-lg'
|
||||
isMobile
|
||||
? 'relative mt-1 w-full bg-gray-800 rounded-md shadow-lg'
|
||||
: 'absolute right-0 mt-2 w-48 bg-gray-800 rounded-md shadow-lg z-50'
|
||||
}`}
|
||||
role="menu"
|
||||
|
@ -137,7 +148,6 @@ export default function Header() {
|
|||
<NavItem href="/contact" icon={Phone}>Contact</NavItem>
|
||||
<NavItem href="/domains" icon={LinkIcon}>Domains</NavItem>
|
||||
<NavItem href="/manifesto" icon={BookOpen}>Manifesto</NavItem>
|
||||
<NavItem href="/music" icon={Music}>Music</NavItem>
|
||||
<NavItem href="https://disfunction.blog" icon={Rss}>Blog</NavItem>
|
||||
<div className="lg:hidden">
|
||||
<LanguageSelector />
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
import React from 'react';
|
||||
import Button from './Button';
|
||||
|
||||
interface TimePeriod {
|
||||
title: string;
|
||||
slug: string;
|
||||
}
|
||||
|
||||
const timePeriods: TimePeriod[] = [
|
||||
{ title: 'Late Summer 2024', slug: 'late-summer-2024' },
|
||||
{ title: 'Early Summer 2024', slug: 'early-summer-2024' },
|
||||
];
|
||||
|
||||
const MusicInfo: React.FC = () => {
|
||||
return (
|
||||
<div>
|
||||
{timePeriods.map((period) => (
|
||||
<section key={period.slug} className="mb-12">
|
||||
<h2 className="text-2xl font-semibold mb-4">{period.title}</h2>
|
||||
<Button
|
||||
href={`/time-periods/${period.slug}/what-was-going-on`}
|
||||
label="WHAT WAS GOING ON"
|
||||
/>
|
||||
</section>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default MusicInfo;
|
||||
|
|
@ -1,14 +1,16 @@
|
|||
"use client"
|
||||
|
||||
import {
|
||||
SiNextdotjs,
|
||||
SiLucide,
|
||||
SiVercel,
|
||||
SiCloudflarepages,
|
||||
SiSimpleicons,
|
||||
SiFontawesome,
|
||||
SiShadcnui,
|
||||
SiTailwindcss
|
||||
} from "react-icons/si"
|
||||
import Link from 'next/link'
|
||||
import { useState, useEffect } from 'react'
|
||||
|
||||
export const footerMessages = [
|
||||
[
|
||||
|
@ -31,11 +33,6 @@ export const footerMessages = [
|
|||
"https://vercel.com/font",
|
||||
<SiVercel key="vercel" className="text-md mr-2" />
|
||||
],
|
||||
[
|
||||
"Hosted by Cloudflare",
|
||||
"https://workers.cloudflare.com/",
|
||||
<SiCloudflarepages key="cloudflare" className="text-md mr-2" />
|
||||
],
|
||||
[
|
||||
"Icons by Font Awesome",
|
||||
"https://fontawesome.com/",
|
||||
|
@ -54,11 +51,30 @@ export const footerMessages = [
|
|||
]
|
||||
|
||||
export default function RandomFooterMsg() {
|
||||
const randomIndex = Math.floor(Math.random() * footerMessages.length)
|
||||
const [randomIndex, setRandomIndex] = useState(0)
|
||||
const [isMounted, setIsMounted] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
setIsMounted(true)
|
||||
setRandomIndex(Math.floor(Math.random() * footerMessages.length))
|
||||
}, [])
|
||||
|
||||
if (!isMounted) {
|
||||
const [message, url, icon] = footerMessages[0]
|
||||
return (
|
||||
<Link href={String(url)} target="_blank" rel="noopener noreferrer" className="hover:text-white transition-colors mb-2 sm:mb-0">
|
||||
<div className="flex items-center justify-center">
|
||||
{icon}
|
||||
{message}
|
||||
</div>
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
|
||||
const [message, url, icon] = footerMessages[randomIndex]
|
||||
|
||||
return (
|
||||
<Link href={String(url)} target="_blank" rel="noopener noreferrer" className="hover:text-white transition-colors mb-2 sm:mb-0" suppressHydrationWarning>
|
||||
<Link href={String(url)} target="_blank" rel="noopener noreferrer" className="hover:text-white transition-colors mb-2 sm:mb-0">
|
||||
<div className="flex items-center justify-center">
|
||||
{icon}
|
||||
{message}
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
import React from 'react'
|
||||
import BackButton from '@/components/objects/BackButton'
|
||||
|
||||
const WhatWasGoingOnLateSummer2024: React.FC = () => {
|
||||
return (
|
||||
<div className="max-w-2xl mx-auto text-center">
|
||||
<h1 className="text-4xl font-bold my-2 text-center text-gray-200" style={{ textShadow: '0 0 10px rgba(255, 255, 255, 0.5)' }}>
|
||||
What was going on during the start of summer 2024?
|
||||
</h1>
|
||||
<div className="px-6 pt-6">
|
||||
<p className="text-gray-300 mb-4">
|
||||
During Early Summer 2024, I was walking a ton in towns all across Massachusetts. During this time, I would listen to a <i>lot</i> of music. I regret not finding out about LastFM for so long... During this time, I was always happy, especially when I had music or a YouTube video playing. I would also call my friends often during this time.
|
||||
</p>
|
||||
<h2 className="text-2xl font-semibold mb-4 mt-12 text-gray-200">Context</h2>
|
||||
<p className="text-gray-300 mb-4">
|
||||
This summer was the one where I came back from my abusive treatment center. I was finally free from the place that had been holding me back for so long. So as you can imagine, I felt free as a bird.
|
||||
</p>
|
||||
<p className="text-gray-300 mb-4">
|
||||
With this chance to explore, being in so many different towns, I really had a good time and made good memories, which I will not be writing about.
|
||||
</p>
|
||||
<BackButton href="/music" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default WhatWasGoingOnLateSummer2024;
|
|
@ -1,26 +0,0 @@
|
|||
import React from 'react'
|
||||
import BackButton from '@/components/objects/BackButton'
|
||||
|
||||
const WhatWasGoingOnLateSummer2024: React.FC = () => {
|
||||
return (
|
||||
<div className="max-w-2xl mx-auto text-center">
|
||||
<h1 className="text-4xl font-bold my-2 text-center text-gray-200" style={{ textShadow: '0 0 10px rgba(255, 255, 255, 0.5)' }}>
|
||||
What was going on during the end of summer 2024?
|
||||
</h1>
|
||||
<div className="px-6 pt-6">
|
||||
<p className="text-gray-300 mb-4">
|
||||
During late summer 2024, my depression and the "after effects" of treatment really kicked in. I had quit going to my therapist as I didn't feel like they were doing much of anything for me. I am very happy to say that since I quit my therapist, I have been doing much better.
|
||||
</p>
|
||||
<p className="text-gray-300 mb-4">
|
||||
At this time, the baseball season was over, so I was walking around much less. I was still listening to a lot of music and I started getting into less depressed songs. I was also starting to get into more "normal" music, which was an interesting phase (which I believe I'm still in).
|
||||
</p>
|
||||
<p className="text-gray-300 mb-4">
|
||||
A highlight of late summer 2024 was a vacation I took. This vacation has entire albums which remind me of it and I will always cherish those memories deeply.
|
||||
</p>
|
||||
<BackButton href="/music" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default WhatWasGoingOnLateSummer2024;
|
|
@ -1,9 +1,8 @@
|
|||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||
import { faGitAlt, faGithub } from '@fortawesome/free-brands-svg-icons'
|
||||
import { faStar, faCodeBranch } from '@fortawesome/free-solid-svg-icons'
|
||||
import featuredProjects from '@/public/data/featured.json'
|
||||
import Link from 'next/link'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { SiGithub, SiForgejo } from "react-icons/si"
|
||||
import { TbStar, TbGitBranch } from "react-icons/tb"
|
||||
import featuredProjects from "@/public/data/featured.json"
|
||||
import Link from "next/link"
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
export default function GitHubFeatured({ className }: { className?: string }) {
|
||||
return (
|
||||
|
@ -11,16 +10,16 @@ export default function GitHubFeatured({ className }: { className?: string }) {
|
|||
{featuredProjects.map((project) => (
|
||||
<div key={project.id} className="bg-gray-800 p-6 rounded-lg shadow-md min-h-[200px] flex flex-col">
|
||||
<div className="flex-1">
|
||||
<h3 className="text-xl font-bold text-gray-100 mb-3">
|
||||
<FontAwesomeIcon icon={project.github ? faGithub : faGitAlt} className="mr-2" /> {project.name}
|
||||
<h3 className="flex items-center justify-center text-xl font-bold text-gray-100 mb-3">
|
||||
{project.github ? <SiGithub className="mr-2" /> : <SiForgejo className="mr-2" />} {project.name}
|
||||
</h3>
|
||||
<p className="text-gray-300 grow">{project.description}</p>
|
||||
</div>
|
||||
<div className="pt-4 border-t border-gray-700 flex justify-between items-center mt-auto">
|
||||
<Link href={project.url} className="text-blue-400 hover:underline">View Repo</Link>
|
||||
<div className="flex items-center text-gray-400">
|
||||
<FontAwesomeIcon icon={faStar} className="mr-1" /> {project.stars}
|
||||
<FontAwesomeIcon icon={faCodeBranch} className="ml-4 mr-1" /> {project.forks}
|
||||
<TbStar className="mr-1 size-5" /> {project.stars}
|
||||
<TbGitBranch className="ml-4 mr-1 size-5" /> {project.forks}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,127 +0,0 @@
|
|||
"use client"
|
||||
|
||||
import { useState, useEffect } from "react"
|
||||
import Image from "next/image"
|
||||
import { Play, SkipBack, SkipForward } from "lucide-react"
|
||||
import LoadingSpinner from "../objects/LoadingSpinner"
|
||||
import { SeekBar } from "@/components/objects/SeekBar"
|
||||
|
||||
interface Song {
|
||||
albumArt: string
|
||||
name: string
|
||||
artist: string
|
||||
duration: string
|
||||
link?: string
|
||||
}
|
||||
|
||||
interface Period {
|
||||
timePeriod: string
|
||||
songs: Song[]
|
||||
}
|
||||
|
||||
export default function Home() {
|
||||
const [timePeriod, setTimePeriod] = useState("Early Summer 2024")
|
||||
const [songs, setSongs] = useState<Song[]>([])
|
||||
const [currentIndex, setCurrentIndex] = useState(0)
|
||||
const [isLoading, setIsLoading] = useState(true)
|
||||
const [currentPosition, setCurrentPosition] = useState(0)
|
||||
|
||||
useEffect(() => {
|
||||
setIsLoading(true)
|
||||
fetch("/data/music.json")
|
||||
.then((response) => response.json())
|
||||
.then((data: Period[]) => {
|
||||
const selectedPeriod = data.find((period) => period.timePeriod === timePeriod)
|
||||
const songsList = selectedPeriod ? selectedPeriod.songs : []
|
||||
setSongs(songsList)
|
||||
const newIndex = Math.floor(Math.random() * songsList.length)
|
||||
setCurrentIndex(newIndex)
|
||||
// Set initial random position for the selected song
|
||||
if (songsList.length > 0) {
|
||||
const durationInSeconds = parseDuration(songsList[newIndex]?.duration || "0:00")
|
||||
setCurrentPosition(Math.floor(Math.random() * durationInSeconds))
|
||||
}
|
||||
setIsLoading(false)
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error fetching music data:", error)
|
||||
setIsLoading(false)
|
||||
})
|
||||
}, [timePeriod])
|
||||
|
||||
const handleNext = () => {
|
||||
setCurrentIndex((prevIndex) => {
|
||||
const nextIndex = (prevIndex + 1) % songs.length
|
||||
const durationInSeconds = parseDuration(songs[nextIndex].duration)
|
||||
setCurrentPosition(Math.floor(Math.random() * durationInSeconds))
|
||||
return nextIndex
|
||||
})
|
||||
}
|
||||
|
||||
const handlePrevious = () => {
|
||||
setCurrentIndex((prevIndex) => {
|
||||
const nextIndex = (prevIndex - 1 + songs.length) % songs.length
|
||||
const durationInSeconds = parseDuration(songs[nextIndex].duration)
|
||||
setCurrentPosition(Math.floor(Math.random() * durationInSeconds))
|
||||
return nextIndex
|
||||
})
|
||||
}
|
||||
|
||||
const parseDuration = (duration: string): number => {
|
||||
const [minutes, seconds] = duration.split(":").map(Number)
|
||||
return minutes * 60 + seconds
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<section id="music-carousel" className="mb-12">
|
||||
{isLoading && <LoadingSpinner />}
|
||||
|
||||
{!isLoading && songs.length > 0 && (
|
||||
<div className="relative">
|
||||
<Image
|
||||
src={songs[currentIndex].albumArt || "/placeholder.svg"}
|
||||
alt={songs[currentIndex].name}
|
||||
width={300}
|
||||
height={300}
|
||||
className="mb-4 rounded-lg"
|
||||
/>
|
||||
<h3 className="text-2xl font-bold text-gray-100">{songs[currentIndex].name}</h3>
|
||||
<p>{songs[currentIndex].artist}</p>
|
||||
<SeekBar
|
||||
key={`${currentIndex}-${currentPosition}`}
|
||||
startPos={currentPosition}
|
||||
duration={songs[currentIndex].duration}
|
||||
/>
|
||||
<div className="flex justify-center pb-2">
|
||||
<button onClick={handlePrevious} className="mr-4 cursor-pointer">
|
||||
<SkipBack className="w-8 h-8" />
|
||||
</button>
|
||||
<button className="mr-4 cursor-pointer" onClick={() => window.open(songs[currentIndex]?.link, "_blank")}>
|
||||
<Play className="w-8 h-8" />
|
||||
</button>
|
||||
<button onClick={handleNext} className="cursor-pointer">
|
||||
<SkipForward className="w-8 h-8" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="flex flex-col items-center mt-4">
|
||||
<label htmlFor="timePeriod" className="font-bold uppercase text-sm pb-1">
|
||||
Time Period
|
||||
</label>
|
||||
<select
|
||||
id="timePeriod"
|
||||
value={timePeriod}
|
||||
onChange={(e) => setTimePeriod(e.target.value)}
|
||||
className="px-3 py-2 bg-gray-700 rounded-sm mb-2"
|
||||
>
|
||||
<option value="Early Summer 2024">Early Summer 2024</option>
|
||||
</select>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue