mirror of
https://github.com/Xevion/xevion.dev.git
synced 2025-12-06 01:16:58 -06:00
animated index, chronark
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { readSingleton } from "@directus/sdk";
|
import { readItems, readSingleton } from "@directus/sdk";
|
||||||
import { GetStaticPropsResult, type NextPage } from "next";
|
import { GetStaticPropsResult, type NextPage } from "next";
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
@@ -6,9 +6,9 @@ import { useEffect } from "react";
|
|||||||
import Balancer from "react-wrap-balancer";
|
import Balancer from "react-wrap-balancer";
|
||||||
import AppWrapper from "@/components/AppWrapper";
|
import AppWrapper from "@/components/AppWrapper";
|
||||||
import ItemCard from "@/components/ItemCard";
|
import ItemCard from "@/components/ItemCard";
|
||||||
import directus from "@/utils/directus";
|
import directus, { type Project } from "@/utils/directus";
|
||||||
import { useBreakpointValue } from "@/utils/helpers";
|
import { useBreakpointValue } from "@/utils/helpers";
|
||||||
import type { Project } from "@/utils/types";
|
import Dots from "@/components/Dots";
|
||||||
|
|
||||||
type IndexProps = {
|
type IndexProps = {
|
||||||
tagline: string;
|
tagline: string;
|
||||||
@@ -19,82 +19,12 @@ type IndexProps = {
|
|||||||
export async function getStaticProps(): Promise<
|
export async function getStaticProps(): Promise<
|
||||||
GetStaticPropsResult<IndexProps>
|
GetStaticPropsResult<IndexProps>
|
||||||
> {
|
> {
|
||||||
const metadata = await directus.request(readSingleton("metadata"));
|
const [metadata, projects] = await Promise.all([directus.request(readSingleton("metadata")), directus.request(readItems("project"))]);
|
||||||
|
|
||||||
const resumeUrl = `${directus.url}assets/${metadata.resume}/${
|
const resumeUrl = `${directus.url}assets/${metadata.resume}/${
|
||||||
metadata.resumeFilename ?? "resume.pdf"
|
metadata.resumeFilename ?? "resume.pdf"
|
||||||
}`;
|
}`;
|
||||||
|
|
||||||
const projects: Project[] = [
|
|
||||||
{
|
|
||||||
title: "Portal",
|
|
||||||
banner: "/portal/banner.jpeg",
|
|
||||||
location: "/portal",
|
|
||||||
longDescription:
|
|
||||||
"An advanced membership & event management system for my university's premier computer science organization.",
|
|
||||||
shortDescription:
|
|
||||||
"Advanced membership & event management system for students",
|
|
||||||
links: [
|
|
||||||
{
|
|
||||||
icon: "github",
|
|
||||||
location: "https://github.com/acmutsa/Portal",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: "external",
|
|
||||||
location: "https://portal.acmutsa.org/",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "Phototag",
|
|
||||||
banner: "/phototag.png",
|
|
||||||
location: "/phototag",
|
|
||||||
longDescription: `Using Google's Vision API and supporting metadata formats on Windows, Phototag makes it easy to quickly add rich, descriptive tags to your photos, saving you time and effort.`,
|
|
||||||
shortDescription:
|
|
||||||
"Effortlessly add rich & descriptive tags to your photos with Phototag.",
|
|
||||||
links: [
|
|
||||||
{
|
|
||||||
icon: "github",
|
|
||||||
location: "https://github.com/Xevion/phototag",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "Paths",
|
|
||||||
banner: "/paths.png",
|
|
||||||
location: "/paths",
|
|
||||||
shortDescription:
|
|
||||||
"Discover the power of graph traversal algorithms with my interactive application.",
|
|
||||||
longDescription: `Discover the power of graph traversal algorithms with my interactive Unity application!
|
|
||||||
Easily generate and edit graphs, create mazes, and experiment with different algorithm configurations to find the most efficient path.`,
|
|
||||||
links: [
|
|
||||||
{
|
|
||||||
icon: "github",
|
|
||||||
location: "https://github.com/Xevion/Paths",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "Grain",
|
|
||||||
banner: "/grain/banner.jpeg",
|
|
||||||
bannerSettings: { quality: 100 },
|
|
||||||
location: "/grain",
|
|
||||||
shortDescription:
|
|
||||||
"An experimental React app to generate beautiful backgrounds with noise filters.",
|
|
||||||
longDescription:
|
|
||||||
"Quickly generate beautiful backgrounds with noise filters. Built with React, hosted on Vercel, and rendered using simple SVG noise filters (just HTML & CSS).",
|
|
||||||
links: [
|
|
||||||
{
|
|
||||||
icon: "external",
|
|
||||||
location: "https://grain.xevion.dev",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: "github",
|
|
||||||
location: "https://github.com/Xevion/grain",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
tagline: metadata.tagline,
|
tagline: metadata.tagline,
|
||||||
@@ -133,6 +63,7 @@ const Home: NextPage<IndexProps> = ({
|
|||||||
</Head>
|
</Head>
|
||||||
<AppWrapper hideNavigation={true} className="overflow-x-hidden">
|
<AppWrapper hideNavigation={true} className="overflow-x-hidden">
|
||||||
<div className="flex h-screen w-screen items-center justify-center overflow-hidden">
|
<div className="flex h-screen w-screen items-center justify-center overflow-hidden">
|
||||||
|
<Dots />
|
||||||
<div className="flex w-full flex-col items-center justify-start">
|
<div className="flex w-full flex-col items-center justify-start">
|
||||||
<nav className="animate-fade-in">
|
<nav className="animate-fade-in">
|
||||||
<ul className="flex items-center justify-center gap-4">
|
<ul className="flex items-center justify-center gap-4">
|
||||||
@@ -147,12 +78,21 @@ const Home: NextPage<IndexProps> = ({
|
|||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
<div className="sm:text-9x cursor-default select-none py-10 font-hanken text-6xl font-black uppercase tracking-widest min-[300px]:text-7xl min-[500px]:text-8xl lg:text-10xl">
|
<div className="hidden w-screen h-px animate-glow md:block animate-fade-left bg-gradient-to-r from-zinc-300/0 via-zinc-300/50 to-zinc-300/0" />
|
||||||
|
<h1 className="font-hanken select-none py-3.5 px-0.5 z-10 text-transparent duration-1000 bg-white cursor-default text-edge-outline animate-title font-display text-5xl sm:text-6xl md:text-9xl lg:text-10xl whitespace-nowrap bg-clip-text ">
|
||||||
|
XEVION
|
||||||
|
</h1>
|
||||||
|
<div className="hidden w-screen h-px animate-glow md:block animate-fade-right bg-gradient-to-r from-zinc-300/0 via-zinc-300/50 to-zinc-300/0" />
|
||||||
|
{/* <div className="sm:text-9x cursor-default select-none py-10 font-hanken text-6xl font-black uppercase tracking-widest min-[300px]:text-7xl min-[500px]:text-8xl lg:text-10xl">
|
||||||
Xevion
|
Xevion
|
||||||
</div>
|
</div> */}
|
||||||
<div className="max-w-screen-sm px-4 text-center text-base text-zinc-500 sm:text-sm">
|
<div className="max-w-screen-sm text-center text-sm sm:text-base animate-fade-in text-zinc-500">
|
||||||
<Balancer>{tagline}</Balancer>
|
<Balancer>{tagline}</Balancer>
|
||||||
</div>
|
</div>
|
||||||
|
{/* <div className="max-w-screen-sm px-4 text-center text-base text-zinc-500 sm:text-sm">
|
||||||
|
<Balancer>{tagline}</Balancer>
|
||||||
|
</div>
|
||||||
|
</div> */}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
@@ -161,15 +101,11 @@ const Home: NextPage<IndexProps> = ({
|
|||||||
>
|
>
|
||||||
<div className="mx-auto h-full w-full max-w-[95%] lg:max-w-[85%] xl:max-w-[70%]">
|
<div className="mx-auto h-full w-full max-w-[95%] lg:max-w-[85%] xl:max-w-[70%]">
|
||||||
<div className="m-1 flex h-full flex-col justify-start gap-y-1">
|
<div className="m-1 flex h-full flex-col justify-start gap-y-1">
|
||||||
{projects.map((project, index) => (
|
{projects.map((project) => {
|
||||||
<ItemCard
|
return (<ItemCard key={project.id}
|
||||||
key={index}
|
description={useLong ? project.description : project.shortDescription} banner={`${directus.url}assets/${project.bannerImage}`} title={project.name} location={`/${project.id}/`} />
|
||||||
{...project}
|
);
|
||||||
description={
|
})}
|
||||||
useLong ? project.longDescription : project.shortDescription
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
const defaultTheme = require("tailwindcss/defaultTheme");
|
||||||
|
|
||||||
/** @type {import('tailwindcss').Config} */
|
/** @type {import('tailwindcss').Config} */
|
||||||
module.exports = {
|
module.exports = {
|
||||||
content: ["./src/**/*.{js,ts,jsx,tsx}"],
|
content: ["./src/**/*.{js,ts,jsx,tsx}"],
|
||||||
@@ -11,11 +13,102 @@ module.exports = {
|
|||||||
fontSize: {
|
fontSize: {
|
||||||
"10xl": "10rem",
|
"10xl": "10rem",
|
||||||
},
|
},
|
||||||
|
typography: {
|
||||||
|
DEFAULT: {
|
||||||
|
css: {
|
||||||
|
"code::before": {
|
||||||
|
content: '""',
|
||||||
|
},
|
||||||
|
"code::after": {
|
||||||
|
content: '""',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
quoteless: {
|
||||||
|
css: {
|
||||||
|
"blockquote p:first-of-type::before": { content: "none" },
|
||||||
|
"blockquote p:first-of-type::after": { content: "none" },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
fontFamily: {
|
fontFamily: {
|
||||||
inter: ['"Inter"', "sans-serif"],
|
inter: ['"Inter"', "sans-serif"],
|
||||||
roboto: ['"Roboto"', "sans-serif"],
|
roboto: ['"Roboto"', "sans-serif"],
|
||||||
mono: ['"Roboto Mono"', "monospace"],
|
mono: ['"Roboto Mono"', "monospace"],
|
||||||
hanken: ['"Hanken Grotesk"', "sans-serif"],
|
hanken: ['"Hanken Grotesk"', "sans-serif"],
|
||||||
|
// sans: ["var(--font-inter)", ...defaultTheme.fontFamily.sans],
|
||||||
|
// display: ["var(--font-calsans)"],
|
||||||
|
},
|
||||||
|
backgroundImage: {
|
||||||
|
"gradient-radial":
|
||||||
|
"radial-gradient(50% 50% at 50% 50%, var(--tw-gradient-stops))",
|
||||||
|
},
|
||||||
|
animation: {
|
||||||
|
bg: "bg 5s ease-in-out forwards",
|
||||||
|
"fade-in": "fade-in 3s ease-in-out forwards",
|
||||||
|
title: "title 3s ease-out forwards",
|
||||||
|
"fade-left": "fade-left 3s ease-in-out forwards",
|
||||||
|
"fade-right": "fade-right 3s ease-in-out forwards",
|
||||||
|
},
|
||||||
|
keyframes: {
|
||||||
|
"fade-in": {
|
||||||
|
"0%": {
|
||||||
|
opacity: "0%",
|
||||||
|
},
|
||||||
|
"75%": {
|
||||||
|
opacity: "0%",
|
||||||
|
},
|
||||||
|
"100%": {
|
||||||
|
opacity: "100%",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"fade-left": {
|
||||||
|
"0%": {
|
||||||
|
transform: "translateX(100%)",
|
||||||
|
opacity: "0%",
|
||||||
|
},
|
||||||
|
|
||||||
|
"30%": {
|
||||||
|
transform: "translateX(0%)",
|
||||||
|
opacity: "100%",
|
||||||
|
},
|
||||||
|
"100%": {
|
||||||
|
opacity: "0%",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"fade-right": {
|
||||||
|
"0%": {
|
||||||
|
transform: "translateX(-100%)",
|
||||||
|
opacity: "0%",
|
||||||
|
},
|
||||||
|
|
||||||
|
"30%": {
|
||||||
|
transform: "translateX(0%)",
|
||||||
|
opacity: "100%",
|
||||||
|
},
|
||||||
|
"100%": {
|
||||||
|
opacity: "0%",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
"0%": {
|
||||||
|
"line-height": "0%",
|
||||||
|
"letter-spacing": "0.25em",
|
||||||
|
opacity: "0",
|
||||||
|
},
|
||||||
|
"25%": {
|
||||||
|
"line-height": "0%",
|
||||||
|
opacity: "0%",
|
||||||
|
},
|
||||||
|
"80%": {
|
||||||
|
opacity: "100%",
|
||||||
|
},
|
||||||
|
|
||||||
|
"100%": {
|
||||||
|
"line-height": "100%",
|
||||||
|
opacity: "100%",
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user