diff --git a/public/icon/mizuki.svg b/public/icon/mizuki.svg deleted file mode 100644 index ee95759..0000000 --- a/public/icon/mizuki.svg +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/public/icon/project-sekai.webp b/public/icon/project-sekai.webp deleted file mode 100644 index 75b4baa..0000000 Binary files a/public/icon/project-sekai.webp and /dev/null differ diff --git a/public/icon/steam.svg b/public/icon/steam.svg deleted file mode 100644 index affefa5..0000000 --- a/public/icon/steam.svg +++ /dev/null @@ -1 +0,0 @@ -Steam \ No newline at end of file diff --git a/public/icon/vrchat.svg b/public/icon/vrchat.svg deleted file mode 100644 index 0c4a3ea..0000000 --- a/public/icon/vrchat.svg +++ /dev/null @@ -1 +0,0 @@ -VRChat \ No newline at end of file diff --git a/public/projects/epc-finale.avif b/public/projects/epc-finale.avif deleted file mode 100644 index 78462bd..0000000 Binary files a/public/projects/epc-finale.avif and /dev/null differ diff --git a/src/components/About.astro b/src/components/About.astro index f4f5a49..7ed6612 100644 --- a/src/components/About.astro +++ b/src/components/About.astro @@ -1,27 +1,25 @@ --- import { events } from "@/lib/events"; -import AboutRow from "@/components/AboutRow.astro"; -import DDay from "./DDay.astro"; const sortedEvents = [...events].sort((a, b) => b.date.localeCompare(a.date)); const years = [...new Set(sortedEvents.map((event) => event.date.slice(0, 4)))]; // biome-ignore lint/correctness/noUnusedVariables: Used in the Astro template below. const eventsByYear = years.map((year) => ({ - year, - events: sortedEvents.filter((event) => event.date.startsWith(year)), + year, + events: sortedEvents.filter((event) => event.date.startsWith(year)), })); // biome-ignore lint/correctness/noUnusedVariables: Used in the Astro template below. const getShortDate = (date: string) => { - const [, month, day] = date.split("-"); - return `${month}.${day}`; + const [, month, day] = date.split("-"); + return `${month}.${day}`; }; const currentYear = new Date().getFullYear(); // biome-ignore lint/correctness/noUnusedVariables: Used in the Astro template below. const daysUntilYearEnd = Math.ceil( - (new Date(currentYear + 1, 0, 1).getTime() - Date.now()) / - (1000 * 60 * 60 * 24), + (new Date(currentYear + 1, 0, 1).getTime() - Date.now()) / + (1000 * 60 * 60 * 24), ); --- @@ -33,101 +31,103 @@ const daysUntilYearEnd = Math.ceil( >
-

- 안녕하세요, 정보보안과 소프트웨어 엔지니어링을 주로하고 있는 - 암냥입니다. -

-
- 생일 : -
- - 연락하기 - - -
-

저는...

-
-
- - - 선린인터넷고등학교 정보보안 동아리 - - Layer7 - +
+

+ 저는 {years.length}년간 {events.length}개의 + 개성있는 조각들을 모아왔어요. +

- - - 선린인터넷고등학교 정보보호과 - - - - ADOFAI.gg Development Team - - - - 화이트햇스쿨 3기 이수 - -
-
-
- 등등... - -

을 이루어냈어요.

+
+ { + eventsByYear.map(({ year, events: yearEvents }) => ( +
+
+

+ {year} +

+ + {yearEvents.length}{" "} + {yearEvents.length === 1 + ? "EVENT" + : "EVENTS"} + +
+
+ +
    + {yearEvents.map((event) => ( +
  1. + +
    +
    + + {event.category} + + {event.link && ( + + )} +
    + {event.link ? ( + + {event.description} + + ) : ( +

    + {event.description} +

    + )} +
    +
  2. + ))} +
+ {year === currentYear.toString() && ( +
+
+ + ✨ | D-{daysUntilYearEnd}동안 + 만들어나갈 멋진 것들을 + 기대해주세요. + +
+
+ )} +
+ )) + } +
@@ -135,13 +135,13 @@ const daysUntilYearEnd = Math.ceil( class="relative order-first h-[min(150vw,720px)] min-h-[600px] overflow-hidden lg:sticky lg:top-0 lg:order-none lg:h-[calc(100svh-64px)] lg:min-h-0 lg:self-start" aria-label="활동 사진" > - + />
diff --git a/src/components/ContactSection.astro b/src/components/ContactSection.astro deleted file mode 100644 index c86c338..0000000 --- a/src/components/ContactSection.astro +++ /dev/null @@ -1,583 +0,0 @@ ---- -// biome-ignore lint/correctness/noUnusedVariables: Used in the Astro template below. -const groups = [ - { - id: "direct", - title: "연락처", - items: [ - { - name: "개인 이메일", - value: "me@imnya.ng", - href: "mailto:me@imnya.ng", - icon: "mail", - tone: "pink", - email: true, - }, - { - name: "dazzle.st 이메일", - value: "imnyang@dazzle.st", - href: "mailto:imnyang@dazzle.st", - icon: "mail", - tone: "green", - email: true, - }, - { - name: "Discord", - value: "@imnyang", - href: "https://discord.com/users/909353223901569035", - icon: "discord", - tone: "purple", - }, - ], - }, - { - id: "social", - title: "소셜", - items: [ - { - name: "X (Twitter)", - value: "@imnya_ng", - href: "https://twitter.com/imnya_ng", - icon: "x", - tone: "blue", - }, - { - name: "Instagram", - value: "@imnya.ng", - href: "https://instagram.com/imnya.ng", - icon: "instagram", - tone: "pink", - }, - { - name: "YouTube", - value: "@imnyang", - href: "https://youtube.com/@imnyang", - icon: "youtube", - tone: "red", - }, - ], - }, - { - id: "work", - title: "코드와 글", - items: [ - { - name: "GitHub", - value: "@imnyang", - href: "https://github.com/imnyang", - icon: "github", - tone: "neutral", - }, - { - name: "git.mizuki.guru", - value: "@imnyang", - href: "https://git.mizuki.guru/imnyang", - icon: "mizuki", - tone: "orange", - }, - { - name: "Blog", - value: "blog.imnya.ng", - href: "https://blog.imnya.ng", - icon: "blog", - tone: "green", - }, - ], - }, - { - id: "game", - title: "Game", - items: [ - { - name: "Steam", - value: "@imnyang", - href: "https://steamcommunity.com/id/imnyang/", - icon: "steam", - tone: "blue", - }, - { - name: "maimai", - value: "@imnya.ng", - href: "https://mai.sft.sh/imnyang", - icon: "maimai", - tone: "blue", - }, - { - name: "Project Sekai KR", - value: "7354623251148069648", - href: "#", - icon: "project-sekai", - tone: "blue", - }, - { - name: "Project Sekai JP", - value: "729310364018688008", - href: "#", - icon: "project-sekai", - tone: "blue", - }, - { - name: "VRChat", - value: "@imnyang", - href: "https://vrchat.com/home/user/usr_d53ac697-182d-40d0-9fd8-1a7442b0ebfd", - icon: "vrchat", - tone: "blue", - }, - ], - }, -]; - -// biome-ignore lint/correctness/noUnusedVariables: Used in the Astro template below. -const imageIcons: Record = { - github: { src: "/icon/github.svg", monochrome: true }, - discord: { src: "/icon/discord.svg", monochrome: true }, - mizuki: { src: "/icon/mizuki.svg", monochrome: false }, - // Source: https://github.com/simple-icons/simple-icons/blob/develop/icons/steam.svg - steam: { src: "/icon/steam.svg", monochrome: true }, - maimai: { src: "/icon/maimai.webp", monochrome: false }, - vrchat: { src: "/icon/vrchat.svg", monochrome: true }, - // Source: https://pjsekai.sega.jp/assets/data/webp/icon/icon_app.png.webp - "project-sekai": { src: "/icon/project-sekai.webp", monochrome: false }, -}; - -// biome-ignore lint/correctness/noUnusedVariables: Used in the Astro template below. -const paths: Record = { - mail: "M22 12a10 10 0 1 0-4 8 M16 8v5a3 3 0 0 0 6 0v-1 M16 12a4 4 0 1 1-8 0 4 4 0 0 1 8 0", - x: "M4 3h4l12 18h-4L4 3Z M20 3l-7 8 M4 21l7-8", - instagram: - "M7 3h10a4 4 0 0 1 4 4v10a4 4 0 0 1-4 4H7a4 4 0 0 1-4-4V7a4 4 0 0 1 4-4Z M16 12a4 4 0 1 1-8 0 4 4 0 0 1 8 0 M17.5 6.5h.01", - youtube: - "M7 5h10a5 5 0 0 1 5 5v4a5 5 0 0 1-5 5H7a5 5 0 0 1-5-5v-4a5 5 0 0 1 5-5Z M10 9l5 3-5 3V9Z", - blog: "M5 3h11l3 3v15H5V3Z M15 3v4h4 M9 11h6 M9 15h6", -}; ---- - -
-
-
-

Contact

-

- 새로운 이야기와 재미있는 만남은 언제나 환영해요. -

-
- -
- { - groups.map((group) => ( -
-

- {group.title} -

- -
- )) - } -
- -

-

-
-
- - - - diff --git a/src/components/DDay.astro b/src/components/DDay.astro index 2ffac2a..a7ed4a9 100644 --- a/src/components/DDay.astro +++ b/src/components/DDay.astro @@ -1,31 +1,27 @@ --- export interface Props { - targetDate: string; - label?: string; + targetDate: string; + label: string; } const { targetDate, label } = Astro.props; --- -
- {label && `${label} | `}{ - new Date(targetDate).toLocaleDateString() - } - D-Day +
+ D-Day + {label} | {new Date(targetDate).toDateString()}
diff --git a/src/components/EPCProjects.astro b/src/components/EPCProjects.astro index b477917..a5b3ef4 100644 --- a/src/components/EPCProjects.astro +++ b/src/components/EPCProjects.astro @@ -24,7 +24,7 @@ const roles = ["Broadcast Manager", "ARG Creator", "Developer"]; class="mt-6 max-w-[32rem] text-base leading-relaxed text-foreground/65" > 불과 얼음의 춤(A Dance of Fire and Ice)의 이펙트 제작과 - 플레이를
함께 다루는 대회, Effect Playing Contest. 2025와 + 플레이를 함께 다루는 대회, Effect Playing Contest. 2025와 Finale 시즌에 참여하며 방송부터 ARG, 개발까지 함께했어요.

    썸네일 후기 영상 - + >Finale 결승 방송 02:19:26부터 재생
b.date.localeCompare(a.date)); -const years = [...new Set(sortedEvents.map((event) => event.date.slice(0, 4)))]; -// biome-ignore lint/correctness/noUnusedVariables: Used in the Astro template below. -const eventsByYear = years.map((year) => ({ - year, - events: sortedEvents.filter((event) => event.date.startsWith(year)), -})); - -// biome-ignore lint/correctness/noUnusedVariables: Used in the Astro template below. -const getShortDate = (date: string) => { - const [, month, day] = date.split("-"); - return `${month}.${day}`; -}; - -const currentYear = new Date().getFullYear(); -// biome-ignore lint/correctness/noUnusedVariables: Used in the Astro template below. -const daysUntilYearEnd = Math.ceil( - (new Date(currentYear + 1, 0, 1).getTime() - Date.now()) / - (1000 * 60 * 60 * 24), -); ---- - -
-
-
-
-

- 저는 {years.length}년간 {events.length}개의 개성있는 - 조각들을 모아왔어요. -

- -
- { - eventsByYear.map(({ year, events: yearEvents }) => ( -
-
-

- {year} -

- - {yearEvents.length}{" "} - {yearEvents.length === 1 - ? "EVENT" - : "EVENTS"} - -
-
- -
    - {yearEvents.map((event) => ( -
  1. - -
    -
    - - {event.category} - - {event.link && ( - - )} -
    - {event.link ? ( - - {event.description} - - ) : ( -

    - {event.description} -

    - )} -
    -
  2. - ))} -
- {year === currentYear.toString() && ( -
-
- - ✨ | D-{daysUntilYearEnd}동안 - 만들어나갈 멋진 것들을 기대해주세요. - -
-
- )} -
- )) - } -
-
-
- -
- 활동 사진 콜라주 -
-
-
diff --git a/src/components/AboutRow.astro b/src/components/ExperienceRow.astro similarity index 100% rename from src/components/AboutRow.astro rename to src/components/ExperienceRow.astro diff --git a/src/components/Hero.astro b/src/components/Hero.astro index 0acf597..bffe7ce 100644 --- a/src/components/Hero.astro +++ b/src/components/Hero.astro @@ -22,11 +22,11 @@ 현실{"로 만들어나가는 "} - 로 만들어나가는 - 암냥입니다. diff --git a/src/components/Projects.astro b/src/components/Projects.astro new file mode 100644 index 0000000..2ff7c9a --- /dev/null +++ b/src/components/Projects.astro @@ -0,0 +1,97 @@ +--- +const projects = [ + { + name: 'EPC : Finale Broadcast Manager & Developer', + url: 'https://www.youtube.com/playlist?list=PLZeYZotn5_IPFvDUWdEUu9xOBwOkdZ0F0', + desc: 'ADOFAI is web-scale', + detail: '달성이 주관하고 ADOFAI.gg가 공동 주최하는 Effect Playing Contest : Finale의 방송 화면 및 ARG를 담당하였습니다.', + tags: ['React', 'ElysiaJS'], + }, + { + name: 'EPC 2025 Broadcast Manager', + url: 'https://www.youtube.com/playlist?list=PLZeYZotn5_IOJDek6e35NKzUtJm09yxZD', + desc: 'ADOFAI is web-scale', + detail: '달성이 주관하고 ADOFAI.gg가 공동 주최하는 Effect Playing Contest 2025 방송 화면의 대부분의 기능을 개발하였습니다.', + tags: ['React', 'ElysiaJS'], + }, + { + name: 'newsletter', + url: 'https://github.com/imnyang/newsletter', + desc: 'For Memos', + detail: '그저 이메일이 오면 Discord 웹훅으로 포워딩합니다.', + tags: ['Rust', 'IMAP'] + }, + { + name: 'memos-rss', + url: 'https://github.com/imnyang/memos-rss', + desc: 'For Memos', + detail: 'Discord 포럼 채널에 RSS 피드에 올라온 내용을 포워딩합니다.', + tags: ['Rust', 'Discord Bot', 'RSS'] + }, + { + name: 'today.isangjeong', + url: 'https://instagram.com/today.isangjeong', + desc: 'Instagram Bot', + detail: '매일 학교의 급식 메뉴를 자동으로 업로드하는 인스타그램 봇입니다.', + tags: ['TypeScript', 'Instagram', '@napi-rs/canvas'] + } +]; +--- + +
+
+ {projects.map((project, idx) => ( +
= 3 ? 'hidden' : ''}`}> +
+
+ {project.url ? ( + + {project.name} + + + ) : ( + {project.name} + )} + {project.desc} +
+
+

{project.detail}

+
+
+
+ {project.tags.map((tag) => ( + {tag} + ))} +
+
+ ))} +
+ {projects.length > 3 && ( + + )} +
+ + diff --git a/src/components/Timeline.astro b/src/components/Timeline.astro new file mode 100644 index 0000000..ed22b97 --- /dev/null +++ b/src/components/Timeline.astro @@ -0,0 +1,135 @@ +--- +import { events } from "@/lib/events"; + +const years = [ + ...new Set(events.map((e) => new Date(e.date).getFullYear())), +].sort((a, b) => b - a); + +const eventsByYear: Record = {}; +for (const year of years) { + eventsByYear[year] = events.filter( + (e) => new Date(e.date).getFullYear() === year, + ); +} + +const currentYear = new Date().getFullYear(); +const daysUntilYearEnd = Math.ceil( + (new Date(currentYear + 1, 0, 1).getTime() - new Date().getTime()) / + (1000 * 60 * 60 * 24), +); +--- + +
+
+
+ +
+ { + years.map((year, i) => ( + + )) + } +
+ + +
+ { + years.map((year, i) => ( +
+ {eventsByYear[year].map((event) => ( +
+
+ + {new Date(event.date).toLocaleDateString("en-US", { + month: "short", + day: "2-digit", + })} + + + ㆍ{event.category} + +
+ {event.link ? ( + + {event.description}{" "} + + + + + + ) : ( + {event.description} + )} +
+ ))} + {year === currentYear && ( +
+
+ + ✨ | D-{daysUntilYearEnd}동안 만들어나갈 멋진 것들을 + 기대해주세요. + +
+
+ )} +
+ )) + } +
+
+
+
+ + diff --git a/src/pages/index.astro b/src/pages/index.astro index 06a5d54..50b0680 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -1,8 +1,6 @@ --- import About from "@/components/About.astro"; -import ContactSection from "@/components/ContactSection.astro"; import EPCProjects from "@/components/EPCProjects.astro"; -import Experience from "@/components/Experience.astro"; import Header from "@/components/Header.astro"; import Hero from "@/components/Hero.astro"; import "@/globals.css"; @@ -41,8 +39,6 @@ import "@/globals.css"; - -