diff --git a/src/app/stories/[storyId]/edit/_components/EditStorySwitchMode.tsx b/src/app/stories/[storyId]/edit/_components/EditStorySwitchMode.tsx new file mode 100644 index 00000000..91ad4f55 --- /dev/null +++ b/src/app/stories/[storyId]/edit/_components/EditStorySwitchMode.tsx @@ -0,0 +1,39 @@ +"use client"; +import { Device } from "@/common/util/device"; +import { EditStory } from "@/components/editStory"; +import { EditStoryYaml } from "@/components/editStoryYaml"; +import { Story, StoryInit } from "@/server/model/story"; +import { useSearchParams } from "next/navigation"; + +export const EditStorySwitchMode = ({ + story, + device, + onSubmit, +}: { + story: Story; + device: Device; + onSubmit: (data: StoryInit) => Promise; +}) => { + const searchParams = useSearchParams(); + const mode = searchParams?.get("mode"); + if (mode === "yaml") { + return ( + + ); + } else { + return ( + + ); + } +}; diff --git a/src/app/stories/[storyId]/edit/page.tsx b/src/app/stories/[storyId]/edit/page.tsx index 7306b475..42d8f90b 100644 --- a/src/app/stories/[storyId]/edit/page.tsx +++ b/src/app/stories/[storyId]/edit/page.tsx @@ -1,25 +1,22 @@ import { getDevice } from "@/common/util/device"; -import { EditStory } from "@/components/editStory"; import { getUserSession } from "@/server/serverComponent/getUserSession"; import { getStory } from "@/server/services/story"; import { updateStory } from "@/server/services/story/updateStory"; +import { Metadata } from "next"; import { revalidateTag } from "next/cache"; import { headers } from "next/headers"; import { notFound } from "next/navigation"; +import { cache } from "react"; import { z } from "zod"; +import { EditStorySwitchMode } from "./_components/EditStorySwitchMode"; -const paramsSchema = z.object({ - storyId: z.string(), -}); - -export default async function StoryEditPage({ params }: { params: unknown }) { - const { storyId } = paramsSchema.parse(params); +const getDataByRequest = cache(async (storyId: string) => { const user = await getUserSession(); if (!user) { notFound(); } const story = await getStory({ - storyId, + storyId: storyId, filter: { type: "withAuthorId", authorId: user.userId, @@ -28,11 +25,37 @@ export default async function StoryEditPage({ params }: { params: unknown }) { if (!story) { notFound(); } + return { + story, + user, + }; +}); + +const paramsSchema = z.object({ + storyId: z.string(), +}); + +export const generateMetadata = async ({ + params, +}: { params: unknown }): Promise => { + const parsed = paramsSchema.safeParse(params); + if (!parsed.success) { + notFound(); + } + const { storyId } = parsed.data; + const { story } = await getDataByRequest(storyId); + return { + title: `編集 - ${story.title}`, + }; +}; + +export default async function StoryEditPage({ params }: { params: unknown }) { + const { storyId } = paramsSchema.parse(params); + const { story, user } = await getDataByRequest(storyId); const device = getDevice(headers().get("user-agent") || undefined); return ( - { "use server"; diff --git a/src/app/stories/[storyId]/edit/yaml/page.tsx b/src/app/stories/[storyId]/edit/yaml/page.tsx deleted file mode 100644 index bf6c142f..00000000 --- a/src/app/stories/[storyId]/edit/yaml/page.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import { EditStoryYaml } from "@/components/editStoryYaml"; -import { getUserSession } from "@/server/serverComponent/getUserSession"; -import { getStory } from "@/server/services/story"; -import { updateStory } from "@/server/services/story/updateStory"; -import { revalidateTag } from "next/cache"; -import { notFound } from "next/navigation"; -import { z } from "zod"; - -const paramsSchema = z.object({ - storyId: z.string(), -}); - -export default async function StoryEditPage({ params }: { params: unknown }) { - const { storyId } = paramsSchema.parse(params); - const user = await getUserSession(); - if (!user) { - notFound(); - } - const story = await getStory({ - storyId, - filter: { - type: "withAuthorId", - authorId: user.userId, - }, - }); - if (!story) { - notFound(); - } - return ( - { - "use server"; - const ok = await updateStory({ - storyId, - input: input, - userId: user.userId, - }); - if (!ok) { - notFound(); - } - revalidateTag(`/stories/${storyId}`); - }} - /> - ); -} diff --git a/src/app/stories/new/_components/NewStorySwitchMode.tsx b/src/app/stories/new/_components/NewStorySwitchMode.tsx new file mode 100644 index 00000000..e4e8364a --- /dev/null +++ b/src/app/stories/new/_components/NewStorySwitchMode.tsx @@ -0,0 +1,22 @@ +"use client"; +import { type Device } from "@/common/util/device"; +import { NewStory } from "@/components/newStory"; +import { NewStoryYaml } from "@/components/newStoryYaml"; +import { StoryInit } from "@/server/model/story"; +import { useSearchParams } from "next/navigation"; + +export const NewStorySwitchMode = ({ + device, + createStory, +}: { + device: Device; + createStory: (data: StoryInit) => Promise; +}) => { + const searchParams = useSearchParams(); + const mode = searchParams?.get("mode"); + if (mode === "yaml") { + return ; + } else { + return ; + } +}; diff --git a/src/app/stories/new/page.tsx b/src/app/stories/new/page.tsx index 8b5d3825..9b64b068 100644 --- a/src/app/stories/new/page.tsx +++ b/src/app/stories/new/page.tsx @@ -1,9 +1,14 @@ -import { type Device, getDevice } from "@/common/util/device"; -import { NewStory } from "@/components/newStory"; +import { getDevice } from "@/common/util/device"; import { getUserSession } from "@/server/serverComponent/getUserSession"; import { createStory } from "@/server/services/story/createStory"; +import { Metadata } from "next"; import { headers } from "next/headers"; import { RedirectType, notFound, redirect } from "next/navigation"; +import { NewStorySwitchMode } from "./_components/NewStorySwitchMode"; + +export const metadata: Metadata = { + title: "新しいストーリー", +}; export default async function NewStoryPage() { const session = await getUserSession(); @@ -15,7 +20,7 @@ export default async function NewStoryPage() { } const device = getDevice(headers().get("user-agent") || undefined); return ( - { "use server"; diff --git a/src/app/stories/new/yaml/page.tsx b/src/app/stories/new/yaml/page.tsx deleted file mode 100644 index c2e5f81c..00000000 --- a/src/app/stories/new/yaml/page.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import { NewStoryYaml } from "@/components/newStoryYaml"; -import { getUserSession } from "@/server/serverComponent/getUserSession"; -import { createStory } from "@/server/services/story/createStory"; -import { RedirectType, notFound, redirect } from "next/navigation"; - -export default async function NewStoryPage() { - const session = await getUserSession(); - if (!session) { - redirect( - `/api/auth/signin?callbackUrl=${encodeURIComponent("/stories/new")}`, - RedirectType.replace, - ); - } - return ( - { - "use server"; - const id = await createStory({ - userId: session.userId, - data, - }); - if (id === null) { - notFound(); - } - return id; - }} - /> - ); -} diff --git a/src/components/editStory/index.tsx b/src/components/editStory/index.tsx index 8b9289aa..16da4c75 100644 --- a/src/components/editStory/index.tsx +++ b/src/components/editStory/index.tsx @@ -34,7 +34,7 @@ export const EditStory: React.FC = ({ {story.title} {device === "desktop" && (
- + diff --git a/src/components/editStoryYaml/index.tsx b/src/components/editStoryYaml/index.tsx index f5cc06ec..3c88caf8 100644 --- a/src/components/editStoryYaml/index.tsx +++ b/src/components/editStoryYaml/index.tsx @@ -1,7 +1,7 @@ "use client"; import { AnchorButton, GenericButton } from "@/designSystem/components/button"; import { Heading } from "@/designSystem/components/heading"; -import type { StoryHead, StoryInit } from "@/server/model/story"; +import type { StoryInit } from "@/server/model/story"; import { useMutation } from "@tanstack/react-query"; import Link from "next/link"; import { useRouter } from "next/navigation"; @@ -11,26 +11,30 @@ import { YamlFileDrop } from "../storyYamlFileDrop"; import styles from "./styles.module.scss"; export const EditStoryYaml: React.FC<{ - initialStory: StoryHead; + story: { + title: string; + id: string; + }; onSubmit: (data: StoryInit) => Promise; -}> = ({ initialStory, onSubmit }) => { +}> = ({ story, onSubmit }) => { const router = useRouter(); const { mutate, isIdle } = useMutation(onSubmit); + const storyId = story.id; const handleFileRead = useCallback( (story: StoryInit) => { mutate(story, { onSuccess: () => { - router.push(`/stories/${initialStory.id}`); + router.push(`/stories/${storyId}`); }, }); }, - [initialStory.id, mutate, router], + [storyId, mutate, router], ); return (
- {initialStory.title} + {story.title}

ストーリーをYAML形式で記述して編集できます。

{isIdle ? ( <> @@ -48,7 +52,7 @@ export const EditStoryYaml: React.FC<{ > ストーリーの書き方 - + ストーリーに戻る diff --git a/src/components/newStory/index.tsx b/src/components/newStory/index.tsx index 1eb54123..23285430 100644 --- a/src/components/newStory/index.tsx +++ b/src/components/newStory/index.tsx @@ -28,7 +28,7 @@ export const NewStory: React.FC = ({ device, createStory }) => { 新しいストーリーを投稿 {device === "desktop" && (
- +