Refactor Projects and Timeline components: update project details and clean up code formatting

This commit is contained in:
암냥 2025-08-17 00:25:27 +09:00
commit e861279fb8
2 changed files with 30 additions and 30 deletions

View file

@ -1,18 +1,18 @@
import ProjectsComponents from "./ProjectsComponents"; import ProjectsComponents from "./ProjectsComponents";
const projects = [ const projects = [
{
name: "EPC/broadcast",
url: "https://www.youtube.com/playlist?list=PLZeYZotn5_IOJDek6e35NKzUtJm09yxZD",
description: "Effect Playing Contest 2025의 방송화면 기능 전체를 맡았습니다.",
techStack: ["Bun", "TypeScript", "React"]
},
{ {
name: "team-neko/two_hearts", name: "team-neko/two_hearts",
url: "https://chromewebstore.google.com/detail/fhbjjhpphmigcniggnhgoepaodgoobdk?utm_source=item-share-cb", url: "https://chromewebstore.google.com/detail/fhbjjhpphmigcniggnhgoepaodgoobdk?utm_source=item-share-cb",
description: "Two Hearts는 Chrome 확장 프로그램으로, 새탭을 더 간단명료하게 보여줍니다.", description: "Two Hearts는 Chrome 확장 프로그램으로, 새탭을 더 간단명료하게 보여줍니다.",
techStack: ["Bun", "Chrome", "TypeScript", "React"] techStack: ["Bun", "Chrome", "TypeScript", "React"]
}, },
{
name: "imnyang/today.isangjeong",
url: "https://github.com/imnyang/today.isangjeong",
description: "친구들과 간단하게 학교의 급식을 공유하기 위해 고안한 프로젝트입니다.\n원래 Python으로 작성되었지만 현재는 TypeScript로 재작성되었습니다.",
techStack: ["Bun", "TypeScript", "Instagram"]
},
{ {
name: "team-neko/dynamic-kawaii", name: "team-neko/dynamic-kawaii",
url: "https://github.com/team-neko/dynamic-kawaii", url: "https://github.com/team-neko/dynamic-kawaii",

View file

@ -4,12 +4,12 @@ import { Plus } from "lucide-react";
import { useEffect, useState, useRef } from "react"; import { useEffect, useState, useRef } from "react";
const events = [ const events = [
{ {
date: "2025-07-26", date: "2025-07-26",
description: description:
"선린인터넷고 여름방학 중학생 특별교육 우수 이수 (프로그래밍)", "선린인터넷고 여름방학 중학생 특별교육 우수 이수 (프로그래밍)",
category: "Education", category: "Education",
link: "https://sunrint.sen.hs.kr/" link: "https://sunrint.sen.hs.kr/"
}, },
{ {
date: "2025-02-27", date: "2025-02-27",
@ -30,14 +30,14 @@ const events = [
description: description:
"2024 Sunrin Layer7 CTF 중등부 2위", "2024 Sunrin Layer7 CTF 중등부 2위",
category: "Award", category: "Award",
link: "https://layer7.kr" link: "https://layer7.kr"
}, },
{ {
date: "2025-01-10", date: "2025-01-10",
description: description:
"선린인터넷고 겨울방학 중학생 특별교육 이수 (IT경영학과)", "선린인터넷고 겨울방학 중학생 특별교육 이수 (IT경영학과)",
category: "Education", category: "Education",
link: "https://sunrint.sen.hs.kr/" link: "https://sunrint.sen.hs.kr/"
}, },
{ {
date: "2024-12-14", date: "2024-12-14",
@ -155,31 +155,31 @@ export default function Timeline() {
const TimelineRef = useRef<HTMLDivElement>(null); const TimelineRef = useRef<HTMLDivElement>(null);
useEffect(() => { useEffect(() => {
const observer = new IntersectionObserver( const observer = new IntersectionObserver(
([entry]) => { ([entry]) => {
if (entry.isIntersecting) { if (entry.isIntersecting) {
setIsVisible(true); setIsVisible(true);
} }
}, },
{ threshold: 0.1 } { threshold: 0.1 }
); );
if (TimelineRef.current) {
observer.observe(TimelineRef.current);
}
return () => {
if (TimelineRef.current) { if (TimelineRef.current) {
observer.observe(TimelineRef.current); observer.unobserve(TimelineRef.current);
} }
};
return () => {
if (TimelineRef.current) {
observer.unobserve(TimelineRef.current);
}
};
}, []); }, []);
useEffect(() => { useEffect(() => {
if (isVisible && count < events.length) { if (isVisible && count < events.length) {
const timer = setTimeout(() => setCount(count + 1), count === 0 ? 300 : 25); const timer = setTimeout(() => setCount(count + 1), count === 0 ? 300 : 25);
return () => clearTimeout(timer); return () => clearTimeout(timer);
} }
}, [isVisible, count]); }, [isVisible, count]);
return ( return (
@ -187,7 +187,7 @@ export default function Timeline() {
<div className="w-full"> <div className="w-full">
<h1 className="text-2xl font-bold mb-4 w-full">🌠 </h1> <h1 className="text-2xl font-bold mb-4 w-full">🌠 </h1>
<p> {count} !</p> <p> {count} !</p>
<br/> <br />
<Accordion type="multiple" className="w-full space-y-2"> <Accordion type="multiple" className="w-full space-y-2">
{Array.from(new Set(events.map(event => new Date(event.date).getFullYear()))).sort((a, b) => b - a).map(year => ( {Array.from(new Set(events.map(event => new Date(event.date).getFullYear()))).sort((a, b) => b - a).map(year => (
<AccordionItem <AccordionItem