forked from CyberAgentHack/web-speed-hackathon-2024
/
RankingCard.tsx
114 lines (99 loc) · 3.46 KB
/
RankingCard.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import { NavigateNext } from '@mui/icons-material';
import { Suspense } from 'react';
import { Link } from 'react-router-dom';
import styled from 'styled-components';
import { Box } from '../../../foundation/components/Box';
import { Flex } from '../../../foundation/components/Flex';
import { Image } from '../../../foundation/components/Image';
import { Separator } from '../../../foundation/components/Separator';
import { Spacer } from '../../../foundation/components/Spacer';
import { Text } from '../../../foundation/components/Text';
import { useImage } from '../../../foundation/hooks/useImage';
import { Color, Radius, Space, Typography } from '../../../foundation/styles/variables';
import { useBook } from '../../book/hooks/useBook';
const _Wrapper = styled.li`
width: 100%;
`;
const _Link = styled(Link)`
width: 100%;
`;
const _ImgWrapper = styled.div`
width: 96px;
height: 96px;
> img {
border-radius: ${Radius.SMALL};
}
`;
const _AvatarWrapper = styled.div`
width: 32px;
height: 32px;
> img {
border-radius: 50%;
}
`;
type Props = {
bookId: string;
};
const RankingCard: React.FC<Props> = ({ bookId }) => {
const { data: book } = useBook({ params: { bookId } });
const imageUrl = useImage({ height: 96, imageId: book.image.id, width: 96 });
const authorImageUrl = useImage({ height: 32, imageId: book.author.image.id, width: 32 });
return (
<_Wrapper>
<_Link to={`/books/${book.id}`}>
<Spacer height={Space * 1.5} />
<Flex align="flex-start" gap={Space * 2.5} justify="flex-start">
{imageUrl != null && (
<_ImgWrapper>
<Image alt={book.name} height={96} objectFit="cover" src={imageUrl} width={96} />
</_ImgWrapper>
)}
<Box width="100%">
<Flex align="flex-start" direction="column" gap={Space * 1} justify="flex-start">
<Text color={Color.MONO_100} typography={Typography.NORMAL16} weight="bold">
{book.name}
</Text>
<Text as="p" color={Color.MONO_80} typography={Typography.NORMAL12}>
{book.description}
</Text>
</Flex>
<Spacer height={Space * 1} />
<Flex align="center" gap={Space * 1} justify="flex-end">
{authorImageUrl != null && (
<_AvatarWrapper>
<Image
alt={`${book.author.name}のアイコン`}
height={32}
objectFit="cover"
src={authorImageUrl}
width={32}
/>
</_AvatarWrapper>
)}
<Text color={Color.MONO_80} typography={Typography.NORMAL12}>
{book.author.name}
</Text>
</Flex>
<Spacer height={Space * 1} />
<Flex align="center" justify="flex-end">
<Text color={Color.Secondary} typography={Typography.NORMAL14} weight="bold">
この漫画を読む
</Text>
<NavigateNext style={{ color: Color.Secondary, height: 32, width: 32 }} />
</Flex>
</Box>
</Flex>
<Spacer height={Space * 1.5} />
<Separator />
</_Link>
</_Wrapper>
);
};
const RankingCardWithSuspense: React.FC<Props> = (props) => {
return (
<Suspense fallback={null}>
<RankingCard {...props} />
</Suspense>
);
};
export { RankingCardWithSuspense as RankingCard };