Projekt

Obecné

Profil

Stáhnout (6.07 KB) Statistiky
| Větev: | Tag: | Revize:
1
import {
2
    Button,
3
    Dialog,
4
    DialogContent,
5
    Divider,
6
    Grid,
7
    Paper,
8
    Stack,
9
    Typography,
10
} from '@mui/material'
11
import { Fragment, FunctionComponent, useEffect, useState } from 'react'
12
import { useParams } from 'react-router-dom'
13
import axiosInstance from '../../api/api'
14
import { CatalogItemDto } from '../../swagger/data-contracts'
15
import ShowErrorIfPresent from '../Reusables/ShowErrorIfPresent'
16
import ContentLoading from '../Reusables/ContentLoading'
17
import CatalogItemMap from './CatalogItemMap'
18
import ArrowBackIosIcon from '@mui/icons-material/ArrowBackIos'
19
import { Link as RouterLink } from 'react-router-dom'
20
import { formatHtmlStringToReactDom } from '../../utils/formatting/HtmlUtils'
21

    
22
const apiError =
23
    'Error while fetching data from the server, please try again later.'
24

    
25
export interface CatalogItemDetailProps {
26
    itemId: string
27
    showReturnToCatalogButton?: boolean
28
}
29

    
30
const CatalogItemDetail: FunctionComponent<CatalogItemDetailProps> = ({
31
    itemId,
32
    showReturnToCatalogButton,
33
}) => {
34
    const [item, setItem] = useState<CatalogItemDto | undefined>(undefined)
35
    const [isItemLoading, setIsItemLoading] = useState(true)
36
    const [err, setErr] = useState<string | undefined>(undefined)
37

    
38
    // Fetch the item from the api after mounting the component
39
    useEffect(() => {
40
        // Function to fetch the item from the api
41
        const fetchItem = async () => {
42
            try {
43
                const { data, status } = await axiosInstance.get(
44
                    `/catalog-items/${itemId}`
45
                )
46
                if (status !== 200) {
47
                    setErr(apiError)
48
                    return
49
                }
50

    
51
                setItem(data)
52
                setIsItemLoading(false)
53
            } catch (err: any) {
54
                setErr(apiError)
55
            }
56
        }
57

    
58
        fetchItem()
59
    }, [itemId])
60

    
61
    // Maps catalogItem property to corresponding table row
62
    const mapToRow = (rowName: string, items: string[]) => (
63
        <Fragment>
64
            <Grid sx={{ my: 2 }} container justifyContent="space-around">
65
                <Grid item xs={8} sx={{ px: 1 }}>
66
                    <Typography fontWeight={500}>{rowName}</Typography>
67
                </Grid>
68
                <Grid item xs={4} sx={{ ml: 'auto' }}>
69
                    {items.map((item) => (
70
                        <Typography key={item}>
71
                            {formatHtmlStringToReactDom(item)}
72
                        </Typography>
73
                    ))}
74
                </Grid>
75
            </Grid>
76
        </Fragment>
77
    )
78

    
79
    // Catalog item rows
80
    const rows = [
81
        {
82
            rowName: 'Name',
83
            items: [item?.name],
84
        },
85
        {
86
            rowName: 'All Names',
87
            items: item?.allNames,
88
        },
89
        {
90
            rowName: 'Written Forms',
91
            items: item?.writtenForms,
92
        },
93
        {
94
            rowName: 'Type',
95
            items: item?.types,
96
        },
97
        {
98
            rowName: 'State or Territory',
99
            items: item?.countries,
100
        },
101
        {
102
            rowName: 'Coordinates',
103
            items: item?.longitude && item?.latitude ? `${item?.latitude}°, ${item?.longitude}°` : '-, -',
104
        },
105
        {
106
            rowName: 'Certainty',
107
            items: [item?.certainty],
108
        },
109
        {
110
            rowName: 'Bibliography',
111
            items: item?.bibliography,
112
        },
113
    ]
114

    
115
    return (
116
        <Fragment>
117
            {showReturnToCatalogButton && (
118
                <Stack
119
                    direction="row"
120
                    alignItems="flex-start"
121
                    spacing={2}
122
                    sx={{ mt: 1 }}
123
                >
124
                    <Button
125
                        startIcon={<ArrowBackIosIcon />}
126
                        variant="contained"
127
                        component={RouterLink}
128
                        to="/catalog"
129
                        color="primary"
130
                        sx={{ mb: 2 }}
131
                    >
132
                        Return To Catalog
133
                    </Button>
134
                </Stack>
135
            )}
136
            <ShowErrorIfPresent err={err} />
137

    
138
            <Paper style={{ minHeight: '100vh' }} variant="outlined">
139
                {isItemLoading && !err ? <ContentLoading /> : null}
140
                {!isItemLoading && item ? (
141
                    <Grid container justifyContent="space-around">
142
                        <Grid item xs={12} md={6} sx={{ px: 2 }}>
143
                            {rows.map((row, idx) => {
144
                                const maxIdx = rows.length - 1
145
                                return (
146
                                    <Fragment>
147
                                        {mapToRow(
148
                                            row.rowName as string,
149
                                            row.items as string[]
150
                                        )}
151
                                        {idx === maxIdx ? null : <Divider />}
152
                                    </Fragment>
153
                                )
154
                            })}
155
                        </Grid>
156

    
157
                        <Grid item md={6} xs={12}>
158
                            <CatalogItemMap item={item} />
159
                        </Grid>
160
                    </Grid>
161
                ) : null}
162
            </Paper>
163
        </Fragment>
164
    )
165
}
166

    
167
export const RoutedCatalogItemDetail = () => {
168
    const { itemId } = useParams()
169
    return <CatalogItemDetail itemId={itemId ?? ''} />
170
}
171

    
172
export const DialogCatalogItemDetail: FunctionComponent<
173
    CatalogItemDetailProps
174
> = ({ itemId }) => {
175
    const [open, setOpen] = useState(false)
176
    return (
177
        <Fragment>
178
            <Button variant="contained" onClick={() => setOpen(true)}>
179
                Detail
180
            </Button>
181
            <Dialog
182
                open={open}
183
                onClose={() => setOpen(false)}
184
                fullWidth
185
                maxWidth="lg"
186
            >
187
                <DialogContent>
188
                    <CatalogItemDetail itemId={itemId} />
189
                </DialogContent>
190
            </Dialog>
191
        </Fragment>
192
    )
193
}
194

    
195
export default CatalogItemDetail
(4-4/8)