From 0d5c3f88a8404e77535febbfa2713f3005c7c628 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=95=94=EB=83=90?= Date: Sun, 6 Sep 2026 12:53:39 +0900 Subject: [PATCH] wow --- src/components/About.astro | 163 +++++++----------- .../{ExperienceRow.astro => AboutRow.astro} | 0 src/components/EPCProjects.astro | 4 +- src/components/Experience.astro | 146 ++++++++++++++++ src/components/Hero.astro | 6 +- src/components/Projects.astro | 97 ----------- src/components/Timeline.astro | 135 --------------- 7 files changed, 212 insertions(+), 339 deletions(-) rename src/components/{ExperienceRow.astro => AboutRow.astro} (100%) create mode 100644 src/components/Experience.astro delete mode 100644 src/components/Projects.astro delete mode 100644 src/components/Timeline.astro diff --git a/src/components/About.astro b/src/components/About.astro index 7ed6612..6a53488 100644 --- a/src/components/About.astro +++ b/src/components/About.astro @@ -1,25 +1,26 @@ --- import { events } from "@/lib/events"; +import AboutRow from "@/components/AboutRow.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), ); --- @@ -31,104 +32,62 @@ const daysUntilYearEnd = Math.ceil( >
-
-

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

+

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

+

저는...

+
+
+ + + 선린인터넷고등학교 정보보안 동아리 + + Layer7 + -
- { - 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}동안 - 만들어나갈 멋진 것들을 - 기대해주세요. - -
-
- )} -
- )) - } -
-
+ + + 선린인터넷고등학교 정보보호과 + + + + ADOFAI.gg Development Team + + + + 화이트햇스쿨 3기 이수 + +
+ +

불과 얼음의 춤(A Dance of Fire and Ice)의 이펙트 제작과 - 플레이를 함께 다루는 대회, Effect Playing Contest. 2025와 + 플레이를
함께 다루는 대회, Effect Playing Contest. 2025와 Finale 시즌에 참여하며 방송부터 ARG, 개발까지 함께했어요.

    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/Hero.astro b/src/components/Hero.astro index bffe7ce..0acf597 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 deleted file mode 100644 index 2ff7c9a..0000000 --- a/src/components/Projects.astro +++ /dev/null @@ -1,97 +0,0 @@ ---- -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 deleted file mode 100644 index ed22b97..0000000 --- a/src/components/Timeline.astro +++ /dev/null @@ -1,135 +0,0 @@ ---- -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}동안 만들어나갈 멋진 것들을 - 기대해주세요. - -
    -
    - )} -
    - )) - } -
    -
    -
    -
    - -