Projekt

Obecné

Profil

Stáhnout (6.56 KB) Statistiky
| Větev: | Tag: | Revize:
1
import {
2
    Button,
3
    Card,
4
    CardContent,
5
    Divider,
6
    Grid,
7
    Paper,
8
    Stack,
9
    Typography,
10
} from '@mui/material'
11
import { Fragment, useEffect, useState } from 'react'
12
import AddIcon from '@mui/icons-material/Add'
13
import { MapContainer, Marker, Polyline, Popup, TileLayer } from 'react-leaflet'
14
import mapConfig from '../../config/mapConfig'
15
import TextPath from 'react-leaflet-textpath'
16
import PlaintextUpload from './PlaintextUpload'
17
import FileUpload from './FileUpload'
18
import L from 'leaflet'
19
import DeleteIcon from '@mui/icons-material/Delete'
20
import { PathDto } from '../../swagger/data-contracts'
21
import { formatHtmlStringToReactDom } from '../../utils/formatting/HtmlUtils'
22
import buildPathVariants, { PathVariant } from './buildPathVariants'
23

    
24
// Page with tracking tool
25
const TrackingTool = () => {
26
    // Path response from the API
27
    const [pathDto, setPathDto] = useState<PathDto | undefined>(undefined)
28

    
29
    // Whether the path variants are building
30
    const [buildingPathVariants, setBuildingPathVariants] =
31
        useState<boolean>(false)
32

    
33
    // List of all computed path variants
34
    const [pathVariants, setPathVariants] = useState<PathVariant[] | undefined>(
35
        undefined
36
    )
37

    
38
    // List of all rendered paths to display
39
    const [renderedPaths, setRenderedPaths] = useState<any[]>([])
40

    
41
    const [mapCenter, setMapCenter] = useState<number[]>([
42
        mapConfig.defaultCoordinates[0],
43
        mapConfig.defaultCoordinates[1],
44
    ])
45

    
46
    // Returns tuple of average latitude and longitude
47
    const calculateMapCenter = (pathVariant: PathVariant) => [
48
        pathVariant
49
            .map((item) => item.latitude ?? 0)
50
            .reduce((a, b) => a + b, 0) / pathVariant.length,
51
        pathVariant
52
            .map((item) => item.longitude ?? 0)
53
            .reduce((a, b) => a + b, 0) / pathVariant.length,
54
    ]
55

    
56
    useEffect(() => {
57
        if (!pathDto) {
58
            return
59
        }
60

    
61
        setBuildingPathVariants(true)
62
        buildPathVariants(pathDto).then((pathVariants) => {
63
            setPathVariants(pathVariants)
64
            setBuildingPathVariants(false)
65
            const paths: any[] = []
66
            let first = true
67
            pathVariants?.forEach((pathVariant) => {
68
                if (first) {
69
                    setMapCenter(calculateMapCenter(pathVariant))
70
                }
71
                for (let i = 0; i < pathVariant.length - 1; i++) {
72
                    paths.push(
73
                        <TextPath
74
                            positions={[
75
                                [
76
                                    pathVariant[i].latitude,
77
                                    pathVariant[i].longitude,
78
                                ],
79
                                [
80
                                    pathVariant[i + 1].latitude,
81
                                    pathVariant[i + 1].longitude,
82
                                ],
83
                            ]}
84
                            text="►"
85
                            attributes={{
86
                                'font-size': 25,
87
                                fill: first ? 'blue' : 'gray',
88
                            }}
89
                            repeat
90
                            center
91
                            weight={10}
92
                        />
93
                    )
94
                }
95
                first = false
96
            })
97
            console.log(paths)
98
            setRenderedPaths(paths)
99
        })
100
    }, [pathDto])
101

    
102
    return (
103
        <Fragment>
104
            <Typography variant="h3" sx={{ mb: 2 }} fontWeight="bold">
105
                Tracking Tool
106
            </Typography>
107

    
108
            {pathDto && (
109
                <Fragment>
110
                    <Card variant="outlined">
111
                        <CardContent>
112
                            <Stack direction="column">
113
                                <Typography
114
                                    variant="h5"
115
                                    sx={{ mb: 1 }}
116
                                    fontWeight="600"
117
                                >
118
                                    Text
119
                                </Typography>
120
                                <Typography variant="body2">
121
                                    {formatHtmlStringToReactDom(
122
                                        pathDto.text ?? ''
123
                                    )}
124
                                </Typography>
125
                            </Stack>
126
                        </CardContent>
127
                    </Card>
128
                </Fragment>
129
            )}
130
            <Grid container>
131
                <Grid item xs={12}>
132
                    {pathDto && pathDto?.foundCatalogItems?.length === 0 && (
133
                        <Typography
134
                            variant="body1"
135
                            sx={{ mb: 2 }}
136
                            fontWeight="500"
137
                            align="center"
138
                            color="error.main"
139
                        >
140
                            Looks like no path / catalog items match this query.
141
                        </Typography>
142
                    )}
143

    
144
                    <Stack
145
                        direction="row"
146
                        alignItems="flex-start"
147
                        spacing={2}
148
                        sx={{ mt: 1 }}
149
                    >
150
                        <Typography
151
                            variant="h5"
152
                            sx={{ mb: 2 }}
153
                            fontWeight="500"
154
                        >
155
                            {pathDto ? 'Update path' : 'Show Path'}
156
                        </Typography>
157
                        <PlaintextUpload setPaths={setPathDto} />
158
                        <FileUpload />
159
                    </Stack>
160
                </Grid>
161

    
162
                <Grid
163
                    item
164
                    xs={12}
165
                    md={12}
166
                    style={{
167
                        minHeight: '60vh',
168
                        maxHeight: '100vh',
169
                        width: '100%',
170
                    }}
171
                >
172
                    <MapContainer
173
                        center={[mapCenter[0], mapCenter[1]]}
174
                        zoom={mapConfig.defaultZoom}
175
                        style={{ height: '100%', minHeight: '100%' }}
176
                    >
177
                        <TileLayer
178
                            attribution={mapConfig.attribution}
179
                            url={mapConfig.url}
180
                        />
181
                        {renderedPaths}
182
                    </MapContainer>
183
                </Grid>
184
            </Grid>
185
        </Fragment>
186
    )
187
}
188

    
189
export default TrackingTool
(3-3/4)