feat: 일지 작성화면 및 일지 화면

This commit is contained in:
2026-02-13 11:36:44 +09:00
parent 15c2100ba2
commit e9bd08c75d
2 changed files with 130 additions and 0 deletions

68
src/app/log/[id]/page.tsx Normal file
View File

@@ -0,0 +1,68 @@
'use client';
import { useEffect, useState, use } from 'react';
import { useRouter } from 'next/navigation';
import Link from 'next/link';
import { getHistory } from '@/lib/store';
import { Voyage } from '@/types';
export default function LogDetailPage({ params }: { params: Promise<{ id: string }> }) {
// Next.js 15: params is a Promise
const resolvedParams = use(params);
const router = useRouter();
const [log, setLog] = useState<Voyage | null>(null);
useEffect(() => {
const history = getHistory();
const found = history.find(item => item.id === resolvedParams.id);
if (found) setLog(found);
}, [resolvedParams.id]);
if (!log) return <div className="p-6 text-slate-500">Loading or Not Found...</div>;
return (
<div className="flex flex-col flex-1 p-6 space-y-8 animate-in fade-in duration-300">
<header className="border-b border-slate-800 pb-4">
<Link href="/log" className="text-sm text-indigo-400 hover:text-indigo-300 mb-4 inline-block">&larr; </Link>
<h1 className="text-2xl font-bold text-white">{log.missionText}</h1>
<div className="flex gap-3 mt-2 text-sm text-slate-500">
<span>{new Date(log.startedAt).toLocaleString()}</span>
<span></span>
<span>{log.routeName} ({log.durationMinutes}m)</span>
</div>
</header>
<div className="space-y-6">
<div className="bg-slate-900/30 p-4 rounded-lg border border-slate-800/50">
<h3 className="text-xs font-bold text-slate-500 uppercase tracking-wider mb-2"> </h3>
<p className="text-lg text-indigo-100">
{log.status === 'completed' && '✅ 계획대로'}
{log.status === 'partial' && '🌓 부분 진행'}
{log.status === 'reoriented' && '🧭 방향 재설정'}
{log.status === 'aborted' && '🚨 조기 귀환'}
{log.status === 'in_progress' && '진행 중'}
</p>
</div>
<div className="grid gap-6 sm:grid-cols-2">
<div>
<h3 className="text-xs font-bold text-slate-500 uppercase tracking-wider mb-2"> </h3>
<p className="text-slate-300 leading-relaxed bg-slate-900/20 p-3 rounded">{log.debriefProgress || '-'}</p>
</div>
<div>
<h3 className="text-xs font-bold text-slate-500 uppercase tracking-wider mb-2"> </h3>
<p className="text-slate-300 leading-relaxed bg-slate-900/20 p-3 rounded">{log.nextAction || '-'}</p>
</div>
</div>
{log.notes && (
<div>
<h3 className="text-xs font-bold text-slate-500 uppercase tracking-wider mb-2"> </h3>
<p className="text-slate-400 text-sm italic">"{log.notes}"</p>
</div>
)}
</div>
</div>
);
}

62
src/app/log/page.tsx Normal file
View File

@@ -0,0 +1,62 @@
'use client';
import { useEffect, useState } from 'react';
import Link from 'next/link';
import { getHistory } from '@/lib/store';
import { Voyage, VoyageStatus } from '@/types';
export default function LogListPage() {
const [logs, setLogs] = useState<Voyage[]>([]);
useEffect(() => {
setLogs(getHistory());
}, []);
const getStatusLabel = (s: VoyageStatus) => {
switch(s) {
case 'completed': return '✅ 계획대로';
case 'partial': return '🌓 부분 진행';
case 'reoriented': return '🧭 방향 재설정';
case 'aborted': return '🚨 조기 귀환';
default: return '진행 중';
}
};
return (
<div className="flex flex-col flex-1 p-6">
<h1 className="text-xl font-bold text-slate-100 mb-6"> </h1>
{logs.length === 0 ? (
<div className="flex flex-col items-center justify-center flex-1 py-20 text-slate-500 border border-dashed border-slate-800 rounded-xl">
<p className="mb-4"> .</p>
<Link href="/" className="text-indigo-400 hover:text-indigo-300 underline">
</Link>
</div>
) : (
<div className="grid gap-3">
{logs.map((log) => (
<Link
key={log.id}
href={`/log/${log.id}`}
className="block bg-slate-900/50 border border-slate-800 hover:border-slate-600 rounded-lg p-4 transition-colors"
>
<div className="flex justify-between items-start mb-1">
<span className="text-xs text-slate-500">
{new Date(log.startedAt).toLocaleDateString()}
</span>
<span className="text-xs font-medium text-slate-400 bg-slate-800 px-1.5 py-0.5 rounded">
{getStatusLabel(log.status)}
</span>
</div>
<h3 className="font-semibold text-slate-200 truncate mb-1">
{log.missionText}
</h3>
<p className="text-xs text-slate-500">{log.routeName} · {log.durationMinutes}min</p>
</Link>
))}
</div>
)}
</div>
);
}