|
| 1 | +import { NextPage } from 'next'; |
| 2 | +import { makeStyles, createStyles, Theme } from '@material-ui/core/styles'; |
| 3 | +import { Pagination } from '@material-ui/lab'; |
| 4 | +import React, { useState } from 'react'; |
| 5 | +import { useRouter } from 'next/router'; |
| 6 | +import useSWR from 'swr'; |
| 7 | +import fetcher from '../../utils/fetcher'; |
| 8 | +import { |
| 9 | + Avatar, |
| 10 | + Box, |
| 11 | + Container, |
| 12 | + Grid, |
| 13 | + Typography, |
| 14 | + useMediaQuery, |
| 15 | + useTheme, |
| 16 | +} from '@material-ui/core'; |
| 17 | +import PostCard from '../../components/PostCard'; |
| 18 | +import { Comment } from '../../src/type'; |
| 19 | + |
| 20 | +const useStyles = makeStyles((theme: Theme) => |
| 21 | + createStyles({ |
| 22 | + profileArea: { |
| 23 | + maxHeight: 256, |
| 24 | + paddingTop: 64, |
| 25 | + paddingBottom: 128, |
| 26 | + display: '-webkit-box', |
| 27 | + '-webkit-line-clamp': 5, |
| 28 | + '-webkit-box-orient': 'vertical', |
| 29 | + overflow: 'hidden', |
| 30 | + }, |
| 31 | + userName: { |
| 32 | + fontSize: 48, |
| 33 | + fontWeight: 'bold', |
| 34 | + [theme.breakpoints.down('sm')]: { |
| 35 | + fontSize: 36, |
| 36 | + }, |
| 37 | + }, |
| 38 | + userProfile: { |
| 39 | + fontSize: 24, |
| 40 | + }, |
| 41 | + userIcon: { |
| 42 | + width: 64, |
| 43 | + height: 64, |
| 44 | + }, |
| 45 | + message: { |
| 46 | + justifyContent: 'center', |
| 47 | + alignItems: 'center', |
| 48 | + marginTop: 24, |
| 49 | + fontSize: 64, |
| 50 | + fontWeight: 'bold', |
| 51 | + }, |
| 52 | + }) |
| 53 | +); |
| 54 | + |
| 55 | +const PostDetail: NextPage = () => { |
| 56 | + const styles = useStyles(); |
| 57 | + const router = useRouter(); |
| 58 | + const theme = useTheme(); |
| 59 | + const isXsSm = useMediaQuery(theme.breakpoints.down('sm')); |
| 60 | + |
| 61 | + const cardsPerPage = 6; |
| 62 | + const cardsPerRow = isXsSm ? 1 : 2; |
| 63 | + const [pageNum, setPageNum] = useState(1); |
| 64 | + |
| 65 | + const handlePageChange = ( |
| 66 | + event: React.ChangeEvent<unknown>, |
| 67 | + value: number |
| 68 | + ): void => { |
| 69 | + setPageNum(value); |
| 70 | + }; |
| 71 | + |
| 72 | + // ad-hocすぎる... |
| 73 | + const uid = router.query.uid; |
| 74 | + // const uid = id === undefined ? '1' : id; |
| 75 | + |
| 76 | + const res_user = useSWR(`/user/${uid}`, fetcher); |
| 77 | + const res_post = useSWR(`/user/${uid}/post`, fetcher); |
| 78 | + |
| 79 | + if (res_user.error) { |
| 80 | + return <>Error</>; |
| 81 | + } |
| 82 | + const userData = res_user.data; |
| 83 | + if (!userData) { |
| 84 | + return <>Loading...</>; |
| 85 | + } |
| 86 | + |
| 87 | + if (res_post.error) { |
| 88 | + return <>Error</>; |
| 89 | + } |
| 90 | + const postData = res_post.data as Comment[]; |
| 91 | + if (!postData) { |
| 92 | + return <>Loading...</>; |
| 93 | + } |
| 94 | + |
| 95 | + // 配列をsize個ずつに分ける |
| 96 | + const chunk = <T extends unknown>(arr: T[], size: number): T[][] => |
| 97 | + arr.reduce( |
| 98 | + (newarr, _, i) => |
| 99 | + i % size ? newarr : [...newarr, arr.slice(i, i + size)], |
| 100 | + [] as T[][] |
| 101 | + ); |
| 102 | + |
| 103 | + return ( |
| 104 | + <> |
| 105 | + <Container style={{ marginTop: '30px', marginBottom: '60px' }}> |
| 106 | + <Box className={styles.profileArea}> |
| 107 | + <Avatar |
| 108 | + alt="userIcon" |
| 109 | + src={userData.icon_url} |
| 110 | + className={styles.userIcon} |
| 111 | + /> |
| 112 | + <Typography className={styles.userName}>{userData.name}</Typography> |
| 113 | + <Typography className={styles.userProfile}> |
| 114 | + {userData.profile} |
| 115 | + </Typography> |
| 116 | + </Box> |
| 117 | + <h1>投稿一覧</h1> |
| 118 | + <Box display="flex" justifyContent="center"> |
| 119 | + <Pagination |
| 120 | + count={Math.ceil(postData.length / cardsPerPage)} |
| 121 | + page={pageNum} |
| 122 | + onChange={handlePageChange} |
| 123 | + /> |
| 124 | + </Box> |
| 125 | + <Grid container spacing={3} style={{ marginTop: '10px' }}> |
| 126 | + {chunk( |
| 127 | + postData.slice( |
| 128 | + cardsPerPage * (pageNum - 1), |
| 129 | + cardsPerPage * pageNum |
| 130 | + ), |
| 131 | + cardsPerRow |
| 132 | + ).map((row, idx_i) => ( |
| 133 | + <Grid item xs={12} key={idx_i}> |
| 134 | + <Grid container spacing={3}> |
| 135 | + {row.map((post, idx_j) => ( |
| 136 | + <Grid item xs={12} md={6} key={idx_j}> |
| 137 | + <PostCard |
| 138 | + user_id={post.user_id} |
| 139 | + post_id={post.id} |
| 140 | + title={post.title} |
| 141 | + code={post.code} |
| 142 | + language={post.language} |
| 143 | + content={post.content} |
| 144 | + source={post.source} |
| 145 | + created_at={post.created_at} |
| 146 | + /> |
| 147 | + </Grid> |
| 148 | + ))} |
| 149 | + </Grid> |
| 150 | + </Grid> |
| 151 | + ))} |
| 152 | + </Grid> |
| 153 | + </Container> |
| 154 | + </> |
| 155 | + ); |
| 156 | +}; |
| 157 | + |
| 158 | +export default PostDetail; |
0 commit comments