-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCharacterView.tsx
139 lines (121 loc) · 5.05 KB
/
CharacterView.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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
import { Box, Button, Card, Center, Divider, Grid, Group, Image, Text, Title } from '@mantine/core'
import { IconChevronLeft, IconStars } from '@tabler/icons'
import { useNavigate, useParams } from 'react-router'
import DeleteRatingButton from 'src/components/characters/DeleteRatingButton'
import Label from 'src/components/characters/Label'
import RatingModal from 'src/components/characters/RatingModal'
import Stats from 'src/components/characters/Stats'
import CustomError from 'src/components/common/CustomError'
import CustomLoading from 'src/components/common/CustomLoading'
import useAuthentication from 'src/hooks/auth/useAuthentication'
import useGetRatingByCharacterId from 'src/hooks/characters/useGetRatingByCharacterId'
import useRedirectIfInvalidCharacterId from 'src/hooks/characters/useRedirectIfInvalidId'
import { ratingModalIsOpenVar } from 'src/state/character'
const CharacterView = () => {
const navigate = useNavigate()
const { id: characterId } = useParams()
useRedirectIfInvalidCharacterId(characterId)
// Get user session
const { isAuthenticated, decoded } = useAuthentication()
const userId = decoded?.id || ''
// Get all necessary data about a character and rating
const { characterData, ratingStatsData, hasRatedCharacterData, loading, error, refetch } =
useGetRatingByCharacterId(characterId as string, userId)
const { name, image, status, species, gender, location } = characterData?.character || {}
const averageRating = ratingStatsData?.ratingStatsByCharacterId.average || 0
const numberOfRatings = ratingStatsData?.ratingStatsByCharacterId.count || 0
const hasRatedCharacter = hasRatedCharacterData?.hasRatedCharacter || false
return (
<Box>
{loading ? (
<CustomLoading />
) : error || !characterData?.character ? (
<CustomError />
) : (
<Box>
<RatingModal characterId={characterId as string} userId={userId} refetch={refetch} />
<Button
leftIcon={<IconChevronLeft size={16} />}
onClick={() => {
navigate('/characters')
}}>
Back
</Button>
<Center>
<Card shadow="sm" style={{ width: '320px', marginTop: 10 }} withBorder>
<Grid>
<Grid.Col span={12}>
<Group style={{ justifyContent: 'center', marginBottom: 10 }}>
<Title order={2}>{name}</Title>
<Group style={{ maxWidth: '250px' }}>
{image && (
<Image
src={image}
radius="md"
alt={name || 'An image of a Rick and Morty character'}
/>
)}
</Group>
</Group>
<Text size="xl" weight="bold" color="indigo">
Personal details
</Text>
<Divider my={5} />
<Label label={'Status'} value={status} />
<Label label={'Species'} value={species} />
<Label label={'Gender'} value={gender} />
<Text size="xl" weight="bold" color="indigo">
Location
</Text>
<Divider mt={5} mb={10} />
<Label label={'Name'} value={location} />
<Divider my={10} />
<Group>
<Grid>
<Grid.Col>
<Text color="dimmed" size="xs" transform="uppercase" weight={700}>
Average rating
</Text>
<Stats rating={averageRating} />
</Grid.Col>
</Grid>
<Box>
<Text color="dimmed" size="xs" transform="uppercase" weight={700}>
Number of ratings
</Text>
<Text weight={700} size="xl">
{numberOfRatings}
</Text>
</Box>
</Group>
<Divider />
<Group mt={10}>
{isAuthenticated && (
<>
<Button
variant="light"
leftIcon={<IconStars size={18} />}
onClick={() => ratingModalIsOpenVar(true)}
style={{ flex: 1 }}>
Rate
</Button>
{hasRatedCharacter && (
<DeleteRatingButton
characterId={characterId as string}
userId={userId}
refetch={refetch}
/>
)}
</>
)}
</Group>
</Grid.Col>
</Grid>
</Card>
</Center>
</Box>
)}
</Box>
)
}
export default CharacterView