Projekt

Obecné

Profil

Stáhnout (6.17 KB) Statistiky
| Větev: | Tag: | Revize:
1
import { Card, CardContent, Grid, Stack, Typography } from '@mui/material'
2
import { Fragment, useEffect, useState } from 'react'
3
import { MapContainer, TileLayer } from 'react-leaflet'
4
import mapConfig from '../../config/mapConfig'
5
import TextPath from 'react-leaflet-textpath'
6
import PlaintextUpload from './PlaintextUpload'
7
import FileUpload from './FileUpload'
8
import L from 'leaflet'
9
import DeleteIcon from '@mui/icons-material/Delete'
10
import { PathDto } from '../../swagger/data-contracts'
11
import { formatHtmlStringToReactDom } from '../../utils/formatting/HtmlUtils'
12
import buildPathVariants, { PathVariant } from './buildPathVariants'
13
import MapPath from './MapPath'
14

    
15
// Page with tracking tool
16
const TrackingTool = () => {
17
    // Path response from the API
18
    const [pathDto, setPathDto] = useState<PathDto | undefined>(undefined)
19

    
20
    // Whether the path variants are building
21
    const [buildingPathVariants, setBuildingPathVariants] =
22
        useState<boolean>(false)
23

    
24
    // List of all computed path variants
25
    const [pathVariants, setPathVariants] = useState<PathVariant[] | undefined>(
26
        undefined
27
    )
28

    
29
    // latitude longitude pair of where the map is to be centered
30
    const [mapCenter, setMapCenter] = useState<number[]>([
31
        mapConfig.defaultCoordinates[0],
32
        mapConfig.defaultCoordinates[1],
33
    ])
34

    
35
    const [primaryPathIdx, setActivePathIdx] = useState(0)
36

    
37
    // TODO make some sort of selection list to select active paths?
38
    const [activePaths, setActivePaths] = useState<Set<number>>(new Set())
39

    
40
    // Returns tuple of average latitude and longitude
41
    const calculateMapCenter = (pathVariant: PathVariant) => [
42
        pathVariant
43
            .map((item) => item.latitude ?? 0)
44
            .reduce((a, b) => a + b, 0) / pathVariant.length,
45
        pathVariant
46
            .map((item) => item.longitude ?? 0)
47
            .reduce((a, b) => a + b, 0) / pathVariant.length,
48
    ]
49

    
50
    useEffect(() => {
51
        if (!pathVariants || pathVariants.length === 0) {
52
            return
53
        }
54
        // TODO calculate only for path that has some non-null coordinates
55
        setMapCenter(calculateMapCenter(pathVariants[0]))
56
    }, [pathVariants])
57

    
58
    useEffect(() => {
59
        if (!pathDto) {
60
            return
61
        }
62

    
63
        setBuildingPathVariants(true)
64
        buildPathVariants(pathDto).then((pathVariants) => {
65
            setActivePaths(new Set(pathVariants.map((_, idx) => idx)))
66
            setPathVariants(pathVariants)
67
            setBuildingPathVariants(false)
68
        })
69
    }, [pathDto])
70

    
71
    return (
72
        <Fragment>
73
            <Typography variant="h3" sx={{ mb: 2 }} fontWeight="bold">
74
                Tracking Tool
75
            </Typography>
76

    
77
            {pathDto && (
78
                <Fragment>
79
                    <Card variant="outlined">
80
                        <CardContent>
81
                            <Stack direction="column">
82
                                <Typography
83
                                    variant="h5"
84
                                    sx={{ mb: 1 }}
85
                                    fontWeight="600"
86
                                >
87
                                    Processed Text
88
                                </Typography>
89
                                <Typography variant="body2">
90
                                    {formatHtmlStringToReactDom(
91
                                        pathDto.text ?? ''
92
                                    )}
93
                                </Typography>
94
                            </Stack>
95
                        </CardContent>
96
                    </Card>
97
                </Fragment>
98
            )}
99
            <Grid container>
100
                <Grid item xs={12}>
101
                    {pathDto && pathDto?.foundCatalogItems?.length === 0 && (
102
                        <Typography
103
                            variant="body1"
104
                            sx={{ mb: 2 }}
105
                            fontWeight="500"
106
                            align="center"
107
                            color="error.main"
108
                        >
109
                            Looks like no path / catalog items match this query.
110
                        </Typography>
111
                    )}
112

    
113
                    <Stack
114
                        direction="row"
115
                        alignItems="flex-start"
116
                        spacing={2}
117
                        sx={{ mt: 1 }}
118
                    >
119
                        <Typography
120
                            variant="h5"
121
                            sx={{ mb: 2 }}
122
                            fontWeight="500"
123
                        >
124
                            {pathDto ? 'Update path' : 'Show Path'}
125
                        </Typography>
126
                        <PlaintextUpload setPaths={setPathDto} />
127
                        <FileUpload />
128
                    </Stack>
129
                </Grid>
130

    
131
                <Grid
132
                    item
133
                    xs={12}
134
                    md={12}
135
                    style={{
136
                        minHeight: '60vh',
137
                        maxHeight: '100vh',
138
                        width: '100%',
139
                    }}
140
                >
141
                    <MapContainer
142
                        center={[mapCenter[0], mapCenter[1]]}
143
                        zoom={mapConfig.defaultZoom}
144
                        style={{ height: '100%', minHeight: '100%' }}
145
                    >
146
                        <TileLayer
147
                            attribution={mapConfig.attribution}
148
                            url={mapConfig.url}
149
                        />
150
                        {pathVariants &&
151
                            pathVariants.map((pathVariant, idx) => (
152
                                <MapPath
153
                                    key={idx}
154
                                    pathVariant={pathVariant}
155
                                    idx={idx}
156
                                    setPrimary={setActivePathIdx}
157
                                    primaryIdx={primaryPathIdx}
158
                                    active={activePaths.has(idx)}
159
                                />
160
                            ))}
161
                    </MapContainer>
162
                </Grid>
163
            </Grid>
164
        </Fragment>
165
    )
166
}
167

    
168
export default TrackingTool
(4-4/5)