- apis/chat 모듈(api/queries/mutations/keys/type) + useChatController(append-only send 주입) - useChatStore 재배선, list→chat session_id 라우팅 연결, mock 제거 - 마감/종료/권한 시 입력 잠금·목록 복귀, 가격범위 인라인 에러, CHAT_IN_PROGRESS 처리 - list 마감일 KST(Asia/Seoul) 고정 표시(lib/datetime formatKstDateTime) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
56 lines
1.3 KiB
TypeScript
56 lines
1.3 KiB
TypeScript
import { useNavigate, useSearchParams, Navigate } from 'react-router'
|
|
import { List } from 'lucide-react'
|
|
import { cn, interactive } from '@/lib'
|
|
import { MainLayout, MainHeaderBar } from '@/layouts'
|
|
import { ChatContainer, ItemSection, RemainingTime } from '@/features/chat'
|
|
import { SidebarFooter } from '@/features/auth'
|
|
|
|
export function ChatPage() {
|
|
const [searchParams] = useSearchParams()
|
|
const sessionId = searchParams.get('session_id') ?? ''
|
|
|
|
// session_id 없이 진입하면 목록으로 되돌린다.
|
|
if (!sessionId) return <Navigate to="/list" replace />
|
|
|
|
return (
|
|
<MainLayout
|
|
sidebarWidth="chat"
|
|
scrollX
|
|
logoAction={<ListNavButton />}
|
|
sidebar={<Sidebar />}
|
|
header={
|
|
<MainHeaderBar className="px-[140px]">
|
|
<RemainingTime />
|
|
</MainHeaderBar>
|
|
}
|
|
>
|
|
<ChatContainer sessionId={sessionId} />
|
|
</MainLayout>
|
|
)
|
|
}
|
|
|
|
function ListNavButton() {
|
|
const navigate = useNavigate()
|
|
return (
|
|
<button
|
|
type="button"
|
|
aria-label="목록으로 이동"
|
|
onClick={() => navigate('/list')}
|
|
className={cn('text-foreground', interactive)}
|
|
>
|
|
<List size={24} />
|
|
</button>
|
|
)
|
|
}
|
|
|
|
function Sidebar() {
|
|
return (
|
|
<>
|
|
<ItemSection />
|
|
<SidebarFooter />
|
|
</>
|
|
)
|
|
}
|
|
|
|
export default ChatPage
|