diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d732c16..4380ec5 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -17,9 +17,11 @@ jobs: needs: checkout steps: - uses: actions/checkout@v4 - - run: pwd && ls -al + - run: cd /home/neko/Workspace/Git/imnyang/imnyang + - run: git pull - run: bun install - run: bun run build + - run: pm2 restart imnya.ng replace: name: Replace Old Build with New Build diff --git a/bun.lock b/bun.lock index 2e5e412..ed94e64 100644 --- a/bun.lock +++ b/bun.lock @@ -18,6 +18,7 @@ "react": "^19", "react-dom": "^19", "react-hook-form": "^7.54.2", + "serve-static-bun": "^0.5.3", "tailwind-merge": "^3.0.1", "tailwindcss": "^4.0.6", "tailwindcss-animate": "^1.0.7", @@ -151,6 +152,8 @@ "scheduler": ["scheduler@0.25.0", "", {}, "sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA=="], + "serve-static-bun": ["serve-static-bun@0.5.3", "", {}, "sha512-QlfA/Z30MwZl4XXWM9KevfinJRJjzJMRK8sXABbaY06Y7KTuXtbT1n0e8qdf1PgM59mpgSh/JTUM9Jjsh0E58Q=="], + "tailwind-merge": ["tailwind-merge@3.0.1", "", {}, "sha512-AvzE8FmSoXC7nC+oU5GlQJbip2UO7tmOhOfQyOmPhrStOGXHU08j8mZEHZ4BmCqY5dWTCo4ClWkNyRNx1wpT0g=="], "tailwindcss": ["tailwindcss@4.0.8", "", {}, "sha512-Me7N5CKR+D2A1xdWA5t5+kjjT7bwnxZOE6/yDI/ixJdJokszsn2n++mdU5yJwrsTpqFX2B9ZNMBJDwcqk9C9lw=="], diff --git a/package.json b/package.json index c00093e..b8a6e0d 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "react": "^19", "react-dom": "^19", "react-hook-form": "^7.54.2", + "serve-static-bun": "^0.5.3", "tailwind-merge": "^3.0.1", "tailwindcss": "^4.0.6", "tailwindcss-animate": "^1.0.7", diff --git a/src/App.tsx b/src/App.tsx index f19f358..7b7380b 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -25,7 +25,7 @@ export function App() { scrollToHash(); // 스크롤 시 hash 업데이트 로직 - const sections = document.querySelectorAll(".section"); + const sections = document.querySelectorAll(".hash"); const observer = new IntersectionObserver( (entries) => { entries.forEach(entry => { @@ -34,7 +34,7 @@ export function App() { } }); }, - { threshold: 0.6 } // 60% 보이면 활성화 + { threshold: 0.9 } // 90% 보이면 활성화 ); sections.forEach(section => observer.observe(section)); @@ -44,10 +44,11 @@ export function App() { }; }, []); + useEffect(() => { // img 위에서 스크롤 방지 - const handleWheel = (event) => { - if (event.target.tagName.toLowerCase() === "img") { + const handleWheel = (event: WheelEvent) => { + if (event.target instanceof HTMLImageElement) { event.preventDefault(); } }; @@ -60,23 +61,23 @@ export function App() { }, []); return ( -
-
+
+
{/* stupid copliot this is not section */}
-
+
{/* Hey Stupid Copliot This is section */}
-
+
{/* Hey Stupid Copliot This is section */}
-
+
{/* Hey Stupid Copliot This is section */}
-
+
{/* Hey Stupid Copliot This is section */}
-
+
{/* Hey Stupid Copliot This is section */}
diff --git a/src/components/Home/About.tsx b/src/components/Home/About.tsx index 0614a50..91c6302 100644 --- a/src/components/Home/About.tsx +++ b/src/components/Home/About.tsx @@ -63,15 +63,29 @@ export default function About() { }, []); useEffect(() => { - // isVisible이 true일 때 time 증가 - if (isVisible && time < totalSeconds) { - const timer = setTimeout(() => setTime(prevTime => prevTime + 1), time === 0 ? 300 : 0); - return () => clearTimeout(timer); - } - }, [isVisible, time, totalSeconds]); - + if (!isVisible) return; + + const start = Date.now() - time; + + let animationFrameId: number; + + const tick = () => { + const elapsed = Date.now() - start; + if (elapsed >= totalSeconds) { + setTime(totalSeconds); + return; + } + setTime(elapsed); + animationFrameId = requestAnimationFrame(tick); + }; + + animationFrameId = requestAnimationFrame(tick); + + return () => cancelAnimationFrame(animationFrameId); + }, [isVisible, totalSeconds]); + return ( -
+

🤔 About

diff --git a/src/components/Home/Contact.tsx b/src/components/Home/Contact.tsx index dfa4ba9..6bd8a90 100644 --- a/src/components/Home/Contact.tsx +++ b/src/components/Home/Contact.tsx @@ -9,7 +9,7 @@ import { Button } from "../ui/button"; export default function Contact() { return ( -
+
diff --git a/src/components/Home/Project.tsx b/src/components/Home/Project.tsx index f8a727e..973ee3f 100644 --- a/src/components/Home/Project.tsx +++ b/src/components/Home/Project.tsx @@ -25,7 +25,7 @@ const projects = [ export default function Project() { return ( -
+

📖 Project

diff --git a/src/components/Home/Timeline.tsx b/src/components/Home/Timeline.tsx index d3a0b46..ae807cb 100644 --- a/src/components/Home/Timeline.tsx +++ b/src/components/Home/Timeline.tsx @@ -181,7 +181,7 @@ export default function Timeline() {

🌠 Timeline

현재까지 {count}개의 개성있는 조각들이 모였어요!


- + {Array.from(new Set(events.map(event => new Date(event.date).getFullYear()))).sort((a, b) => b - a).map(year => ( - + {events.filter(event => new Date(event.date).getFullYear() === year).map((event, index) => (

{new Date(event.date).toLocaleDateString('en-US', { month: 'short', day: '2-digit' })}

ㆍ{event.category}

diff --git a/src/components/Home/Wakatime.tsx b/src/components/Home/Wakatime.tsx index f61d751..928d875 100644 --- a/src/components/Home/Wakatime.tsx +++ b/src/components/Home/Wakatime.tsx @@ -15,7 +15,7 @@ export default function Wakatime() { }, []); return ( -
+
🍝 Wakatime

Dashboards for developers

diff --git a/src/flag_kr.svg b/src/flag_kr.svg deleted file mode 100644 index 18f9c7a..0000000 --- a/src/flag_kr.svg +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/index.css b/src/index.css index cb32963..f324e4e 100644 --- a/src/index.css +++ b/src/index.css @@ -1,21 +1,13 @@ @import "../styles/globals.css"; -#fullpage { - scroll-snap-type: y mandatory; - overflow-y: scroll; - height: 100vh; -} .section { - scroll-snap-align: start; - min-height: 100vh; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; + @apply py-16 border-b-1 border-muted; } @layer base { - body { - @apply min-h-screen m-0 p-0 overflow-hidden; + html, + body, + #root { + @apply h-full m-0 p-0; } -} \ No newline at end of file +} diff --git a/src/index.html b/src/index.html index 23838f7..f1050d6 100644 --- a/src/index.html +++ b/src/index.html @@ -12,7 +12,7 @@ 남현석 | :two_hearts: - ' +
diff --git a/src/index.tsx b/src/index.tsx index d8d1dc8..06e8e9a 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,16 +1,27 @@ import { serve } from "bun"; import index from "./index.html"; +import serveStatic from "serve-static-bun"; + +// Parse command line arguments for port +const args = process.argv.slice(2); +const portArgIndex = args.findIndex(arg => arg === "--port"); +const port = portArgIndex !== -1 && args[portArgIndex + 1] ? + parseInt(args[portArgIndex + 1]) : 3000; const server = serve({ + port: port, routes: { // Serve index.html for all unmatched routes. "/*": index, - '/timeline': Response.redirect("/#timeline"), - '/ads.txt': new Response("google.com, pub-4588517451789913, DIRECT, f08c47fec0942fa0", { - headers: { - "content-type": "text/plain", + "/timeline": Response.redirect("/#timeline"), + "/ads.txt": new Response( + "google.com, pub-4588517451789913, DIRECT, f08c47fec0942fa0", + { + headers: { + "content-type": "text/plain", + }, }, - }), + ), }, development: process.env.NODE_ENV !== "production", });