diff --git a/README.md b/README.md index f3604da..742cda8 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,14 @@ stash 프로젝트의 프론트엔드 애플리케이션 ## Recent Changes -[![v0.0.6](https://img.shields.io/badge/v0.0.6-purple)](./docs/CHANGELOG.md#v006) `2025.11.30 15:00` +[![v0.0.7](https://img.shields.io/badge/v0.0.7-purple)](./docs/CHANGELOG.md#v007) `2025.11.30 16:30` +- 404 Not Found 페이지 추가 (터미널 스타일 UI) +- 500 Error 페이지 추가 (retry 버튼, 5초 카운트다운) +- Global Error 페이지 추가 (root layout 에러 처리) +- 에러 발생 시 자동 리다이렉트 (같은 도메인 = 뒤로가기, 외부 = 홈으로) +- 터미널 한글 입력 시 너비 계산 수정 + +[![v0.0.6](https://img.shields.io/badge/v0.0.6-gray)](./docs/CHANGELOG.md#v006) `2025.11.30 15:00` - Tab/→/Enter 키로 명령어 자동완성 - 힌트 목록 세로 표시 (여러 개일 때) - ↑/↓ 키로 힌트 목록 탐색 diff --git a/app/error.tsx b/app/error.tsx new file mode 100644 index 0000000..a0965dd --- /dev/null +++ b/app/error.tsx @@ -0,0 +1,70 @@ +'use client' + +import { useEffect, useState } from 'react' +import { useRouter } from 'next/navigation' + +export default function Error({ + error, + reset, +}: { + error: Error & { digest?: string } + reset: () => void +}) { + const router = useRouter() + const [countdown, setCountdown] = useState(5) + + useEffect(() => { + console.error(error) + }, [error]) + + useEffect(() => { + const timer = setInterval(() => { + setCountdown(prev => { + if (prev <= 1) { + clearInterval(timer) + if (document.referrer && new URL(document.referrer).origin === window.location.origin) { + router.back() + } else { + router.push('/') + } + return 0 + } + return prev - 1 + }) + }, 1000) + + return () => clearInterval(timer) + }, [router]) + + return ( +
+
+
+
+
+
+ error — 500 +
+
+
+ ~ + $ + ./run +
+
+ Error: Something went wrong +
+
+ + Redirecting in {countdown}... +
+
+
+
+ ) +} diff --git a/app/global-error.tsx b/app/global-error.tsx new file mode 100644 index 0000000..ec6d251 --- /dev/null +++ b/app/global-error.tsx @@ -0,0 +1,44 @@ +'use client' + +export default function GlobalError({ + error: _error, + reset, +}: { + error: Error & { digest?: string } + reset: () => void +}) { + return ( + + +
+
+
+
+
+
+ error — fatal +
+
+
+ ~ + $ + ./init +
+
+ Fatal: Application crashed +
+
+ +
+
+
+
+ + + ) +} diff --git a/app/not-found.tsx b/app/not-found.tsx new file mode 100644 index 0000000..dca0287 --- /dev/null +++ b/app/not-found.tsx @@ -0,0 +1,57 @@ +'use client' + +import { useEffect, useState } from 'react' +import { useRouter } from 'next/navigation' + +export default function NotFound() { + const router = useRouter() + const [countdown, setCountdown] = useState(3) + + useEffect(() => { + const timer = setInterval(() => { + setCountdown(prev => { + if (prev <= 1) { + clearInterval(timer) + // 같은 도메인에서 왔으면 뒤로가기, 아니면 홈으로 + if (document.referrer && new URL(document.referrer).origin === window.location.origin) { + router.back() + } else { + router.push('/') + } + return 0 + } + return prev - 1 + }) + }, 1000) + + return () => clearInterval(timer) + }, [router]) + + return ( +
+
+
+
+
+
+ error — 404 +
+
+
+ ~ + $ + find /page +
+
+ find: /page: No such file or directory +
+
+ ~ + $ + Redirecting in {countdown}... +
+
+
+
+ ) +} diff --git a/app/page.tsx b/app/page.tsx index 9b0716e..335e987 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -492,7 +492,7 @@ export default function Home() { onChange={(e) => setInputValue(e.target.value)} onKeyDown={handleKeyDown} className="bg-transparent outline-none caret-[#c9d1d9] placeholder:text-[#484f58]" - style={{ width: inputValue ? `${inputValue.length}ch` : '22ch' }} + style={{ width: inputValue ? `${[...inputValue].reduce((w, c) => w + (c.charCodeAt(0) > 127 ? 2 : 1), 0)}ch` : '22ch' }} spellCheck={false} autoComplete="off" placeholder="type 'help' for commands" diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 7029901..f55830c 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -4,6 +4,19 @@ +## v0.0.7 +`2025.11.30 16:30` + +에러 페이지 추가 및 한글 입력 너비 수정 + +- 404 Not Found 페이지 추가 (터미널 스타일 UI) +- 500 Error 페이지 추가 (retry 버튼, 5초 카운트다운) +- Global Error 페이지 추가 (root layout 에러 처리) +- 에러 발생 시 자동 리다이렉트 (같은 도메인이면 뒤로가기, 아니면 홈으로) +- 터미널 한글 입력 시 너비 계산 수정 (charCode > 127 = 2ch) + +--- + ## v0.0.6 `2025.11.30 15:00` diff --git a/package.json b/package.json index 49b7ad6..3fbce8e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pixel", - "version": "0.0.6", + "version": "0.0.7", "private": true, "scripts": { "dev": "next dev",