import { redirect } from 'next/navigation'; import { getCurrentUser, toPublicUser } from '@/lib/auth/getCurrentUser'; import { createSearchService, createProjectService } from '@/lib/api/services'; import { Header } from '@/components/layout/Header'; import { ProjectNav } from '@/components/layout/ProjectNav'; import { SearchForm } from '@/components/project/SearchForm'; import { ForbiddenError, NotFoundError } from '@/lib/errors'; export const dynamic = 'force-dynamic'; const TYPE_LINKS: Record string> = { thread: (id, p) => `/projects/${p}/board/${id}`, note: (id, p) => `/projects/${p}/notes/${id}`, todo: (_id, p) => `/projects/${p}/todos`, file: (id) => `/api/files/${id}/download`, event: (_id, p) => `/projects/${p}/calendar`, meeting: (_id, p) => `/projects/${p}/meetings`, milestone: (_id, p) => `/projects/${p}/milestones`, chat: (_id, p) => `/projects/${p}/chat`, }; export default async function SearchPage({ params, searchParams, }: { params: Promise<{ projectId: string }>; searchParams: Promise<{ q?: string; type?: string }>; }) { const user = await getCurrentUser(); if (!user) redirect('/login'); const { projectId } = await params; const { q, type } = await searchParams; const projectService = createProjectService(); let project: Awaited>; try { project = projectService.getProject(user.id, Number(projectId)); } catch (error) { if (error instanceof ForbiddenError || error instanceof NotFoundError) { redirect('/dashboard'); } throw error; } const searchService = createSearchService(); const results = q ? searchService.search(user.id, project.id, { q, type: type as never, }) : []; return (

検索

{q && results.length === 0 && (

該当する結果はありません。

)} {results.map((r) => { const href = TYPE_LINKS[r.type]?.(r.id, project.id) ?? `/projects/${project.id}`; return (
{r.title} {r.type}

{r.snippet}

); })}
); }