add handling for non-github repos, fix hydration errors in header, use Link instead of <a>, move contact button to own component, migrate data folders, use music skip buttons for navigating songs on music by time, change icon in footer, update about page with gitea details, rename LastPlayed widget

This commit is contained in:
Aidan 2025-01-23 22:38:44 -05:00
parent 28d0cb4d63
commit 4ea774cca5
14 changed files with 128 additions and 128 deletions

View File

@ -1,12 +1,12 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faGithub } from '@fortawesome/free-brands-svg-icons'
import { faHeart } from '@fortawesome/free-solid-svg-icons';
export default function Footer() {
return (
<footer className="bg-gray-800 py-6">
<div className="container mx-auto px-4 text-center">
<a href="https://github.com/ihatenodejs/aidxnCC" target="_blank" rel="noopener noreferrer" className="text-gray-400 hover:text-white transition-colors">
<FontAwesomeIcon icon={faGithub} className="text-md mr-1" /> This website is free, open source and in the public domain.
<a href="https://git.pontusmail.org/aidan/aidxnCC" target="_blank" rel="noopener noreferrer" className="text-gray-400 hover:text-white transition-colors">
<FontAwesomeIcon icon={faHeart} className="text-md mr-1" /> This website is free, open source and in the public domain.
</a>
</div>
</footer>

View File

@ -14,12 +14,12 @@ interface NavItemProps {
}
const NavItem = ({ href, icon, children }: NavItemProps) => (
<li>
<div className="nav-item">
<Link href={href} className="flex items-center text-gray-300 hover:text-white hover:bg-gray-700 rounded-md px-3 py-2 transition-all duration-300">
<FontAwesomeIcon icon={icon} className="text-md mr-2" />
{children}
</Link>
</li>
</div>
);
export default function Header() {
@ -43,12 +43,12 @@ export default function Header() {
<NavItem href="/domains" icon={faLink}>Domains</NavItem>
<NavItem href="https://blog.aidxn.fun/" icon={faWordpressSimple}>Blog</NavItem>
<NavItem href="/music" icon={faMusic}>Music by Time</NavItem>
<li className="flex items-center">
<div className="flex items-center">
<NavItem href="https://tilde.club/~lxu" icon={faTerminal}>Tilde</NavItem>
<a href="https://tilde.wiki/Tildeverse" className="text-gray-300 hover:text-green-400 ml-1 text-sm" target="_blank" rel="noopener noreferrer">
<sup>what?</sup>
</a>
</li>
</div>
</ul>
</nav>
</header>

View File

@ -0,0 +1,26 @@
import { IconDefinition } from '@fortawesome/fontawesome-svg-core'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import Link from 'next/link';
interface ContactButtonProps {
href: string;
icon: IconDefinition;
label: string;
className?: string;
}
function ContactButton({ href, icon, label, className }: ContactButtonProps) {
return (
<Link
href={href}
target="_blank"
rel="noopener noreferrer"
className={`bg-gray-700 text-white px-4 py-2 rounded-full hover:bg-gray-600 transition-colors inline-flex items-center ${className}`}
>
<FontAwesomeIcon icon={icon} className="text-xl mr-2" />
{label}
</Link>
)
}
export default ContactButton;

View File

@ -2,9 +2,10 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faUser } from '@fortawesome/free-solid-svg-icons'
import GitHubFeatured from '../widgets/GitHubFeatured'
import FeaturedRepos from '../widgets/FeaturedRepos'
import Image from 'next/image'
import { useState } from 'react'
import Link from 'next/link'
export default function About() {
const [imageError, setImageError] = useState(false);
@ -28,12 +29,13 @@ export default function About() {
When I&apos;m not programming, I can typically be found installing another Linux distro on my laptop or flashing a new ROM to my phone. I am also a passionate writer and I like to write creatively in my free time.
</p>
<p className="text-gray-300">
I am almost always active on GitHub and make daily contributions to several of my repositories. I am a big fan of open source software and public domain software (which most of my repos are licensed under). In fact, the website you&apos;re currently on is free and open source. It&apos;s even under the public domain!
I am almost always active on <Link href="https://git.pontusmail.org/" className="text-blue-400 hover:underline">my Gitea instance</Link> and GitHub and make daily contributions to several of my repositories. I am a big fan of open source software and public domain software (which most of my repos are licensed under). In fact, the website you&apos;re currently on is free and open source. It&apos;s even under the public domain!
</p>
</div>
<div className="mt-12">
<h2 className="text-2xl font-semibold mb-4 text-gray-200">My GitHub Contributions</h2>
<p className="text-gray-300 mb-4">You can find me on GitHub as <a href="https://github.com/ihatenodejs/" className="text-blue-400 hover:underline">ihatenodejs</a>.</p>
<h2 className="text-2xl font-semibold mb-4 text-gray-200">My Gitea/GitHub Contributions</h2>
<p className="text-gray-300 mb-4">Most of my repositories have migrated to <Link href="https://git.pontusmail.org/" className="text-blue-400 hover:underline">LibreCloud Git</Link>. My username is <Link href="https://git.pontusmail.org/aidan/" className="text-blue-400 hover:underline">aidan</Link>.</p>
<p className="text-gray-300 mb-4">You can find me on GitHub as <Link href="https://github.com/ihatenodejs/" className="text-blue-400 hover:underline">ihatenodejs</Link>.</p>
{!imageError && (
<div className="flex flex-col md:flex-row justify-center gap-4">
<Image
@ -63,8 +65,8 @@ export default function About() {
</div>
<div className="mt-12">
<h2 className="text-2xl font-semibold mb-4 text-gray-200">Featured Projects</h2>
<p className="text-gray-300 mb-6">Here&apos;s just four of my top projects.</p>
<GitHubFeatured />
<p className="text-gray-300 mb-6">Here&apos;s just four of my top projects. Star and fork counts are manually updated and count both Gitea and GitHub.</p>
<FeaturedRepos />
</div>
</div>
)

View File

@ -1,7 +1,7 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faPhone, faEnvelope } from '@fortawesome/free-solid-svg-icons'
import { faGithub, faTelegram } from '@fortawesome/free-brands-svg-icons'
import { IconDefinition } from '@fortawesome/fontawesome-svg-core'
import ContactButton from '../objects/ContactButton'
export default function Contact() {
return (
@ -35,24 +35,3 @@ export default function Contact() {
</div>
)
}
interface ContactButtonProps {
href: string;
icon: IconDefinition;
label: string;
className?: string;
}
function ContactButton({ href, icon, label, className }: ContactButtonProps) {
return (
<a
href={href}
target="_blank"
rel="noopener noreferrer"
className={`bg-gray-700 text-white px-4 py-2 rounded-full hover:bg-gray-600 transition-colors inline-flex items-center ${className}`}
>
<FontAwesomeIcon icon={icon} className="text-xl mr-2" />
{label}
</a>
)
}

View File

@ -1,6 +1,6 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faLink } from '@fortawesome/free-solid-svg-icons'
import domains from '../../data/domains.json'
import domains from '../../../public/data/domains.json'
export default function About() {
return (

View File

@ -40,6 +40,9 @@ export default function Home() {
<p className="text-gray-300 leading-relaxed mt-2">
I&apos;m most proud of LibreCloud/p0ntus mail, which is a cloud services provider that I self-host and maintain, free of charge.
</p>
<p className="text-gray-300 leading-relaxed mt-2">
I frequently write and work on a website hosted on a public Linux server, called a &quot;tilde.&quot; You can check it out by clicking the link &quot;Tilde&quot; in the header, or &quot;what?&quot; if you are still confused!
</p>
</section>
<section id="contact">

View File

@ -1,7 +1,8 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faGithub } from '@fortawesome/free-brands-svg-icons'
import { faGitAlt, faGithub } from '@fortawesome/free-brands-svg-icons'
import { faStar, faCodeBranch } from '@fortawesome/free-solid-svg-icons'
import featuredProjects from '../../data/featured.json'
import featuredProjects from '../../../public/data/featured.json'
import Link from 'next/link'
export default function GitHubFeatured() {
return (
@ -10,12 +11,12 @@ export default function GitHubFeatured() {
<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={faGithub} className="mr-2" /> {project.name}
<FontAwesomeIcon icon={project.github ? faGithub : faGitAlt} className="mr-2" /> {project.name}
</h3>
<p className="text-gray-300 flex-grow">{project.description}</p>
</div>
<div className="pt-4 border-t border-gray-700 flex justify-between items-center mt-auto">
<a href={project.url} className="text-blue-400 hover:underline">View Repo</a>
<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}

View File

@ -15,7 +15,7 @@ interface Track {
'@attr'?: { nowplaying: string };
}
const NowPlaying: React.FC = () => {
const LastPlayed: React.FC = () => {
const [track, setTrack] = useState<Track | null>(null);
const apiUrl = process.env.LASTFM_API_URL || 'https://lastfm-last-played.biancarosa.com.br/aidxn_/latest-song';
@ -29,7 +29,7 @@ const NowPlaying: React.FC = () => {
if (!track) {
return (
<div className="max-w-2xl mx-auto mt-4">
<h2 className="text-2xl font-bold mb-4 pt-10 text-gray-200">Music</h2>
<h2 className="text-2xl font-bold mb-4 pt-10 text-gray-200">Last Played Song</h2>
<div className="flex justify-center items-center border border-gray-300 rounded-lg p-4 max-w-md mt-8">
<span className="spinner-border animate-spin inline-block w-8 h-8 border-4 rounded-full" role="status"></span>
</div>
@ -39,7 +39,7 @@ const NowPlaying: React.FC = () => {
return (
<div className="max-w-2xl mx-auto mt-4">
<h2 className="text-2xl font-bold mb-4 pt-10 text-gray-200">Music</h2>
<h2 className="text-2xl font-bold mb-4 pt-10 text-gray-200">Last Played Song</h2>
<div className="now-playing flex items-center border border-gray-300 rounded-lg p-4 max-w-md mt-8 bg-white bg-opacity-10 backdrop-filter backdrop-blur-lg">
<Image
src={track.image.find(img => img.size === 'large')?.['#text'] || '/placeholder.png'}
@ -61,4 +61,4 @@ const NowPlaying: React.FC = () => {
);
};
export default NowPlaying;
export default LastPlayed;

View File

@ -2,7 +2,7 @@
import { useState, useEffect } from 'react';
import Image from 'next/image';
import { Play, SkipBack, SkipForward, ChevronLeft, ChevronRight } from 'lucide-react';
import { Play, SkipBack, SkipForward } from 'lucide-react';
import LoadingSpinner from '../objects/LoadingSpinner';
interface Song {
@ -19,7 +19,7 @@ interface Period {
}
export default function Home() {
const [timePeriod, setTimePeriod] = useState('Summer 2024');
const [timePeriod, setTimePeriod] = useState('Early Summer 2024');
const [songs, setSongs] = useState<Song[]>([]);
const [currentIndex, setCurrentIndex] = useState(0);
const [isLoading, setIsLoading] = useState(true);
@ -61,7 +61,7 @@ export default function Home() {
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>
<option value="Early Summer 2024">Early Summer 2024</option>
</select>
</div>
@ -69,10 +69,6 @@ export default function Home() {
{!isLoading && songs.length > 0 && (
<div className="relative">
<button onClick={handlePrevious} className="absolute left-0 top-1/2 transform -translate-y-1/2 text-gray-300">
<ChevronLeft className="w-8 h-8" />
</button>
<div className="text-center">
<Image
src={songs[currentIndex].albumArt}
@ -85,21 +81,17 @@ export default function Home() {
<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">
<button onClick={handlePrevious} className="mr-4 text-gray-300">
<SkipBack className="w-8 h-8" />
</button>
<button className="mr-4 text-gray-300" onClick={() => window.open(songs[currentIndex]?.link, '_blank')}>
<Play className="w-8 h-8" />
</button>
<button className="text-gray-300">
<button onClick={handleNext} className="text-gray-300">
<SkipForward className="w-8 h-8" />
</button>
</div>
</div>
<button onClick={handleNext} className="absolute right-0 top-1/2 transform -translate-y-1/2 text-gray-300">
<ChevronRight className="w-8 h-8" />
</button>
</div>
)}
</section>

View File

@ -1,7 +1,7 @@
import Header from './components/Header';
import HomePg from './components/pages/Home';
import Footer from './components/Footer';
import NowPlaying from './components/widgets/NowPlaying';
import LastPlayed from './components/widgets/LastPlayed';
export default function Home() {
return (
@ -9,7 +9,7 @@ export default function Home() {
<Header />
<main className="flex-grow container mx-auto px-4 py-12">
<HomePg />
<NowPlaying />
<LastPlayed />
</main>
<Footer />
</div>

View File

@ -3,32 +3,36 @@
"id": 1,
"name": "aidxnCC",
"description": "aidxnCC is the third version of my personal website",
"url": "https://github.com/ihatenodejs/aidxnCC",
"stars": 1,
"github": false,
"url": "https://git.pontusmail.org/aidan/aidxnCC",
"stars": 2,
"forks": 1
},
{
"id": 2,
"name": "pontus-mail",
"description": "Landing page for p0ntus mail",
"url": "https://github.com/ihatenodejs/pontus-mail",
"stars": 7,
"github": false,
"url": "https://git.pontusmail.org/aidan/pontus-mail",
"stars": 8,
"forks": 0
},
{
"id": 3,
"name": "modules",
"description": "An open-source Magisk module and FOSS app store",
"url": "https://github.com/ihatenodejs/modules",
"stars": 2,
"github": false,
"url": "https://git.pontusmail.org/aidan/modules",
"stars": 3,
"forks": 0
},
{
"id": 4,
"name": "AndroidIntegrity/website",
"description": "AIA website source code",
"github": true,
"url": "https://github.com/AndroidIntegrity/website",
"stars": 5,
"stars": 6,
"forks": 1
}
]

View File

@ -1,63 +1,56 @@
[
{
"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"
},
{
"albumArt": "https://p0ntus.com/archives/img/nani.webp",
"name": "NANi",
"artist": "Saweetie",
"duration": "2:34",
"link": "https://www.last.fm/music/Saweetie/Nani"
},
{
"albumArt": "https://p0ntus.com/archives/img/nani.webp",
"name": "NANi",
"artist": "Saweetie",
"duration": "2:34",
"link": "https://www.last.fm/music/Saweetie/Nani"
},
{
"albumArt": "https://p0ntus.com/archives/img/killerloverboy.webp",
"name": "killer lover boy",
"artist": "SEB",
"duration": "2:14",
"link": "https://www.last.fm/music/Seb/_/killer+lover+boy"
}
]
}
]
{
"timePeriod": "Early 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"
},
{
"albumArt": "https://p0ntus.com/archives/img/nani.webp",
"name": "NANi",
"artist": "Saweetie",
"duration": "2:34",
"link": "https://www.last.fm/music/Saweetie/Nani"
},
{
"albumArt": "https://p0ntus.com/archives/img/killerloverboy.webp",
"name": "killer lover boy",
"artist": "SEB",
"duration": "2:14",
"link": "https://www.last.fm/music/Seb/_/killer+lover+boy"
}
]
}
]