add radio page
This commit is contained in:
Generated
+4
-4
@@ -18,7 +18,7 @@
|
||||
"@trpc/react-query": "^10.37.1",
|
||||
"@trpc/server": "^10.37.1",
|
||||
"axios": "^1.6.2",
|
||||
"grommet-icons": "^4.11.0",
|
||||
"grommet-icons": "^4.12.1",
|
||||
"next": "^13.5.4",
|
||||
"next-auth": "^4.23.0",
|
||||
"react": "18.2.0",
|
||||
@@ -2729,9 +2729,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/grommet-icons": {
|
||||
"version": "4.11.0",
|
||||
"resolved": "https://registry.npmjs.org/grommet-icons/-/grommet-icons-4.11.0.tgz",
|
||||
"integrity": "sha512-ArXf2XyXmpk5JsQ8NudzNz3mbWv+TeZkPiyog2s9yoNAWTlIr3vzNjr97uon/Xm4Uiq2kiHkvO4i2fG1u6EaDg==",
|
||||
"version": "4.12.1",
|
||||
"resolved": "https://registry.npmjs.org/grommet-icons/-/grommet-icons-4.12.1.tgz",
|
||||
"integrity": "sha512-LhOP6BkDAGiSNcUOfsGGRo+AKD6zWOXeNeusY1WYvKplAR6mKCAQfH7Nig2Buc/v5zadKSko2NDtCQqwJaME0Q==",
|
||||
"peerDependencies": {
|
||||
"react": "^16.6.0 || ^17.0.0 || ^18.0.0",
|
||||
"react-dom": "^16.6.0 || ^17.0.0 || ^18.0.0",
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@
|
||||
"@trpc/react-query": "^10.37.1",
|
||||
"@trpc/server": "^10.37.1",
|
||||
"axios": "^1.6.2",
|
||||
"grommet-icons": "^4.11.0",
|
||||
"grommet-icons": "^4.12.1",
|
||||
"next": "^13.5.4",
|
||||
"next-auth": "^4.23.0",
|
||||
"react": "18.2.0",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
export default function Footer() {
|
||||
return (
|
||||
<>
|
||||
<div className="relative rounded-t-sm p-2 text-white opacity-50">
|
||||
<div className="absolute bottom-0 rounded-t-sm p-2 text-white opacity-50">
|
||||
<p className="text-center">
|
||||
The 'PipBoy' is owned by Bethesda, I'm just doing this for fun!
|
||||
</p>
|
||||
|
||||
@@ -9,14 +9,15 @@ export default function Header({
|
||||
}: HeaderProps) {
|
||||
return (
|
||||
<>
|
||||
<div className="text-white max-w-sm mx-auto pt-2 pb-4">
|
||||
<div className="inline-block pb-2 space-x-6 text-center">
|
||||
<div className="text-white max-w-md mx-auto pt-2 pb-4 text-center">
|
||||
<div className="inline-block pb-2 space-x-6">
|
||||
<HeaderItem content="HOME" linkTo={
|
||||
isNotHomePage ? "/?noAnimation"
|
||||
: "/"
|
||||
} />
|
||||
<HeaderItem content="LINKS" linkTo="/links" />
|
||||
<HeaderItem content="PROJECTS" linkTo="/projects" />
|
||||
<HeaderItem content="RADIO" linkTo="/radio" />
|
||||
<HeaderItem content="ABOUT" linkTo="/about" />
|
||||
</div>
|
||||
<hr className="border-green-500" />
|
||||
|
||||
+39
-7
@@ -2,25 +2,57 @@ import RootLayout from "@/components/RootLayout";
|
||||
import Footer from "@/components/footer";
|
||||
import Header from "@/components/header";
|
||||
import Link from "next/link";
|
||||
import {useState} from 'react';
|
||||
|
||||
// icons
|
||||
import {
|
||||
Twitter,
|
||||
MailOption
|
||||
} from 'grommet-icons'
|
||||
|
||||
export default function LinksPage() {
|
||||
const [icon, setIcon] = useState<Element | null>();
|
||||
|
||||
return (
|
||||
<RootLayout>
|
||||
<Header isNotHomePage={true} />
|
||||
<div className="text-green-500 text-center">
|
||||
<h1 className="font-bold text-3xl">My Links!</h1>
|
||||
<div className="space-y-2">
|
||||
<Link href="https://twitter.com/avvex__" target="_blank">
|
||||
<div className="text-green-500 max-h-96">
|
||||
<h1 className="font-bold text-3xl ml-2">My Links!</h1>
|
||||
<div className="space-y-2 float-left">
|
||||
<Link
|
||||
href="https://twitter.com/avvex__"
|
||||
target="_blank"
|
||||
onMouseOver={() => {
|
||||
setIcon(<Twitter size="large" />)
|
||||
}}
|
||||
onMouseLeave={() => {
|
||||
setIcon(null)
|
||||
}}
|
||||
>
|
||||
<div className="hover:bg-green-500 hover:text-black">
|
||||
<h1 className="text-2xl mx-32">Twitter</h1>
|
||||
<h1 className="text-2xl mr-32 ml-2">Twitter</h1>
|
||||
</div>
|
||||
</Link>
|
||||
<Link href="https://mast.thatalex.dev/@alex" target="_blank">
|
||||
<Link
|
||||
href="https://mast.thatalex.dev/@alex"
|
||||
target="_blank"
|
||||
onMouseOver={() => {
|
||||
setIcon(<MailOption size="large" />)
|
||||
}}
|
||||
onMouseLeave={() => {
|
||||
setIcon(null)
|
||||
}}
|
||||
>
|
||||
<div className="hover:bg-green-500 hover:text-black">
|
||||
<h1 className="text-2xl mx-32">Mastodon</h1>
|
||||
<h1 className="text-2xl mr-32 ml-2">Mastodon</h1>
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="float-right">
|
||||
{/* <Twitter size='xlarge' className="mr-24" /> */}
|
||||
{icon}
|
||||
</div>
|
||||
</div>
|
||||
<Footer />
|
||||
</RootLayout>
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
import RootLayout from "@/components/RootLayout";
|
||||
import Footer from "@/components/footer";
|
||||
import Header from "@/components/header";
|
||||
import { api } from "@/utils/api";
|
||||
|
||||
// next components
|
||||
import Link from 'next/link';
|
||||
import Image from "next/image";
|
||||
|
||||
export default function MusicPage() {
|
||||
const { data: musicData, fetchStatus} = api.misc.song.useQuery();
|
||||
|
||||
return (
|
||||
<RootLayout>
|
||||
<Header isNotHomePage={true} />
|
||||
<div className="text-green-500 flicker max-w-1/2">
|
||||
<div className="float-left">
|
||||
{
|
||||
fetchStatus === "idle" ?
|
||||
musicData?.data.tracks.map((v,k) => {
|
||||
return <div key={k}>
|
||||
<div className={`text-lg ${k === 0 ? "bg-green-500 text-black" : "hover:bg-green-500 hover:text-black"}`}>
|
||||
<Link href={v.url} target="_blank">
|
||||
<h1 className="ml-2 mr-36 truncate max-w-10">{k === 0 && "■"} {v.name}</h1>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
})
|
||||
: <h1 className="font-bold text-green-500">Fetching..</h1>
|
||||
}
|
||||
</div>
|
||||
<div className="float-right">
|
||||
{
|
||||
fetchStatus === "idle" &&
|
||||
<Image
|
||||
src={musicData?.data.tracks[0]?.image[2]?.["#text"] ?? "https://storage.thatalex.dev"}
|
||||
alt="Cover Art"
|
||||
width="160"
|
||||
height="160"
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<Footer />
|
||||
</RootLayout>
|
||||
)
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import { postRouter } from "@/server/api/routers/post";
|
||||
import { linksRouter } from "./routers/links";
|
||||
import { blogRouter } from "./routers/blog";
|
||||
import { miscRouter } from "./routers/misc";
|
||||
import { createTRPCRouter } from "@/server/api/trpc";
|
||||
|
||||
/**
|
||||
@@ -11,7 +12,8 @@ import { createTRPCRouter } from "@/server/api/trpc";
|
||||
export const appRouter = createTRPCRouter({
|
||||
post: postRouter,
|
||||
links: linksRouter,
|
||||
blog: blogRouter
|
||||
blog: blogRouter,
|
||||
misc: miscRouter
|
||||
});
|
||||
|
||||
// export type definition of API
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
import axios from 'axios';
|
||||
import {
|
||||
createTRPCRouter,
|
||||
publicProcedure
|
||||
} from '@/server/api/trpc';
|
||||
|
||||
type ImageListType = {
|
||||
"size": string,
|
||||
"#text": string
|
||||
}
|
||||
|
||||
type TrackResponseType = {
|
||||
status: number,
|
||||
data: {
|
||||
tracks: LastTrackType[]
|
||||
}
|
||||
}
|
||||
|
||||
type LastTrackType = {
|
||||
"@attr": {
|
||||
"nowplaying": string
|
||||
},
|
||||
"album": {
|
||||
"mbid": string,
|
||||
"#text": string
|
||||
},
|
||||
"artist": {
|
||||
"mbid": string,
|
||||
"#text": string,
|
||||
},
|
||||
"image": ImageListType[],
|
||||
"mbid": string,
|
||||
"name": string,
|
||||
"streamable": number,
|
||||
"url": string
|
||||
}
|
||||
|
||||
export const miscRouter = createTRPCRouter({
|
||||
song: publicProcedure
|
||||
.query(async () => {
|
||||
const response = await axios.get<TrackResponseType>("https://api.thatalex.dev/v4/social/music")
|
||||
return response.data
|
||||
}),
|
||||
})
|
||||
Reference in New Issue
Block a user