|
1 | 1 | import React, {useState, useMemo, useEffect} from 'react'; |
2 | 2 |
|
3 | | -import { Subheading, Whisper } from './Elements'; |
| 3 | +import { Whisper } from './Elements'; |
4 | 4 | import { Statistics } from '../models'; |
5 | 5 | import ConfigStorage from '../storage/configStorage'; |
6 | 6 | import API from '../api'; |
@@ -76,51 +76,96 @@ function StatFrequency({ object, measure }) { |
76 | 76 | } |
77 | 77 |
|
78 | 78 | export function AllStats({ filters }) { |
79 | | - const [statistics, setStatistics] = useState<Statistics>() |
80 | | - const metricUnits = ConfigStorage.getSetting("metricUnits"); |
| 79 | + const [statistics, setStatistics] = useState<Statistics>(); |
| 80 | + const [durationUnitIndex, setDurationUnitIndex] = useState(0); |
| 81 | + const [distanceUnitIndex, setDistanceUnitIndex] = useState(0); |
| 82 | + const metricUnits = ConfigStorage.getSetting('metricUnits'); |
81 | 83 |
|
82 | 84 | useEffect(() => { |
83 | | - API.get(`/statistics?metric=${metricUnits}`, filters) |
84 | | - .then((data: Statistics) => { |
85 | | - setStatistics(data); |
| 85 | + API.get(`/statistics?metric=${metricUnits}`, filters).then((data: Statistics) => { |
| 86 | + setStatistics(data); |
86 | 87 | }); |
87 | | - }, [filters]); |
| 88 | + }, [filters, metricUnits]); |
88 | 89 |
|
89 | | - if (statistics === undefined) { |
| 90 | + if (!statistics) { |
90 | 91 | return <p className="m-4">loading...</p>; |
91 | 92 | } |
92 | 93 |
|
| 94 | + // cycle through duration units |
| 95 | + const durationUnits = [ |
| 96 | + { label: "hours", divisor: 60 }, |
| 97 | + { label: "days", divisor: 1440 }, |
| 98 | + { label: "weeks", divisor: 10080 }, |
| 99 | + ]; |
| 100 | + |
| 101 | + const handleDurationClick = () => { |
| 102 | + setDurationUnitIndex((prev) => (prev + 1) % durationUnits.length); |
| 103 | + }; |
| 104 | + |
| 105 | + // cycle through distance units |
| 106 | + const distanceUnits = [ |
| 107 | + { label: metricUnits === 'false' ? 'mi' : 'km', divisor: 1 }, |
| 108 | + { label: "times around Earth", divisor: metricUnits === 'false' ? 3963 : 6371 }, |
| 109 | + { label: "times to Moon", divisor: metricUnits === 'false' ? 239000 : 385000 }, |
| 110 | + ]; |
| 111 | + |
| 112 | + const handleDistanceClick = () => { |
| 113 | + setDistanceUnitIndex((prev) => (prev + 1) % distanceUnits.length); |
| 114 | + }; |
| 115 | + |
93 | 116 | return ( |
94 | 117 | <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 p-4"> |
95 | 118 | <div className="container"> |
96 | 119 | <h3 className="text-lg font-semibold mb-4">Generic</h3> |
97 | | - |
98 | | - <p className="mb-2">Number of flights: <span className="font-medium">{statistics.totalFlights}</span></p> |
99 | | - <p className="mb-2">Total (registered) time spent flying: <span className="font-medium">{(statistics.totalDuration / 60).toLocaleString()} hours</span></p> |
100 | | - <p className="mb-2">Total distance travelled: <span className="font-medium">{statistics.totalDistance.toLocaleString()} {metricUnits === "false" ? "mi" : "km"}</span></p> |
101 | | - <p className="mb-2">Total unique airports visited: <span className="font-medium">{statistics.totalUniqueAirports}</span></p> |
102 | | - <p className="mb-2">Range of days: <span className="font-medium">{statistics.daysRange} days</span></p> |
| 120 | + |
| 121 | + <p className="mb-2"> |
| 122 | + Number of flights: <span className="font-medium">{statistics.totalFlights}</span> |
| 123 | + </p> |
| 124 | + <p className="mb-2"> |
| 125 | + Total (registered) time spent flying:{' '} |
| 126 | + <span className="font-medium cursor-pointer" onClick={handleDurationClick}> |
| 127 | + {(statistics.totalDuration / durationUnits[durationUnitIndex].divisor).toFixed(1)} {' '} |
| 128 | + {durationUnits[durationUnitIndex].label} |
| 129 | + </span> |
| 130 | + </p> |
| 131 | + <p className="mb-2"> |
| 132 | + Total distance travelled:{' '} |
| 133 | + <span className="font-medium cursor-pointer" onClick={handleDistanceClick}> |
| 134 | + {(statistics.totalDistance / distanceUnits[distanceUnitIndex].divisor).toFixed(1)} {' '} |
| 135 | + {distanceUnits[distanceUnitIndex].label} |
| 136 | + </span> |
| 137 | + </p> |
| 138 | + <p className="mb-2"> |
| 139 | + Total unique airports visited:{' '} |
| 140 | + <span className="font-medium">{statistics.totalUniqueAirports}</span> |
| 141 | + </p> |
| 142 | + <p className="mb-2"> |
| 143 | + Range of days:{' '} |
| 144 | + <span className="font-medium">{statistics.daysRange} days</span> |
| 145 | + </p> |
103 | 146 | </div> |
104 | | - |
| 147 | + |
105 | 148 | <div className="container"> |
106 | 149 | <h3 className="text-lg font-semibold mb-4">Most visited airports</h3> |
107 | | - <StatFrequency object={statistics.mostVisitedAirports} measure="visits"/> |
| 150 | + <StatFrequency object={statistics.mostVisitedAirports} measure="visits" /> |
108 | 151 | </div> |
109 | | - |
| 152 | + |
110 | 153 | <div className="container"> |
111 | 154 | <h3 className="text-lg font-semibold mb-4">Most common seat</h3> |
112 | | - <StatFrequency object={statistics.seatFrequency} measure="flights"/> |
| 155 | + <StatFrequency object={statistics.seatFrequency} measure="flights" /> |
113 | 156 | </div> |
114 | | - |
| 157 | + |
115 | 158 | <div className="container"> |
116 | 159 | <h3 className="text-lg font-semibold mb-4">Most common class</h3> |
117 | | - <StatFrequency object={statistics.ticketClassFrequency} measure="flights"/> |
| 160 | + <StatFrequency object={statistics.ticketClassFrequency} measure="flights" /> |
118 | 161 | </div> |
119 | | - |
| 162 | + |
120 | 163 | <div className="container"> |
121 | 164 | <h3 className="text-lg font-semibold mb-4">Most common airlines</h3> |
122 | | - <StatFrequency object={statistics.mostCommonAirlines} measure="flights"/> |
| 165 | + <StatFrequency object={statistics.mostCommonAirlines} measure="flights" /> |
123 | 166 | </div> |
124 | | - </div> |
125 | | - ); |
| 167 | + |
| 168 | + </div> |
| 169 | + ); |
126 | 170 | } |
| 171 | + |
0 commit comments