Skip to content

Commit 89f746b

Browse files
authored
Merge pull request #162 from kc3hack/hayato/develop
共有URLのメタデータ
2 parents bff8c7d + 313bd57 commit 89f746b

File tree

2 files changed

+69
-53
lines changed

2 files changed

+69
-53
lines changed

Diff for: frontend/src/app/(main)/post/[postId]/PostPage.tsx

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
'use client';
2+
3+
import React from 'react';
4+
import { useRouter } from 'next/navigation';
5+
import { PostTypes } from '@/types/postTypes';
6+
import Post from '@/components/Post';
7+
import { AnimatePresence, motion } from 'framer-motion';
8+
9+
/**
10+
* 指定されたIDの投稿を表示する.
11+
* @async
12+
* @function Post
13+
* @returns {JSX.Element} プロフィールを表示するReactコンポーネント
14+
*/
15+
const PostPage = ({ post }: { post: PostTypes | null }) => {
16+
const router = useRouter();
17+
18+
return (
19+
<div>
20+
{!post && <p className='py-3 text-center'>短歌を取得中...</p>}
21+
<AnimatePresence mode='wait'>
22+
{post && (
23+
<motion.div
24+
initial={{ opacity: 0 }}
25+
animate={{ opacity: 1 }}
26+
exit={{ opacity: 0 }}
27+
transition={{ duration: 0.5 }}
28+
className='mx-auto max-w-sm pt-5 lg:max-w-lg'
29+
>
30+
{post && <Post post={post} onDelete={() => router.push('/')} />}
31+
</motion.div>
32+
)}
33+
</AnimatePresence>
34+
</div>
35+
);
36+
};
37+
38+
export default PostPage;

Diff for: frontend/src/app/(main)/post/[postId]/page.tsx

+31-53
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,48 @@
1-
'use client';
2-
import React, { useEffect, useState } from 'react';
3-
import { useSession } from 'next-auth/react';
4-
import { useRouter, useParams } from 'next/navigation';
5-
import { PostTypes } from '@/types/postTypes';
6-
import Post from '@/components/Post';
1+
import React from 'react';
72
import fetchOnePost from './actions/fetchOnePost';
8-
import { AnimatePresence, motion } from 'framer-motion';
9-
import Head from 'next/head';
3+
import PostPage from './PostPage';
4+
import { notFound } from 'next/navigation';
105

6+
const tankaToString = (tanka: string[]) => {
7+
return tanka.join(' ');
8+
};
9+
10+
export const generateMetadata = async (context: { params: Promise<{ postId: string }> }) => {
11+
const params = await context.params;
12+
13+
const post = await fetchOnePost({
14+
postId: params.postId,
15+
iconUrl: '',
16+
});
17+
18+
if (!post) return { title: '投稿が見つかりません' };
19+
20+
return {
21+
title: `Tankalizer: ${post.user.name}さんの短歌`,
22+
description: tankaToString(post.tanka),
23+
};
24+
};
1125
/**
1226
* 指定されたIDの投稿を表示する.
1327
* @async
1428
* @function Post
1529
* @returns {JSX.Element} プロフィールを表示するReactコンポーネント
1630
*/
17-
const PostPage = () => {
18-
const { postId } = useParams() as { postId: string };
19-
const [post, setPost] = useState<PostTypes | null>(null);
20-
// セッションの取得
21-
const session = useSession();
22-
const router = useRouter();
31+
const Page = async (context: { params: Promise<{ postId: string }> }) => {
32+
const params = await context.params;
2333

24-
// 投稿IDから投稿をFetchする
25-
useEffect(() => {
26-
const getPost = async () => {
27-
if (!postId) return;
28-
if (session.status === 'loading') return;
29-
const data = await fetchOnePost({
30-
postId: postId as string,
31-
iconUrl: session.data?.user?.image ?? '',
32-
});
33-
if (!data) router.push('/post-not-found');
34-
setPost(data);
35-
};
36-
getPost();
37-
}, [postId, session.data?.user?.image, session.status, router]);
34+
const post = await fetchOnePost({
35+
postId: params.postId,
36+
iconUrl: '',
37+
});
3838

39-
const tankaToString = (tanka: string[]) => {
40-
return tanka.join('\n');
41-
};
39+
if (!post) notFound();
4240

4341
return (
4442
<div>
45-
{post && (
46-
<Head>
47-
<title>Tankalizer:{`${post.user.name}さんの短歌`}</title>
48-
<meta name='description' content={tankaToString(post.tanka)} />
49-
</Head>
50-
)}
51-
52-
{!post && <p className='py-3 text-center'>短歌を取得中...</p>}
53-
<AnimatePresence mode='wait'>
54-
{post && (
55-
<motion.div
56-
initial={{ opacity: 0 }}
57-
animate={{ opacity: 1 }}
58-
exit={{ opacity: 0 }}
59-
transition={{ duration: 0.5 }}
60-
className='mx-auto max-w-sm pt-5 lg:max-w-lg'
61-
>
62-
{post && <Post post={post} onDelete={() => router.push('/')} />}
63-
</motion.div>
64-
)}
65-
</AnimatePresence>
43+
<PostPage post={post} />
6644
</div>
6745
);
6846
};
6947

70-
export default PostPage;
48+
export default Page;

0 commit comments

Comments
 (0)