add some new fun things
This commit is contained in:
@@ -2,8 +2,8 @@ import type { ReactNode } from "react";
|
|||||||
|
|
||||||
export default function Layout({ children }: { children: ReactNode }) {
|
export default function Layout({ children }: { children: ReactNode }) {
|
||||||
return (
|
return (
|
||||||
<div className="bg-black text-white min-h-screen flex flex-col items-center sm:justify-center mx-auto select-none">
|
<div className="bg-black text-white min-h-screen select-none">
|
||||||
<div className="w-full sm:w-[500px] relative">{children}</div>
|
<div className="relative">{children}</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,10 +8,16 @@ export default function Overlay({
|
|||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<div
|
// <div onClick={onClose} className="fixed bg-black/50">
|
||||||
onClick={onClose}
|
// <p
|
||||||
className="absolute bg-black/50 w-full h-full z-1 overflow-hidden flex justify-center items-center"
|
// onClick={onClose}
|
||||||
>
|
// className="absolute text-2xl font-bold top-4 right-4 bg-white text-black rounded-full p-2"
|
||||||
|
// >
|
||||||
|
// X
|
||||||
|
// </p>
|
||||||
|
// {children}
|
||||||
|
// </div>
|
||||||
|
<div onClick={onClose} className="fixed bg-black/50 w-full h-full z-1">
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import ScrollingText from "./ScrollingText";
|
import ScrollingText from "../ScrollingText";
|
||||||
import type { LastFMMusicObject } from "../utils/types";
|
import type { LastFMMusicObject } from "../../utils/types";
|
||||||
|
|
||||||
export default function MusicComponent() {
|
export default function MusicComponent() {
|
||||||
const [music, setMusic] = useState<LastFMMusicObject | null>(null);
|
const [music, setMusic] = useState<LastFMMusicObject | null>(null);
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useEffect, useRef } from "react";
|
import { useEffect, useRef } from "react";
|
||||||
|
|
||||||
export default function Countdown() {
|
export default function CountdownModule() {
|
||||||
const countdownRef = useRef<HTMLParagraphElement | null>(null);
|
const countdownRef = useRef<HTMLParagraphElement | null>(null);
|
||||||
const audioRef = useRef<HTMLAudioElement | null>(null);
|
const audioRef = useRef<HTMLAudioElement | null>(null);
|
||||||
|
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
import MusicComponent from "../info/MusicComponent";
|
||||||
|
import TVComponent from "../info/TVComponent";
|
||||||
|
|
||||||
|
export default function InfoModule() {
|
||||||
|
return (
|
||||||
|
<div className="border border-white border-solid rounded-lg p-2">
|
||||||
|
<div className="flex flex-wrap justify-between p-2 space-y-2">
|
||||||
|
<div>
|
||||||
|
<h1 className="text-2xl font-bold italic opacity-95">alex, 18</h1>
|
||||||
|
<img
|
||||||
|
src="https://storage.alexav.gg/content/6d87f5ac-e7f0-413c-84a6-6838e590b7d9.png"
|
||||||
|
className="rounded-md w-[150px] h-[110px] object-cover object-left-top"
|
||||||
|
alt="Profile"
|
||||||
|
/>
|
||||||
|
<div className="pt-2">
|
||||||
|
<MusicComponent />
|
||||||
|
<a
|
||||||
|
href="https://last.fm/user/lulawex"
|
||||||
|
target="_blank"
|
||||||
|
className="hover:underline w-fit opacity-50"
|
||||||
|
>
|
||||||
|
powered by last.fm
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h1 className="font-bold text-2xl italic">what i do</h1>
|
||||||
|
<p>
|
||||||
|
qa @{" "}
|
||||||
|
<a
|
||||||
|
href="https://medal.tv"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="hover:underline text-[#bff83e]"
|
||||||
|
>
|
||||||
|
medal.tv
|
||||||
|
</a>
|
||||||
|
, game, code
|
||||||
|
</p>
|
||||||
|
<h1
|
||||||
|
className="italic opacity-50 font-semibold underline"
|
||||||
|
onClick={() => navigator.clipboard.writeText("alex@vierfrantz.com")}
|
||||||
|
>
|
||||||
|
alex@vierfrantz.com
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<hr className="my-2" />
|
||||||
|
|
||||||
|
<h1 className="font-bold text-2xl italic">obsessed with</h1>
|
||||||
|
<p>dexter, tlou, twd</p>
|
||||||
|
|
||||||
|
<hr className="my-2" />
|
||||||
|
|
||||||
|
<h1 className="font-bold text-2xl italic">status</h1>
|
||||||
|
<TVComponent />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { BillsScore, SabresScore } from "../../utils/types";
|
||||||
|
|
||||||
|
const IMAGES = {
|
||||||
|
bills: "https://storage.alexav.gg/content/bills.png",
|
||||||
|
sabres: "https://storage.alexav.gg/content/sabres.png",
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function ScoreModule({ type }: { type: "sabres" | "bills" }) {
|
||||||
|
const [billsScore, setBillsScore] = useState<BillsScore | null>(null);
|
||||||
|
const [sabresScore, setSabresScore] = useState<SabresScore | null>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
async function fetchBillsScore() {
|
||||||
|
const res = await fetch("https://api.alexav.gg/v4/scores/bills");
|
||||||
|
if (res.ok) {
|
||||||
|
const data = await res.json();
|
||||||
|
setBillsScore(data);
|
||||||
|
} else {
|
||||||
|
console.error("Failed to fetch Bills score; " + res.statusText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async function fetchSabresScore() {
|
||||||
|
const res = await fetch("https://api.alexav.gg/v4/scores/sabres");
|
||||||
|
if (res.ok) {
|
||||||
|
const data = await res.json();
|
||||||
|
setSabresScore(data);
|
||||||
|
} else {
|
||||||
|
console.error("Failed to fetch Sabresscore; " + res.statusText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == "bills" && !billsScore) {
|
||||||
|
fetchBillsScore();
|
||||||
|
} else if (type === "sabres" && !sabresScore) {
|
||||||
|
fetchSabresScore();
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="border border-white border-solid rounded-lg w-full sm:w-[500px] mb-4">
|
||||||
|
<div className="flex justify-between">
|
||||||
|
<div>
|
||||||
|
<img width="100" className="p-4" src={IMAGES[type]} />
|
||||||
|
</div>
|
||||||
|
<div className="flex justify-center items-center px-6">
|
||||||
|
<div>
|
||||||
|
<h1 className="text-2xl">
|
||||||
|
{type === "bills"
|
||||||
|
? billsScore?.name
|
||||||
|
: `${sabresScore?.awayTeam.abbrev} @ ${sabresScore?.homeTeam.abbrev}`}
|
||||||
|
</h1>
|
||||||
|
<p className="float-right text-[20px]">
|
||||||
|
{type === "bills"
|
||||||
|
? billsScore?.score
|
||||||
|
: `${sabresScore && sabresScore?.sabresScore > sabresScore?.oppScore ? "W" : "L"} ${sabresScore?.sabresScore}-${sabresScore?.oppScore}`}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
export default function WelcomeModule() {
|
||||||
|
return (
|
||||||
|
<div className="border border-white border-solid p-2 rounded-lg flex justify-between w-full">
|
||||||
|
<h1 className="text-2xl font-bold">welcome to my site !</h1>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
+28
-73
@@ -1,11 +1,12 @@
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import Layout from "../components/Layout";
|
import Layout from "../components/Layout";
|
||||||
import Overlay from "../components/Overlay";
|
import Overlay from "../components/Overlay";
|
||||||
import MusicComponent from "../components/MusicComponent";
|
import GameComponent from "../components/info/GameComponent";
|
||||||
import TVComponent from "../components/TVComponent";
|
|
||||||
import GameComponent from "../components/GameComponent";
|
|
||||||
import FantasyStatus from "../components/FantasyStatus";
|
|
||||||
import PictureCarousel from "../components/modules/PictureCarousel";
|
import PictureCarousel from "../components/modules/PictureCarousel";
|
||||||
|
import InfoModule from "../components/modules/InfoModule";
|
||||||
|
import WelcomeModule from "../components/modules/WelcomeModule";
|
||||||
|
import FantasyStatus from "../components/FantasyStatus";
|
||||||
|
import ScoreModule from "../components/modules/ScoreModule";
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
const [selectedImage, setSelectedImage] = useState<string>("");
|
const [selectedImage, setSelectedImage] = useState<string>("");
|
||||||
@@ -14,80 +15,34 @@ export default function App() {
|
|||||||
<Layout>
|
<Layout>
|
||||||
{selectedImage !== "" && (
|
{selectedImage !== "" && (
|
||||||
<Overlay onClose={() => setSelectedImage("")}>
|
<Overlay onClose={() => setSelectedImage("")}>
|
||||||
<img
|
<div className="flex justify-center items-center w-full h-full">
|
||||||
draggable={false}
|
<img
|
||||||
className="select-none"
|
draggable={false}
|
||||||
width="400"
|
className="select-none"
|
||||||
height="400"
|
width="400"
|
||||||
src={selectedImage}
|
height="400"
|
||||||
/>
|
src={selectedImage}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</Overlay>
|
</Overlay>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="my-2 space-y-4">
|
<div className="my-2 flex flex-col items-center sm:justify-center">
|
||||||
<PictureCarousel onClick={(url) => setSelectedImage(url)} />
|
<div className="space-y-4 sm:w-[500px]">
|
||||||
|
<img
|
||||||
|
className="rounded-lg"
|
||||||
|
src={
|
||||||
|
"https://storage.alexav.gg/content/55f3eca0-a5a9-4c71-9d92-ba5d669a7a0c.jpg"
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
<div className="border border-white border-solid p-2 rounded-lg flex justify-between">
|
<WelcomeModule />
|
||||||
<h1 className="text-2xl font-bold">welcome to my site !</h1>
|
<InfoModule />
|
||||||
|
<PictureCarousel onClick={(url) => setSelectedImage(url)} />
|
||||||
|
<GameComponent />
|
||||||
|
<ScoreModule type={"bills"} />
|
||||||
|
<FantasyStatus />
|
||||||
</div>
|
</div>
|
||||||
<GameComponent />
|
|
||||||
|
|
||||||
<div className="border border-white border-solid rounded-lg p-2">
|
|
||||||
<div className="flex flex-wrap justify-between p-2 space-y-2">
|
|
||||||
<div>
|
|
||||||
<h1 className="text-2xl font-bold italic opacity-95">alex, 18</h1>
|
|
||||||
<img
|
|
||||||
src="https://storage.alexav.gg/content/yeehaw.jpg"
|
|
||||||
className="rounded-md w-[150px] h-[110px] object-cover object-left-top"
|
|
||||||
alt="Profile"
|
|
||||||
/>
|
|
||||||
<div className="pt-2">
|
|
||||||
<MusicComponent />
|
|
||||||
<a
|
|
||||||
href="https://last.fm/user/lulawex"
|
|
||||||
target="_blank"
|
|
||||||
className="hover:underline w-fit opacity-50"
|
|
||||||
>
|
|
||||||
powered by last.fm
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<h1 className="font-bold text-2xl italic">what i do</h1>
|
|
||||||
<p>
|
|
||||||
qa @{" "}
|
|
||||||
<a
|
|
||||||
href="https://medal.tv"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
className="hover:underline text-[#bff83e]"
|
|
||||||
>
|
|
||||||
medal.tv
|
|
||||||
</a>
|
|
||||||
, game, code
|
|
||||||
</p>
|
|
||||||
<h1
|
|
||||||
className="italic opacity-50 font-semibold underline"
|
|
||||||
onClick={() =>
|
|
||||||
navigator.clipboard.writeText("alex@vierfrantz.com")
|
|
||||||
}
|
|
||||||
>
|
|
||||||
alex@vierfrantz.com
|
|
||||||
</h1>
|
|
||||||
|
|
||||||
<hr className="my-2" />
|
|
||||||
|
|
||||||
<h1 className="font-bold text-2xl italic">obsessed with</h1>
|
|
||||||
<p>dexter, tlou, twd</p>
|
|
||||||
|
|
||||||
<hr className="my-2" />
|
|
||||||
|
|
||||||
<h1 className="font-bold text-2xl italic">status</h1>
|
|
||||||
<TVComponent />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<FantasyStatus />
|
|
||||||
</div>
|
</div>
|
||||||
</Layout>
|
</Layout>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -46,6 +46,38 @@ interface SleeperUser {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// scores
|
||||||
|
type BillsScore = {
|
||||||
|
name: string;
|
||||||
|
date: string;
|
||||||
|
score: string;
|
||||||
|
};
|
||||||
|
type SabresScore = {
|
||||||
|
gameDate: string;
|
||||||
|
wonInRegulation: boolean;
|
||||||
|
sabresScore: number;
|
||||||
|
oppScore: number;
|
||||||
|
homeTeam: NHLTeam;
|
||||||
|
awayTeam: NHLTeam;
|
||||||
|
};
|
||||||
|
type NHLTeam = {
|
||||||
|
id: number;
|
||||||
|
name: {
|
||||||
|
default: string;
|
||||||
|
fr: string;
|
||||||
|
};
|
||||||
|
commonName: {
|
||||||
|
default: string;
|
||||||
|
};
|
||||||
|
placeNameWithPreposition: {
|
||||||
|
default: string;
|
||||||
|
fr: string;
|
||||||
|
};
|
||||||
|
abbrev: string;
|
||||||
|
score: number;
|
||||||
|
logo: string;
|
||||||
|
};
|
||||||
|
|
||||||
export type {
|
export type {
|
||||||
LastFMMusicObject,
|
LastFMMusicObject,
|
||||||
LastFMImageObject,
|
LastFMImageObject,
|
||||||
@@ -54,4 +86,6 @@ export type {
|
|||||||
SleeperUser,
|
SleeperUser,
|
||||||
NFLAPIData,
|
NFLAPIData,
|
||||||
NFLPlayer,
|
NFLPlayer,
|
||||||
|
BillsScore,
|
||||||
|
SabresScore,
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user