new site
This commit is contained in:
@@ -1,9 +1,5 @@
|
|||||||
@import "tailwindcss";
|
@import "tailwindcss";
|
||||||
|
|
||||||
@theme {
|
|
||||||
--breakpoint-xs: 400px;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
body {
|
||||||
font-family: 'Pathway Gothic One', sans-serif;
|
font-family: 'Pathway Gothic One', sans-serif;
|
||||||
background-color: black;
|
background-color: black;
|
||||||
@@ -18,27 +14,4 @@ body {
|
|||||||
background-color:gray;
|
background-color:gray;
|
||||||
border-radius: var(--radius-lg);
|
border-radius: var(--radius-lg);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.marquee {
|
|
||||||
overflow: hidden;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.marquee-content {
|
|
||||||
display: inline-block;
|
|
||||||
animation: scroll 10s linear infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
.marquee-content span {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes scroll {
|
|
||||||
0% {
|
|
||||||
transform: translateX(0);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: translateX(-50%);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
export default function ErrorState({
|
||||||
|
type = "error",
|
||||||
|
}: {
|
||||||
|
type: "error" | "loading" | "unavailable";
|
||||||
|
}) {
|
||||||
|
if (type === "error") {
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col bg-black border border-black text-white">
|
||||||
|
<div className="px-2">
|
||||||
|
<h1 className="text-lg font-semibold">uh oh :(</h1>
|
||||||
|
<p>something went wrong loading this stat</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
} else if (type === "loading") {
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col bg-black border border-black text-white">
|
||||||
|
<div className="px-2">
|
||||||
|
<h1 className="text-lg font-semibold">loading..</h1>
|
||||||
|
<p>hang tight..</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
} else if (type === "unavailable") {
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col bg-black border border-black text-white">
|
||||||
|
<div className="px-2">
|
||||||
|
<h1 className="text-lg font-semibold">nothing here :(</h1>
|
||||||
|
<p>no game launched recently</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,17 +4,17 @@ import { TeamRow } from "./fantasy/TeamRow";
|
|||||||
|
|
||||||
export default function FantasyStatus() {
|
export default function FantasyStatus() {
|
||||||
const [personalRoster, setPersonalRoster] = useState<NFLMatchupState | null>(
|
const [personalRoster, setPersonalRoster] = useState<NFLMatchupState | null>(
|
||||||
null
|
null,
|
||||||
);
|
);
|
||||||
const [opposingRoster, setOpposingRoster] = useState<NFLMatchupState | null>(
|
const [opposingRoster, setOpposingRoster] = useState<NFLMatchupState | null>(
|
||||||
null
|
null,
|
||||||
);
|
);
|
||||||
|
|
||||||
// fetch roster information
|
// fetch roster information
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function fetchData() {
|
async function fetchData() {
|
||||||
const data = (await fetch("https://api.alexav.gg/v4/football").then(
|
const data = (await fetch("https://api.alexav.gg/v4/football").then(
|
||||||
(res) => res.json()
|
(res) => res.json(),
|
||||||
)) as NFLAPIData;
|
)) as NFLAPIData;
|
||||||
|
|
||||||
// rosters
|
// rosters
|
||||||
@@ -35,12 +35,12 @@ export default function FantasyStatus() {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="border border-white border-solid rounded-lg w-full p-2">
|
<div className="p-2 text-black">
|
||||||
<div className="mb-4 space-y-4">
|
<div className="mb-4 space-y-4">
|
||||||
<a
|
<a
|
||||||
href="https://sleeper.com/leagues/1263620000418119680/matchup"
|
href="https://sleeper.com/leagues/1263620000418119680/matchup"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
className="underline"
|
className="hover:underline"
|
||||||
>
|
>
|
||||||
<h1 className="font-semibold text-2xl mb-2">fantasy</h1>
|
<h1 className="font-semibold text-2xl mb-2">fantasy</h1>
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ 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 select-none">
|
<div className="bg-neutral-800 text-white min-h-screen select-none">
|
||||||
<div className="relative">{children}</div>
|
<div className="relative">{children}</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
import { ReactNode } from "react";
|
|
||||||
|
|
||||||
export default function Overlay({
|
|
||||||
children,
|
|
||||||
onClose,
|
|
||||||
}: {
|
|
||||||
children: ReactNode;
|
|
||||||
onClose: () => void;
|
|
||||||
}) {
|
|
||||||
return (
|
|
||||||
<div onClick={onClose} className="fixed bg-black/50 w-full h-full z-1">
|
|
||||||
{children}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
export default function Picture({
|
|
||||||
image,
|
|
||||||
onClick,
|
|
||||||
}: {
|
|
||||||
image: string;
|
|
||||||
onClick: () => void;
|
|
||||||
}) {
|
|
||||||
return (
|
|
||||||
<img
|
|
||||||
src={image}
|
|
||||||
className="inline w-[200px] max-h-[100px] object-cover"
|
|
||||||
onClick={onClick}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
|
import ErrorState from "../ErrorState";
|
||||||
|
|
||||||
type GameObject = {
|
type GameObject = {
|
||||||
currentlyPlaying: CurrentlyPlaying;
|
currentlyPlaying: CurrentlyPlaying;
|
||||||
@@ -18,7 +19,7 @@ export default function GameComponent() {
|
|||||||
|
|
||||||
async function fetchGame() {
|
async function fetchGame() {
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
"https://api.alexav.gg/v4/tracker/latestGame"
|
"https://api.alexav.gg/v4/tracker/latestGame",
|
||||||
);
|
);
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
@@ -33,54 +34,27 @@ export default function GameComponent() {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
if (game) {
|
if (game) {
|
||||||
const dateOrTime = (game: CurrentlyPlaying) => {
|
|
||||||
if (game.finishedAt) {
|
|
||||||
const currentDate = new Date();
|
|
||||||
const finishedDate = new Date(game.finishedAt);
|
|
||||||
|
|
||||||
if (
|
|
||||||
currentDate.toLocaleDateString() === finishedDate.toLocaleDateString()
|
|
||||||
) {
|
|
||||||
return `at ${finishedDate.toLocaleTimeString()}`;
|
|
||||||
} else {
|
|
||||||
return `on ${finishedDate.toLocaleDateString()}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="border border-white border-solid p-2 rounded-lg space-y-2">
|
<a href={`https://medal.tv/u/alexav`} target="_blank">
|
||||||
{game.currentlyPlaying && (
|
<div className="flex flex-col bg-black border border-black text-white">
|
||||||
<>
|
<div className="flex">
|
||||||
<h1 className="text-2xl font-bold italic">currently playing</h1>
|
<div className="pl-2 pr-1">
|
||||||
<p>
|
<p className="w-[150px] truncate overflow-hidden whitespace-nowrap">
|
||||||
<span className="font-semibold">
|
|
||||||
{game.currentlyPlaying.game}
|
{game.currentlyPlaying.game}
|
||||||
</span>{" "}
|
</p>
|
||||||
since{" "}
|
<p>
|
||||||
{new Date(
|
{" "}
|
||||||
game.currentlyPlaying.startedPlayingAt
|
since{" "}
|
||||||
).toLocaleTimeString()}
|
{new Date(
|
||||||
</p>
|
game.currentlyPlaying.startedPlayingAt,
|
||||||
</>
|
).toLocaleTimeString()}
|
||||||
)}
|
</p>
|
||||||
|
|
||||||
{game.history.length > 0 && (
|
|
||||||
<>
|
|
||||||
<h1 className="text-2xl font-bold italic">previously played</h1>
|
|
||||||
<div className="flex flex-wrap space-x-2">
|
|
||||||
{game.history.splice(0, 5).map((v, k) => {
|
|
||||||
return (
|
|
||||||
<div key={k}>
|
|
||||||
<p className="font-semibold">{v.game}</p>
|
|
||||||
<p>{dateOrTime(v)}</p>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
</div>
|
||||||
</>
|
</div>
|
||||||
)}
|
</div>
|
||||||
</div>
|
</a>
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
return <ErrorState type="unavailable" />;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import type { LastFMMusicObject } from "../../utils/types";
|
import type { LastFMMusicObject } from "../../utils/types";
|
||||||
|
import ErrorState from "../ErrorState";
|
||||||
|
|
||||||
export default function MusicComponent() {
|
export default function MusicComponent() {
|
||||||
const [music, setMusic] = useState<LastFMMusicObject | null>(null);
|
const [music, setMusic] = useState<LastFMMusicObject | null>(null);
|
||||||
const [failedFetch, setFailedFetch] = useState(false);
|
const [failedFetch, setFailedFetch] = useState<boolean>(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function fetchMusic() {
|
async function fetchMusic() {
|
||||||
@@ -25,46 +26,67 @@ export default function MusicComponent() {
|
|||||||
fetchMusic();
|
fetchMusic();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
if (music) {
|
if (!failedFetch) {
|
||||||
return (
|
if (music) {
|
||||||
<a href="https://last.fm/user/lulawex" target="_blank">
|
return (
|
||||||
<div className="flex flex-col">
|
<a href="https://last.fm/user/lulawex" target="_blank">
|
||||||
<div className="flex align-middle">
|
<div className="flex flex-col bg-black border border-black text-white">
|
||||||
<img width="50" src={music.images[1]?.url} />
|
<div className="flex align-middle">
|
||||||
<div className="pl-2 max-w-25">
|
<img
|
||||||
{music.title.length > 15 ? (
|
className="w-[50px] h-[50px] object-cover"
|
||||||
<div className="marquee">
|
src={music.images[1]?.url}
|
||||||
<div className="marquee-content">
|
/>
|
||||||
<span>{music.title} </span>
|
<div className="pl-2 pr-1">
|
||||||
<span>{music.title} </span>
|
<p className="w-[150px] truncate overflow-hidden whitespace-nowrap">
|
||||||
</div>
|
{music.title}
|
||||||
</div>
|
</p>
|
||||||
) : (
|
<p> {music.artist}</p>
|
||||||
<h1>{music.title}</h1>
|
</div>
|
||||||
)}
|
|
||||||
|
|
||||||
<p className="truncate">{music.artist}</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p className="hover:underline w-fit opacity-50">powered by last.fm</p>
|
</a>
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
if (failedFetch) {
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<h1>uh oh!</h1>
|
|
||||||
<p>failed to get music :(</p>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return (
|
return <ErrorState type="loading" />;
|
||||||
<div>
|
|
||||||
<h1>loading music..</h1>
|
|
||||||
<p>loading artist..</p>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
return <ErrorState type="error" />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if (music) {
|
||||||
|
// return (
|
||||||
|
// <a href="https://last.fm/user/lulawex" target="_blank">
|
||||||
|
// <div className="flex flex-col bg-black border border-black text-white">
|
||||||
|
// <div className="flex align-middle">
|
||||||
|
// <img
|
||||||
|
// className="w-[50px] h-[50px] object-cover"
|
||||||
|
// src={music.images[1]?.url}
|
||||||
|
// />
|
||||||
|
// <div className="pl-2 pr-1">
|
||||||
|
// <p className="w-[150px] truncate overflow-hidden whitespace-nowrap">
|
||||||
|
// {music.title}
|
||||||
|
// </p>
|
||||||
|
// <p> {music.artist}</p>
|
||||||
|
// </div>
|
||||||
|
// </div>
|
||||||
|
// </div>
|
||||||
|
// </a>
|
||||||
|
// );
|
||||||
|
// } else {
|
||||||
|
// if (failedFetch) {
|
||||||
|
// return (
|
||||||
|
// <div>
|
||||||
|
// <h1>uh oh!</h1>
|
||||||
|
// <p>failed to get music :(</p>
|
||||||
|
// </div>
|
||||||
|
// );
|
||||||
|
// } else {
|
||||||
|
// return (
|
||||||
|
// <div>
|
||||||
|
// <h1>loading music..</h1>
|
||||||
|
// <p>loading artist..</p>
|
||||||
|
// </div>
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import { useState, useEffect } from "react";
|
||||||
|
|
||||||
|
export default function Clock() {
|
||||||
|
const [clock, setClock] = useState(
|
||||||
|
new Date().toLocaleTimeString("en-GB", {
|
||||||
|
hour: "2-digit",
|
||||||
|
minute: "2-digit",
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setInterval(() => {
|
||||||
|
const date = new Date().toLocaleTimeString("en-GB", {
|
||||||
|
hour: "2-digit",
|
||||||
|
minute: "2-digit",
|
||||||
|
});
|
||||||
|
if (clock != date) {
|
||||||
|
setClock(date);
|
||||||
|
}
|
||||||
|
}, 500);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<h1 className="text-center bg-white text-black max-w-fit mx-auto px-1">
|
||||||
|
{clock}
|
||||||
|
</h1>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
import MusicComponent from "../info/MusicComponent";
|
|
||||||
|
|
||||||
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 className="space-y-2">
|
|
||||||
<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 />
|
|
||||||
</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 select-text 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>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
import Picture from "../Picture";
|
|
||||||
|
|
||||||
const images = [
|
const images = [
|
||||||
"https://storage.alexav.gg/content/1f822215-0768-424d-893a-13bcd10aa98b.jpg",
|
"https://storage.alexav.gg/content/1f822215-0768-424d-893a-13bcd10aa98b.jpg",
|
||||||
"https://storage.alexav.gg/content/de890eaf-fc73-42a4-9fbe-a62313394a4c.jpg",
|
"https://storage.alexav.gg/content/de890eaf-fc73-42a4-9fbe-a62313394a4c.jpg",
|
||||||
@@ -8,19 +6,19 @@ const images = [
|
|||||||
"https://storage.alexav.gg/content/2f36c1dd-eaf8-4fd3-a3cd-1d25fe8f5a07.jpg",
|
"https://storage.alexav.gg/content/2f36c1dd-eaf8-4fd3-a3cd-1d25fe8f5a07.jpg",
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function PictureCarousel({
|
export default function PictureCarousel() {
|
||||||
onClick,
|
|
||||||
}: {
|
|
||||||
onClick: (url: string) => void;
|
|
||||||
}) {
|
|
||||||
return (
|
return (
|
||||||
<div className="border border-white border-solid rounded-lg p-2">
|
<div className="border border-white border-solid rounded-lg p-2">
|
||||||
<h1 className="text-2xl font-bold italic">pictures</h1>
|
|
||||||
|
|
||||||
<div className="whitespace-nowrap overflow-x-auto">
|
<div className="whitespace-nowrap overflow-x-auto">
|
||||||
<div className="my-2 space-x-2">
|
<div className="my-2 space-x-2">
|
||||||
{images.map((v, k) => {
|
{images.map((v, k) => {
|
||||||
return <Picture key={k} image={v} onClick={() => onClick(v)} />;
|
return (
|
||||||
|
<img
|
||||||
|
key={k}
|
||||||
|
src={v}
|
||||||
|
className="inline w-[200px] max-h-[100px] object-cover"
|
||||||
|
/>
|
||||||
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ export default function ScoreModule({ type }: { type: "sabres" | "bills" }) {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="border border-white border-solid rounded-lg w-full mb-4">
|
<div className="text-black rounded-lg w-full">
|
||||||
<div className="flex justify-between">
|
<div className="flex justify-between">
|
||||||
<div>
|
<div>
|
||||||
<img width="100" className="p-4" src={IMAGES[type]} />
|
<img width="100" className="p-4" src={IMAGES[type]} />
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
|
import ErrorState from "../ErrorState";
|
||||||
|
|
||||||
type ContentObject = {
|
type ContentObject = {
|
||||||
id: number;
|
id: number;
|
||||||
@@ -17,19 +18,9 @@ type ContentObject = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default function StatModule() {
|
export default function StatModule() {
|
||||||
const [data, setData] = useState<ContentObject[] | null>(null);
|
const [data, setData] = useState<ContentObject | null>(null);
|
||||||
|
|
||||||
const [failedFetch, setFailedFetch] = useState<boolean>(false);
|
const [failedFetch, setFailedFetch] = useState<boolean>(false);
|
||||||
|
|
||||||
const ErrorState = () => {
|
|
||||||
return (
|
|
||||||
<div className="text-center p-2">
|
|
||||||
<h1 className="text-lg font-semibold">Uh oh :(</h1>
|
|
||||||
<p>Something went wrong loading this stat</p>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function fetchData() {
|
async function fetchData() {
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
@@ -39,49 +30,46 @@ export default function StatModule() {
|
|||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
if (data && data.length <= 0) {
|
if (data && data.length <= 0) {
|
||||||
setFailedFetch(true);
|
setFailedFetch(true);
|
||||||
} else setData(data.data as ContentObject[]);
|
} else setData(data.data[0] as ContentObject);
|
||||||
} else setFailedFetch(true);
|
} else setFailedFetch(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchData();
|
fetchData();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
if (!failedFetch) {
|
||||||
<div className="border border-white border-solid rounded-lg w-full mb-4">
|
if (data) {
|
||||||
<h1 className="text-2xl font-bold italic p-2">recent watches</h1>
|
return (
|
||||||
<div className="grid grid-cols-3 gap-2">
|
<a href={`https://tracker.alexav.gg/info/${data?.id}`} target="_blank">
|
||||||
{data && data.length > 0 && !failedFetch ? (
|
<div className="flex flex-col bg-black border border-black text-white">
|
||||||
data?.map((v, k) => {
|
<div className="flex">
|
||||||
return (
|
<div className="pl-2 pr-1">
|
||||||
<div key={k} className="text-center p-2 space-y-2">
|
<p className="w-[150px] truncate flex justify-end overflow-hidden whitespace-nowrap">
|
||||||
<img
|
{data?.title}
|
||||||
src={v?.image}
|
</p>
|
||||||
className="object-cover w-full h-[50px] object-top"
|
<p className="flex justify-end">
|
||||||
/>
|
{" "}
|
||||||
<a
|
{data?.finished
|
||||||
className="hover:underline"
|
? "finished"
|
||||||
href={`https://tracker.alexav.gg/info/${v?.id}`}
|
: data?.paused
|
||||||
target="_blank"
|
? "paused"
|
||||||
>
|
: data?.startedOn
|
||||||
<h1 className="font-semibold">{v?.title}</h1>
|
? "started"
|
||||||
<p>
|
: "not started"}
|
||||||
{" "}
|
</p>
|
||||||
{v?.finished
|
|
||||||
? "finished"
|
|
||||||
: v?.paused
|
|
||||||
? "paused"
|
|
||||||
: v.startedOn
|
|
||||||
? "started"
|
|
||||||
: "not started"}
|
|
||||||
</p>
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
<img
|
||||||
})
|
className="w-[50px] h-[50px] object-cover"
|
||||||
) : (
|
src={data?.image}
|
||||||
<ErrorState />
|
/>
|
||||||
)}
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</a>
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
return <ErrorState type="loading" />;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return <ErrorState type="error" />;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
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>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
+136
-31
@@ -1,48 +1,153 @@
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import Layout from "../components/Layout";
|
import Layout from "../components/Layout";
|
||||||
import Overlay from "../components/Overlay";
|
|
||||||
import GameComponent from "../components/info/GameComponent";
|
import GameComponent from "../components/info/GameComponent";
|
||||||
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 ScoreModule from "../components/modules/ScoreModule";
|
import ScoreModule from "../components/modules/ScoreModule";
|
||||||
import StatModule from "../components/modules/StatModule";
|
import StatModule from "../components/modules/StatModule";
|
||||||
|
import FantasyStatus from "../components/FantasyStatus";
|
||||||
|
import Clock from "../components/modules/Clock";
|
||||||
|
import MusicComponent from "../components/info/MusicComponent";
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
const [selectedImage, setSelectedImage] = useState<string>("");
|
const [tab, setTab] = useState<string>("home");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout>
|
<Layout>
|
||||||
{selectedImage !== "" && (
|
<div className="min-h-screen flex justify-center items-center">
|
||||||
<Overlay onClose={() => setSelectedImage("")}>
|
<div className="border-3 bg-[#ebebeb] border-black w-full sm:w-[500px]">
|
||||||
<div className="flex justify-center items-center w-full h-full">
|
<div className="] text-black">
|
||||||
|
<div className="bg-black w-full text-white">
|
||||||
|
<div className="grid grid-cols-3 gap-2 p-2 text-2xl">
|
||||||
|
<h1 className="font-semibold">welcome</h1>
|
||||||
|
<Clock />
|
||||||
|
<h1 className="text-right">let it rip</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<img
|
<img
|
||||||
draggable={false}
|
className="h-[100px] object-[25%_75%] w-full object-cover"
|
||||||
className="select-none"
|
src="https://storage.alexav.gg/content/1f822215-0768-424d-893a-13bcd10aa98b.jpg"
|
||||||
width="400"
|
|
||||||
height="400"
|
|
||||||
src={selectedImage}
|
|
||||||
/>
|
/>
|
||||||
|
<hr className="border-black" />
|
||||||
|
<div className="p-2">
|
||||||
|
<div className="grid grid-cols-3 gap-2">
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
className="h-40 w-50 object-cover object-top"
|
||||||
|
src="https://storage.alexav.gg/content/f49b355a-25cd-48ba-8421-da702620fcc6.jpeg"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h1 className="text-2xl font-semibold">hi, i'm alex!</h1>
|
||||||
|
<p className="text-lg">
|
||||||
|
i do QA stuff at{" "}
|
||||||
|
<a
|
||||||
|
className="underline"
|
||||||
|
href="https://medal.tv/u/alexav"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
Medal.tv{" "}
|
||||||
|
</a>
|
||||||
|
and write mediocre code sometimes
|
||||||
|
</p>
|
||||||
|
<p className="text-sm space-x-1">
|
||||||
|
<a
|
||||||
|
href="https://twitter.com/lostinmyyabyss_"
|
||||||
|
className="hover:underline"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
twt
|
||||||
|
</a>
|
||||||
|
<span>•</span>
|
||||||
|
<a
|
||||||
|
className="hover:underline"
|
||||||
|
href="https://instagram.com/alexfrantz07"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
instagram
|
||||||
|
</a>
|
||||||
|
<span>•</span>
|
||||||
|
<a
|
||||||
|
className="hover:underline"
|
||||||
|
href="https://tiktok.com/@lostinherabyss_"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
tiktok
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="text-2xl">
|
||||||
|
<div>
|
||||||
|
{" "}
|
||||||
|
<span className="bg-black text-white px-1">shows</span>{" "}
|
||||||
|
dexter, the pitt, tlou, twd
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span className="bg-black text-white px-1">music</span> ptv,
|
||||||
|
treaty oak, zach top, she wants revenge
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr className="border-black" />
|
||||||
|
<div className="px-2">
|
||||||
|
<div className="grid grid-cols-2">
|
||||||
|
<div>
|
||||||
|
<h1 className="text-2xl font-bold">about me</h1>
|
||||||
|
<p>
|
||||||
|
born & raised western new yorker. i've been doing QA work
|
||||||
|
for the past 4 years and learning software engineering in
|
||||||
|
between. i also play acoustic guitar, am really into gaming
|
||||||
|
and love travelling to NYC. i am also incredibly awkward,
|
||||||
|
but that's besides the point
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="mx-auto">
|
||||||
|
<div className="p-2">
|
||||||
|
<div className="mb-2">
|
||||||
|
<MusicComponent />
|
||||||
|
</div>
|
||||||
|
<div className="mb-2">
|
||||||
|
<StatModule />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<GameComponent />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="grid grid-cols-4 text-center border-b">
|
||||||
|
<h1
|
||||||
|
onClick={() => setTab("home")}
|
||||||
|
className={`border-r-1 border-t-1 border-black hover:cursor-pointer ${tab === "home" && "underline"}`}
|
||||||
|
>
|
||||||
|
home
|
||||||
|
</h1>
|
||||||
|
<h1
|
||||||
|
onClick={() => setTab("fantasy")}
|
||||||
|
className={`border-r-1 border-t-1 border-black hover:cursor-pointer ${tab === "fantasy" && "underline"}`}
|
||||||
|
>
|
||||||
|
fantasy
|
||||||
|
</h1>
|
||||||
|
<h1
|
||||||
|
onClick={() => setTab("pictures")}
|
||||||
|
className={`border-r-1 border-t-1 border-black hover:cursor-pointer ${tab === "pictures" && "underline"}`}
|
||||||
|
>
|
||||||
|
pictures
|
||||||
|
</h1>
|
||||||
|
<h1
|
||||||
|
onClick={() => setTab("scores")}
|
||||||
|
className={`border-r-1 border-t-1 border-black hover:cursor-pointer ${tab === "scores" && "underline"}`}
|
||||||
|
>
|
||||||
|
scores
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Overlay>
|
{tab === "fantasy" && <FantasyStatus />}
|
||||||
)}
|
{tab === "pictures" && <PictureCarousel />}
|
||||||
|
{tab === "scores" && <ScoreModule type="sabres" />}
|
||||||
<div className="my-2 mx-auto w-full sm:w-[500px]">
|
|
||||||
<div className="space-y-4">
|
|
||||||
<img
|
|
||||||
className="rounded-lg"
|
|
||||||
src={
|
|
||||||
"https://storage.alexav.gg/content/55f3eca0-a5a9-4c71-9d92-ba5d669a7a0c.jpg"
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<WelcomeModule />
|
|
||||||
<InfoModule />
|
|
||||||
<StatModule />
|
|
||||||
<PictureCarousel onClick={(url) => setSelectedImage(url)} />
|
|
||||||
<GameComponent />
|
|
||||||
<ScoreModule type={"sabres"} />
|
|
||||||
{/* <FantasyStatus /> */}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|||||||
Reference in New Issue
Block a user