Init NextJS

This commit is contained in:
암냥 2025-09-28 14:52:22 +09:00
commit 7fee80308c
52 changed files with 465 additions and 3542 deletions

BIN
src/app/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

26
src/app/globals.css Normal file
View file

@ -0,0 +1,26 @@
@import "tailwindcss";
:root {
--background: #ffffff;
--foreground: #171717;
}
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--font-sans: var(--font-geist-sans);
--font-mono: var(--font-geist-mono);
}
@media (prefers-color-scheme: dark) {
:root {
--background: #0a0a0a;
--foreground: #ededed;
}
}
body {
background: var(--background);
color: var(--foreground);
font-family: Arial, Helvetica, sans-serif;
}

View file

@ -1,29 +0,0 @@
import "../index.css";
import { BrowserRouter, Routes, Route } from "react-router";
import { Page } from "./page";
import NotFound from "./utils/NotFound";
import { ThemeProvider } from "@/components/theme-provider";
import { useEffect } from "react";
import { useNavigate } from "react-router";
import SUPERCOMMAND from "@/components/SUPERCOMMAND";
function TimelineRedirect() {
const navigate = useNavigate();
useEffect(() => { navigate("/#timeline"); }, [navigate]);
return null;
}
export default function App() {
return (
<ThemeProvider defaultTheme="system">
<SUPERCOMMAND />
<BrowserRouter>
<Routes>
<Route path="/" element={<Page />} />
<Route path="/timeline" element={<TimelineRedirect />} />
<Route path="/*" element={<NotFound />} />
</Routes>
</BrowserRouter>
</ThemeProvider>
);
}

34
src/app/layout.tsx Normal file
View file

@ -0,0 +1,34 @@
import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";
const geistSans = Geist({
variable: "--font-geist-sans",
subsets: ["latin"],
});
const geistMono = Geist_Mono({
variable: "--font-geist-mono",
subsets: ["latin"],
});
export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
>
{children}
</body>
</html>
);
}

View file

@ -1,185 +1,103 @@
import "../link.css";
import { useState, useEffect } from "react";
import Image from "@/profile.avif";
import Timeline from "@/components/TimeLine";
import Contact from "@/components/Contact";
import Projects from "@/components/Projects";
import Seperator from "@/components/Seperator";
import Image from "next/image";
export function Page() {
const [age, setAge] = useState<number>(0);
const [post, setPost] = useState<any>({});
export default function Home() {
return (
<div className="font-sans grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20">
<main className="flex flex-col gap-[32px] row-start-2 items-center sm:items-start">
<Image
className="dark:invert"
src="/next.svg"
alt="Next.js logo"
width={180}
height={38}
priority
/>
<ol className="font-mono list-inside list-decimal text-sm/6 text-center sm:text-left">
<li className="mb-2 tracking-[-.01em]">
Get started by editing{" "}
<code className="bg-black/[.05] dark:bg-white/[.06] font-mono font-semibold px-1 py-0.5 rounded">
src/app/page.tsx
</code>
.
</li>
<li className="tracking-[-.01em]">
Save and see your changes instantly.
</li>
</ol>
useEffect(() => {
const scrollToHash = () => {
const hash = window.location.hash.substring(1);
if (hash) {
const element = document.getElementById(hash);
if (element) {
setTimeout(() => {
element.scrollIntoView({ behavior: "smooth" });
}, 100);
}
}
};
scrollToHash();
}, []);
useEffect(() => {
// 나이 계산
const referenceDate = new Date(2010, 11, 8);
const currentDate = new Date();
let calculatedAge = currentDate.getFullYear() - referenceDate.getFullYear();
if (currentDate < new Date(currentDate.getFullYear(), referenceDate.getMonth(), referenceDate.getDate())) {
calculatedAge -= 1;
}
setAge(calculatedAge);
}, []);
useEffect(() => {
// 블로그 데이터 가져오기
const fetchBlogData = async () => {
try {
const response = await fetch("https://api.imnya.ng/rss");
const data = await response.json();
if (data) {
setPost(data[0] || {});
}
} catch (error) {
console.error("Error fetching posts:", error);
}
};
fetchBlogData();
}, []);
return (
<div className="flex flex-col justify-center font-medium">
<div className="max-w-3xl px-4 mx-auto pt-24 pb-12 leading-8">
<header className="mb-6">
<h1 className="mb-4">
<a
href="mailto:me@imnya.ng"
className="text-5xl font-medium font-serif font-ntype hover:opacity-80 transition-opacity"
>
me@imnya.ng
</a>
</h1>
</header>
<section className="mb-8 space-y-4">
<p className="font-medium">
<span className="font-extrabold"> </span> {" "}
<span className="font-extrabold"></span> {" "}
<span className="font-extrabold"></span>.
</p>
<p className="font-medium">
{" "}
<a
className="link-pink"
target="_blank"
href="https://github.com/team-neko/two_hearts"
title="Chrome New Tab Extension"
rel="noopener noreferrer"
>
Two Hearts
</a>
,{" "}
<a
className="link-amber"
target="_blank"
href="https://www.youtube.com/watch?v=XTdqpdTMZbw&list=PLZeYZotn5_IOJDek6e35NKzUtJm09yxZD"
title="Effect Playing Contest is ADOFAI Contest"
rel="noopener noreferrer"
>
EPC 2025
</a>
,{" "}
<a
className="link-emerald"
target="_blank"
href="https://github.com/team-neko/dynamic-kawaii"
title="Dark Pink VSCode Theme"
rel="noopener noreferrer"
>
Dynamic Kawaii
</a>{" "}
.
</p>
</section>
<figure className="my-8">
<picture className="block bg-gray-100 rounded-xl aspect-3-2 overflow-hidden image-scale object-shadowed">
<img
src={Image}
className="w-full aspect-3-2 object-cover object-center transition-transform duration-300 hover:scale-105"
alt="프로필 이미지"
/>
</picture>
</figure>
<section className="mb-8 space-y-4">
<p className="font-medium">
{age} , {" "}
<span className="font-extrabold"> </span> ,
<br />
<span className="font-extrabold"> </span> .
<br />
<span className="font-extrabold"> </span> .
</p>
<p className="font-medium">
<span className="font-extrabold"></span> ,
<span className="font-extrabold"></span> .
<br />
4 <span className="font-extrabold">Python</span> ,
<span className="font-extrabold">TypeScript</span> .
<br />
<span className="font-extrabold"> </span> .
</p>
</section>
<section className="my-8">
<div className="flex flex-row items-center justify-center p-6 bg-muted rounded-xl shadow-lg">
<img
loading="lazy"
decoding="async"
src="https://skillicons.dev/icons?i=typescript,js,c,cpp,rust,go,java,kotlin,py,html,css,php,react,remix,nextjs,tailwind,tauri,bun,elysia,mongodb,postgres,sqlite,docker,nginx,github,githubactions,git,arduino,raspberrypi,bots"
className="w-full max-w-3xl rounded-lg object-contain select-none pointer-events-none transition-transform duration-300 hover:scale-105"
alt="기술 스택"
title="기술 스택"
width={800}
/>
</div>
</section>
{post.title && (
<section className="mb-8">
<p className="font-medium">
:{" "}
<a
href={post.link}
className="text-muted-foreground hover:text-foreground transition-colors underline decoration-dashed underline-offset-4"
target="_blank"
rel="noopener noreferrer"
>
{post.title}
</a>
</p>
</section>
)}
<Seperator />
<Projects />
<Seperator />
<Timeline />
<Seperator />
<Contact />
<p>We are in MAGICALWORLD!</p>
</div>
</div>
);
<div className="flex gap-4 items-center flex-col sm:flex-row">
<a
className="rounded-full border border-solid border-transparent transition-colors flex items-center justify-center bg-foreground text-background gap-2 hover:bg-[#383838] dark:hover:bg-[#ccc] font-medium text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5 sm:w-auto"
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
<Image
className="dark:invert"
src="/vercel.svg"
alt="Vercel logomark"
width={20}
height={20}
/>
Deploy now
</a>
<a
className="rounded-full border border-solid border-black/[.08] dark:border-white/[.145] transition-colors flex items-center justify-center hover:bg-[#f2f2f2] dark:hover:bg-[#1a1a1a] hover:border-transparent font-medium text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5 w-full sm:w-auto md:w-[158px]"
href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
Read our docs
</a>
</div>
</main>
<footer className="row-start-3 flex gap-[24px] flex-wrap items-center justify-center">
<a
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
<Image
aria-hidden
src="/file.svg"
alt="File icon"
width={16}
height={16}
/>
Learn
</a>
<a
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
<Image
aria-hidden
src="/window.svg"
alt="Window icon"
width={16}
height={16}
/>
Examples
</a>
<a
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
href="https://nextjs.org?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
<Image
aria-hidden
src="/globe.svg"
alt="Globe icon"
width={16}
height={16}
/>
Go to nextjs.org
</a>
</footer>
</div>
);
}

View file

@ -1,17 +0,0 @@
import { CommitsGrid } from "@/components/commits-grid"
import { Button } from "@/components/ui/button";
import { useNavigate } from "react-router";
export default function NotFound() {
const navigate = useNavigate();
return (
<div className="flex flex-col justify-center items-center h-screen gap-8">
<CommitsGrid text="404" />
<p className="text-2xl">The page you are looking for does not exist.</p>
<Button variant="outline" onClick={() => navigate("/")}>
Go to Home
</Button>
</div>
);
}