응 넥제로 갈아타면 그만이야~
This commit is contained in:
parent
ffd421a1f1
commit
b8c25c35b4
34 changed files with 460 additions and 9725 deletions
48
src/app/components/Timeline.tsx
Normal file
48
src/app/components/Timeline.tsx
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
const events = [
|
||||
{ date: '2024-12-07', description: '??? ???? ?? ? ??', link: 'https://ncf.or.kr/' },
|
||||
{ date: '2024-12-07', description: '??? ???? ?? ?? ??', link: 'https://ncf.or.kr/' },
|
||||
{ date: '2024-08-18', description: '29회 해킹캠프 CTF 1위 (고민중독)', link: 'https://ctf.hackingcamp.org/' },
|
||||
{ date: '2024-08-05', description: '29회 해킹캠프 선발', link: 'https://hackingcamp.org/' },
|
||||
{ date: '2024-08-01', description: '글로벌 스타트업 학교 2기 베트남 해외 연수 데모데이 대상 (1위)', link: 'http://ncf.or.kr' },
|
||||
{ date: '2024-05-16', description: '글로벌 스타트업 학교 2기 합격', link: 'http://ncf.or.kr' },
|
||||
{ date: '2024-05-11', description: 'LG AI 청소년 캠프 1기 LG 탐색상 수상', link: 'https://lgaiyouthcamp.or.kr/' },
|
||||
{ date: '2024-05-11', description: 'LG AI 청소년 캠프 1기 수료', link: 'https://lgaiyouthcamp.or.kr/' },
|
||||
{ date: '2024-04-22', description: '@isangjeong.today (인천상정중학교의 오늘 급식)', link: 'https://www.instagram.com/isangjeong.today/' },
|
||||
{ date: '2024-04-06', description: 'TimeTable (Sekai 개조판 배포) [API 유실]', link: 'https://timeline.imnyang.xyz' },
|
||||
{ date: '2024-03-24', description: 'Dreamhack #133', link: 'https://dreamhack.io/users/40116/wargame' },
|
||||
{ date: '2024-03-24', description: 'Ubuntu Mirror', link: 'https://launchpad.net/ubuntu/+mirror/mirror.imnyang.xyz-release' },
|
||||
{ date: '2024-03-24', description: '내 목소리로 AI Cover 만들기', link: 'https://colab.research.google.com/drive/1a4G4hD9huBeGRZhEL2HNDMpqSuf4y61k?usp=sharing' },
|
||||
{ date: '2024-01-26', description: 'Fastapi를 통해 API 제작', link: 'https://github.com/imnyang/api' },
|
||||
{ date: '2023-12-20', description: 'LG AI 청소년 캠프 1기 합격' },
|
||||
{ date: '2023-11-14', description: '인천상정중학교 2023학년도 SW 문제 해결 활동 우수상(2위) 수여' },
|
||||
{ date: '2023-11-01', description: '블로그 시작', link: 'https://blog.imnyang.xyz' },
|
||||
{ date: '2023-10-12', description: '나는 로컬 시간을 알고 싶다', link: 'https://time.imnyang.xyz/' },
|
||||
{ date: '2023-09-24', description: 'sqlr.kr 기획 및 초기 개발', link: 'https://github.com/sqlare/sqlr.kr/tree/main' },
|
||||
{ date: '2023-09-02', description: '선린인터넷고등학교 제6회 소프트웨어나늠축제 Layer7 부서 과정 이수' },
|
||||
{ date: '2023-08-26', description: '컴시간 시간표를 더 나아보이게 Sekai', link: 'https://github.com/imnyang/Sekai' },
|
||||
{ date: '2023-08-23', description: '디스코드 통화방 녹음', link: 'https://github.com/imnyang/discord-voice-rec'},
|
||||
{ date: '2023-07-24', description: '한국정보기술연구원이 주도하는 사이버 가디언즈 보안캠프 수료' },
|
||||
{ date: '2023-03-20', description: '디스코드에서 대화형 인공지능 Siru 제작', link: 'https://github.com/imnyang/siru' },
|
||||
{ date: '2023-05-15', description: '한국 코드페어 예선 진출' },
|
||||
{ date: '2023-03-14', description: '타이머', link: 'https://github.com/imnyang/imnyang-timer' },
|
||||
{ date: '2022-12-20', description: '2022 SW영재 창작대회 은상 수상'},
|
||||
{ date: '2022-09-27', description: '2022 삼성 주니어 SW 창작대회 본선 진출' },
|
||||
{ date: '2022-05-23', description: '2022학년도 석정초SW영재학급 첫 수업' },
|
||||
{ date: '2022-07-26', description: '제 14회 맑은하늘 맑은웃음 공모전에서 맑은웃음상 수여' },
|
||||
{ date: '2021-11-14', description: 'Become a ZEPETO Creator 이수' },
|
||||
{ date: '2021-05-19', description: '소프트웨어와 전자신문이 주관한 소프트웨어재단 꿈찾기 캠프 이수' },
|
||||
{ date: '2018-01-27', description: '제4회 맑은하늘 맑은웃음 어린이 문예공모전에서 위닉스상(2위) 수여' },
|
||||
];
|
||||
|
||||
export default function Timeline() {
|
||||
return (
|
||||
<div>
|
||||
{events.map((event, index) => (
|
||||
<div key={index} className="flex flex-row gap-4">
|
||||
<p className="tabular-nums">{event.date}</p>
|
||||
{event.link ? <a href={event.link}>{event.description}</a> : event.description}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
24
src/app/components/repos.tsx
Normal file
24
src/app/components/repos.tsx
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
"use client"
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
export default function Repos() {
|
||||
const [userInfo, setUserInfo] = useState({ public_repos: 0, followers: 0 });
|
||||
|
||||
useEffect(() => {
|
||||
async function fetchUserInfo() {
|
||||
try {
|
||||
const response = await fetch("https://api.github.com/users/imnyang");
|
||||
const data = await response.json();
|
||||
setUserInfo({ public_repos: data.public_repos, followers: data.followers });
|
||||
} catch (error) {
|
||||
console.error("Error fetching user info:", error);
|
||||
}
|
||||
}
|
||||
|
||||
fetchUserInfo();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>{userInfo.public_repos}</>
|
||||
)
|
||||
}
|
||||
BIN
src/app/favicon.ico
Normal file
BIN
src/app/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
BIN
src/app/fonts/GeistMonoVF.woff
Normal file
BIN
src/app/fonts/GeistMonoVF.woff
Normal file
Binary file not shown.
BIN
src/app/fonts/GeistVF.woff
Normal file
BIN
src/app/fonts/GeistVF.woff
Normal file
Binary file not shown.
94
src/app/globals.css
Normal file
94
src/app/globals.css
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
* {
|
||||
font-family: "Pretendard Variable", Pretendard, -apple-system, BlinkMacSystemFont, system-ui, Roboto, "Helvetica Neue", "Segoe UI", "Apple SD Gothic Neo", "Noto Sans KR", "Malgun Gothic", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", sans-serif;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html, body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
body {
|
||||
color: rgba(255, 255, 255, 0.87);
|
||||
background-color: #262225;
|
||||
font-synthesis: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
display: flex;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
#__next {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
a {
|
||||
font-weight: 500;
|
||||
color: #ffe7fb;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #ffe7fb;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3.2em;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 8px;
|
||||
border: 1px solid transparent;
|
||||
padding: 0.6em 1.2em;
|
||||
font-size: 1em;
|
||||
font-weight: 500;
|
||||
font-family: inherit;
|
||||
background-color: #1a1a1a;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.25s;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
border-color: #ffe7fb;
|
||||
}
|
||||
|
||||
button:focus,
|
||||
button:focus-visible {
|
||||
outline: 4px auto -webkit-focus-ring-color;
|
||||
}
|
||||
|
||||
/* Scrollbar Styles */
|
||||
::-webkit-scrollbar {
|
||||
width: 10px;
|
||||
height: 11px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: rgb(65, 66, 68);
|
||||
border: 1px solid rgb(29, 30, 32);
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: rgb(155, 156, 157);
|
||||
}
|
||||
77
src/app/index.css
Normal file
77
src/app/index.css
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
.App {
|
||||
width: 100vw;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
background-color: #262225;
|
||||
}
|
||||
|
||||
.container {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: 100vw;
|
||||
min-width: 100vw;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.left {
|
||||
width: 40%;
|
||||
min-height: 100vh;
|
||||
background-color: #373236;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 2rem;
|
||||
border-top-right-radius: 25px;
|
||||
border-bottom-right-radius: 25px;
|
||||
}
|
||||
|
||||
.right {
|
||||
flex: 1;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 2rem;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.profile {
|
||||
border-radius: 100%;
|
||||
width: 256px;
|
||||
height: 256px;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.profile:hover {
|
||||
animation: rotate 1000ms linear infinite;
|
||||
}
|
||||
|
||||
@keyframes rotate {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.container {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.left {
|
||||
width: 100%;
|
||||
min-height: auto;
|
||||
border-radius: 0;
|
||||
border-bottom-left-radius: 25px;
|
||||
border-bottom-right-radius: 25px;
|
||||
}
|
||||
.right {
|
||||
min-height: auto !important;
|
||||
}
|
||||
}
|
||||
41
src/app/layout.tsx
Normal file
41
src/app/layout.tsx
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
import type { Metadata } from "next";
|
||||
import localFont from "next/font/local";
|
||||
import "./globals.css";
|
||||
|
||||
const geistSans = localFont({
|
||||
src: "./fonts/GeistVF.woff",
|
||||
variable: "--font-geist-sans",
|
||||
weight: "100 900",
|
||||
});
|
||||
const geistMono = localFont({
|
||||
src: "./fonts/GeistMonoVF.woff",
|
||||
variable: "--font-geist-mono",
|
||||
weight: "100 900",
|
||||
});
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "imnyang",
|
||||
description: "imnyang's portfolio",
|
||||
};
|
||||
|
||||
export default function RootLayout({
|
||||
children,
|
||||
}: Readonly<{
|
||||
children: React.ReactNode;
|
||||
}>) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<head>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.6.0/css/all.min.css"
|
||||
/>
|
||||
</head>
|
||||
<body
|
||||
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
|
||||
>
|
||||
{children}
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
190
src/app/page.tsx
Normal file
190
src/app/page.tsx
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
'use client';
|
||||
|
||||
import { useEffect, useState, forwardRef } from "react";
|
||||
import { useSearchParams } from "next/navigation";
|
||||
import Link from "next/link";
|
||||
import Repos from "./components/repos";
|
||||
import Tippy from "@tippyjs/react";
|
||||
import "tippy.js/dist/tippy.css";
|
||||
import "./index.css";
|
||||
|
||||
const TippyWrapper = forwardRef<HTMLAnchorElement, any>((props, ref) => (
|
||||
<a {...props} ref={ref} />
|
||||
));
|
||||
TippyWrapper.displayName = 'TippyWrapper';
|
||||
|
||||
export default function Home() {
|
||||
const searchParams = useSearchParams();
|
||||
const [imageSrc, setImageSrc] = useState(
|
||||
"https://f.imnyang.xyz/profile/imnyang.webp",
|
||||
);
|
||||
const [gotoHref, setGotoHref] = useState("/");
|
||||
const [isMobile, setIsMobile] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setIsMobile(window.innerWidth <= 768);
|
||||
const handleResize = () => {
|
||||
setIsMobile(window.innerWidth <= 768);
|
||||
};
|
||||
window.addEventListener('resize', handleResize);
|
||||
return () => window.removeEventListener('resize', handleResize);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (searchParams.has("kawaii")) {
|
||||
setImageSrc("https://f.imnyang.xyz/profile/hatchu_imnyang.webp");
|
||||
setGotoHref("/");
|
||||
} else {
|
||||
setImageSrc("https://f.imnyang.xyz/profile/imnyang.webp");
|
||||
setGotoHref("/?kawaii");
|
||||
}
|
||||
if (searchParams.has("no_hair") && searchParams.has("no_ear")) {
|
||||
setImageSrc("https://f.imnyang.xyz/profile/no_ear_no_long_hair.png");
|
||||
} else if (searchParams.has("no_ear")) {
|
||||
setImageSrc("https://f.imnyang.xyz/profile/no_ear.png");
|
||||
} else if (searchParams.has("no_hair")) {
|
||||
setImageSrc("https://f.imnyang.xyz/profile/no_hair.avif");
|
||||
}
|
||||
if (searchParams.has("fast")) {
|
||||
const style = document.createElement("style");
|
||||
style.innerHTML = `
|
||||
.profile:hover {
|
||||
animation: rotate 1ms linear infinite;
|
||||
}
|
||||
`;
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
}, [searchParams]);
|
||||
|
||||
const SocialLink = ({ href, icon, tooltip }: { href: string; icon: string; tooltip: string }) => (
|
||||
<Tippy content={tooltip} placement="bottom">
|
||||
<TippyWrapper
|
||||
href={href}
|
||||
style={{
|
||||
color: "#b2a1af",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
}}
|
||||
>
|
||||
<i className={icon} style={{ fontSize: "24px" }} />
|
||||
</TippyWrapper>
|
||||
</Tippy>
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="App">
|
||||
<div className="container">
|
||||
<div className="left">
|
||||
<p style={{ color: "transparent" }}>/?no_hair</p>
|
||||
{/* /?no_ear */}
|
||||
<img src={imageSrc} width={256} className="profile" alt="Profile" />
|
||||
<h1
|
||||
style={{
|
||||
color: "#ffe7fb",
|
||||
fontSize: 60,
|
||||
margin: 0,
|
||||
fontWeight: "700",
|
||||
}}
|
||||
>
|
||||
<Link
|
||||
style={{
|
||||
color: "#ffe7fb",
|
||||
fontSize: 60,
|
||||
margin: 0,
|
||||
fontWeight: "700"
|
||||
}}
|
||||
href={gotoHref}
|
||||
>
|
||||
hyun._.suk
|
||||
</Link>
|
||||
</h1>
|
||||
|
||||
<div className="mt-5" style={{ color: "white" }}>
|
||||
<div style={{ textAlign: "left" }}>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
gap: 25,
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
}}
|
||||
>
|
||||
{isMobile && (
|
||||
<SocialLink
|
||||
href="supertoss://send?bank=토스뱅크&accountNo=100079352039&origin=qr"
|
||||
icon="fa-solid fa-circle-dollar-to-slot"
|
||||
tooltip="Toss"
|
||||
/>
|
||||
)}
|
||||
<SocialLink
|
||||
href="https://github.com/imnyang"
|
||||
icon="fa-brands fa-github"
|
||||
tooltip="Github"
|
||||
/>
|
||||
<SocialLink
|
||||
href="mailto:me@imnyang.xyz"
|
||||
icon="fa-solid fa-at"
|
||||
tooltip="Mail"
|
||||
/>
|
||||
<SocialLink
|
||||
href="https://instagram.com/not.furry_"
|
||||
icon="fa-brands fa-instagram"
|
||||
tooltip="Instagram"
|
||||
/>
|
||||
<SocialLink
|
||||
href="https://x.com/mahiro_me"
|
||||
icon="fa-brands fa-x-twitter"
|
||||
tooltip="X"
|
||||
/>
|
||||
</div>
|
||||
<br />
|
||||
🖥️ Software Engineer
|
||||
<br />
|
||||
🎨 Team. <a href="https://sqlare.com">Sqlare</a>
|
||||
<br />
|
||||
<br />
|
||||
📚 Middle School Student in South Korea
|
||||
<br />
|
||||
<br />
|
||||
<span style={{ color: "transparent" }}>Enter Furry.</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="right">
|
||||
<div style={{ display: "flex", flexDirection: "row", gap: 25 }}>
|
||||
<a href="https://github.com/imnyang">
|
||||
<i
|
||||
className="fa-brands fa-github"
|
||||
style={{ color: "white", paddingRight: 8 }}
|
||||
/>
|
||||
<Repos /> Repos
|
||||
</a>
|
||||
<a href="https://blog.imnyang.xyz">📝 Blog</a>
|
||||
<Link href="/timeline">🌈 Timeline</Link>
|
||||
</div>
|
||||
<div style={{ display: "flex", flexDirection: "row", gap: 25 }}>
|
||||
<p style={{ color: "white" }}>Project</p>
|
||||
</div>
|
||||
<div style={{ display: "flex", flexDirection: "row", gap: 25 }}>
|
||||
<a href="https://github.com/sqlare/sqlr.kr/tree/main">
|
||||
🔗 sqlr.kr (SQLite)
|
||||
</a>
|
||||
<a hidden href="https://qloat.com">
|
||||
🗨️ Qloat
|
||||
</a>
|
||||
</div>
|
||||
<div style={{ display: "flex", flexDirection: "row", gap: 25 }}>
|
||||
<a href="https://instagram.com/today.isangjeong">
|
||||
🥕 isangjeong.today
|
||||
</a>
|
||||
<a href="https://github.com/imnyang/FakeAlyac">💊 FakeAlyac</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
14
src/app/timeline/page.tsx
Normal file
14
src/app/timeline/page.tsx
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import Link from 'next/link';
|
||||
import Timeline from '../components/Timeline';
|
||||
|
||||
export default function Timeline_Page() {
|
||||
return (
|
||||
<div style={{ display: 'flex', overflow: 'auto', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', color: 'white', width: '100vw', height: '100vh', background: '#101020' }}>
|
||||
<div style={{height: '70%', overflow: 'auto'}}>
|
||||
<Link href='/'>🏠 Back</Link>
|
||||
<h1>Timeline</h1>
|
||||
<Timeline />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue