1
import Sidebar from "./components/Sidebar";
2
import { Sorter, Filter, PickAirlines, PriceRange } from "./components/Sidebar";
3
import FlightList from "./components/FlightList";
4
import Logo from "./components/Logo";
5
import { useState, useEffect } from "react";
7
export default function App() {
8
const [flightsData, setFlightsData] = useState(null);
9
const [flightsDataLoading, setFlightsDataLoading] = useState(false);
10
const [errorLoadingData, setErrorLoadingData] = useState("");
11
const [sortBy, setSortBy] = useState("price-increase");
12
const [filterBy, setFilterBy] = useState("");
13
const [minPriceRange, setMinPriceRange] = useState("");
14
const [maxPriceRange, setMaxPriceRange] = useState("");
15
const [pickedAirlines, setPickedAirlines] = useState([]);
16
const [displayedNumber, setDisplayedNumber] = useState(2);
17
const [highestPrice, setHighestPrice] = useState("");
18
const [lowestPrice, setLowestPrice] = useState(0);
19
const [filteredFlights, setFilteredFlights] = useState([]);
20
const [bestPricesArr, setBestPricesArr] = useState([]);
22
function handleShowMore() {
23
setDisplayedNumber(curNum => curNum + 2)
26
useEffect(function () {
27
async function importData() {
29
setFlightsDataLoading(true);
30
setErrorLoadingData("");
32
const data = (await import("./flights.json")).default
34
if (!data) throw new Error("Ошибка в загрузке данных");
38
setErrorLoadingData(err.message)
39
} finally { setFlightsDataLoading(false) }
42
}, [setFlightsData, setFlightsDataLoading, setErrorLoadingData])
44
useEffect(function filteringFlights() {
47
const { result: { bestPrices, flights } } = flightsData;
48
setBestPricesArr(bestPrices);
49
setFilteredFlights(flights);
51
setFilteredFlights((cur) => cur
52
.filter(flight => (flight?.flight?.price?.total?.amount >= (minPriceRange || 0)))
53
.filter(flight => (flight?.flight?.price?.total?.amount <= (maxPriceRange || flight?.flight?.price.total.amount)))
56
if (filterBy === "single-transfer") {
57
setFilteredFlights((cur) => cur.filter(flight => flight?.flight?.legs[0]?.segments.length === 2 && flight?.flight?.legs[1]?.segments.length === 2));
60
if (filterBy === "no-transfer") {
61
setFilteredFlights((cur) => cur.filter(flight => flight?.flight?.legs[0]?.segments.length === 1 && flight?.flight?.legs[1]?.segments.length === 1));
64
if (sortBy === "price-increase") {
65
setFilteredFlights((cur) => cur.sort((flightA, flightB) => flightA?.flight?.price?.total?.amount - flightB?.flight?.price?.total?.amount));
68
if (sortBy === "price-decrease") {
69
setFilteredFlights((cur) => cur.sort((flightA, flightB) => flightB?.flight?.price?.total?.amount - flightA?.flight?.price?.total?.amount));
72
if (sortBy === "travel-duration") {
73
setFilteredFlights((cur) => cur.sort((flightA, flightB) => {
74
const totalDurationA = flightA?.flight?.legs.reduce((total, leg) => total + leg?.duration, 0);
75
const totalDurationB = flightB?.flight?.legs.reduce((total, leg) => total + leg?.duration, 0);
76
return totalDurationA - totalDurationB;
80
}, [flightsData, sortBy, filterBy, minPriceRange, maxPriceRange])
82
useEffect(function updatePickedAirlines() {
83
setPickedAirlines((cur) => cur.filter((airline) => {
84
return filteredFlights.some((flight) => flight?.flight?.carrier?.caption === airline)
86
}, [filteredFlights, setPickedAirlines])
88
useEffect(function findPriceRange() {
89
if (filteredFlights.length > 0) {
90
setHighestPrice(filteredFlights.reduce((maxPrice, flight) => {
91
const flightTotalPrice = parseInt(flight?.flight?.price?.total?.amount) || 0;
92
return Math.max(maxPrice, flightTotalPrice);
93
}, parseInt(filteredFlights[0]?.flight?.price?.total?.amount)))
95
setLowestPrice(filteredFlights.reduce((minPrice, flight) => {
96
const flightTotalPrice = parseInt(flight?.flight?.price?.total?.amount) || 0;
97
return Math.min(minPrice, flightTotalPrice);
98
}, parseInt(filteredFlights[0]?.flight?.price?.total?.amount)))
101
}, [filteredFlights, filterBy, setMaxPriceRange, setMinPriceRange])
104
<div className="app">
105
<div className="container">
107
<Sidebar flightsData={flightsData}>
108
<Sorter sortBy={sortBy} onSortBy={setSortBy} />
109
<Filter filterBy={filterBy} onFilterBy={setFilterBy} />
110
<PriceRange lowestPrice={lowestPrice} highestPrice={highestPrice} minPriceRange={minPriceRange} maxPriceRange={maxPriceRange} onMinPriceRange={setMinPriceRange} onMaxPriceRange={setMaxPriceRange} />
111
<PickAirlines minPriceRange={minPriceRange} maxPriceRange={maxPriceRange} flightsData={flightsData} flightsDataLoading={flightsDataLoading} errorLoadingData={errorLoadingData} filterBy={filterBy} bestPricesArr={bestPricesArr} filteredFlights={filteredFlights} pickedAirlines={pickedAirlines} onPickedAirlines={setPickedAirlines} />
113
<FlightList pickedAirlines={pickedAirlines} displayedNumber={displayedNumber} onShowMore={handleShowMore} minPriceRange={minPriceRange} maxPriceRange={maxPriceRange} sortBy={sortBy} filterBy={filterBy} filteredFlights={filteredFlights} flightsDataLoading={flightsDataLoading} errorLoadingData={errorLoadingData} />