From d5df77810d4f906f49077cc17a4af13e992e7464 Mon Sep 17 00:00:00 2001 From: shiv Date: Thu, 5 Sep 2024 20:06:54 +0530 Subject: [PATCH 1/4] loading issue fix --- src/App.js | 174 +++++++------ src/components/Itinerary/ItineraryCalendar.js | 127 +++++----- src/components/Search/AutosuggestSearch.js | 83 +++--- src/components/Search/Search.js | 237 +++++++++--------- src/views/Start/Header.js | 57 ++--- src/views/Start/Start.js | 184 +++++++------- 6 files changed, 432 insertions(+), 430 deletions(-) diff --git a/src/App.js b/src/App.js index b8565059..088896ba 100644 --- a/src/App.js +++ b/src/App.js @@ -1,97 +1,119 @@ +import CircularProgress from "@mui/material/CircularProgress"; +import ThemeProvider from "@mui/material/styles/ThemeProvider"; import * as React from "react"; +import { lazy, Suspense } from "react"; +import { Navigate, Route, Routes } from "react-router-dom"; import "./App.css"; -import ThemeProvider from "@mui/material/styles/ThemeProvider"; -import { theme } from "./theme"; import ModalRoot from "./components/ModalRoot"; -import { Route, Routes, Navigate } from "react-router-dom"; -import { lazy, Suspense, useCallback } from "react"; -import CircularProgress from "@mui/material/CircularProgress"; -// import Start from "./views/Start/Start"; +import { theme } from "./theme"; +import Start from "./views/Start/Start"; // import DetailReworked from "./views/Main/DetailReworked"; // import Search from "./components/Search/Search"; import i18next from "i18next"; import { getTopLevelDomain } from "./utils/globals"; -import '/src/config.js'; +import "/src/config.js"; const Main = lazy(() => import("./views/Main/Main")); const Impressum = lazy(() => import("./views/Pages/Impressum")); const Privacy = lazy(() => import("./views/Pages/Privacy")); -const DetailReworked = lazy(() => import("./views/Main/DetailReworked")); -const Search = lazy(() => import("./components/Search/Search")); -const Start = lazy(() => import("./views/Start/Start")); - - - +const DetailReworked = lazy(() => import("./views/Main/DetailReworked")); +const Search = lazy(() => import("./components/Search/Search")); +// const Start = lazy(() => import("./views/Start/Start")); function App() { - //check if first visit and change code to domain language - if(!localStorage.getItem('visited')) { - - let domain = getTopLevelDomain(); - - //switch to domain language - switch (domain) { - case 'si': - i18next.changeLanguage('sl'); - break; - case 'fr': - i18next.changeLanguage('fr'); - break; - case 'it': - i18next.changeLanguage('it'); - break; - default: - i18next.changeLanguage('de'); - break; - } - - localStorage.setItem('visited',true); - } - - // Matomo tracking - var _mtm = window._mtm = window._mtm || []; - React.useEffect(() => { - _mtm.push({'mtm.startTime': (new Date().getTime()), 'event': 'mtm.Start'}); - var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; - g.async=true; g.src='https://stats.bahnzumberg.at/js/container_ANAXmMKf.js'; s.parentNode.insertBefore(g,s); - let language = i18next.resolvedLanguage; - _mtm.push({'language': language}); - }); + //check if first visit and change code to domain language + if (!localStorage.getItem("visited")) { + let domain = getTopLevelDomain(); + //switch to domain language + switch (domain) { + case "si": + i18next.changeLanguage("sl"); + break; + case "fr": + i18next.changeLanguage("fr"); + break; + case "it": + i18next.changeLanguage("it"); + break; + default: + i18next.changeLanguage("de"); + break; + } + localStorage.setItem("visited", true); + } - return ( - <> - -
- - -
- } - > - - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> + // Matomo tracking + var _mtm = (window._mtm = window._mtm || []); + React.useEffect(() => { + _mtm.push({ + "mtm.startTime": new Date().getTime(), + event: "mtm.Start", + }); + var d = document, + g = d.createElement("script"), + s = d.getElementsByTagName("script")[0]; + g.async = true; + g.src = "https://stats.bahnzumberg.at/js/container_ANAXmMKf.js"; + s.parentNode.insertBefore(g, s); + let language = i18next.resolvedLanguage; + _mtm.push({ language: language }); + }, []); - } /> - - - - -
- + return ( + <> + +
+ + +
+ } + > + + } /> + } /> + } /> + } + /> + } /> + } + /> + } /> + } /> + } /> + } /> - ); + } + /> + + + + +
+ + ); } export default App; diff --git a/src/components/Itinerary/ItineraryCalendar.js b/src/components/Itinerary/ItineraryCalendar.js index 5dc62213..83b86274 100644 --- a/src/components/Itinerary/ItineraryCalendar.js +++ b/src/components/Itinerary/ItineraryCalendar.js @@ -1,87 +1,88 @@ -import React from "react"; import moment from "moment"; import "moment/locale/de"; import "moment/locale/fr"; import "moment/locale/it"; import "moment/locale/sl"; +import React from "react"; import { useTranslation } from "react-i18next"; -import * as _ from "lodash"; const formatDate = (date, locale) => { - const formats = { - fr: "dddd D MMMM YYYY", - de: "dddd, D. MMMM YYYY", - sl: "dddd, D. MMMM YYYY", - it: "dddd D MMMM YYYY", - en: "dddd, D MMMM YYYY", - }; - moment.locale(locale); - return date.format(formats[locale]); + const formats = { + fr: "dddd D MMMM YYYY", + de: "dddd, D. MMMM YYYY", + sl: "dddd, D. MMMM YYYY", + it: "dddd D MMMM YYYY", + en: "dddd, D MMMM YYYY", + }; + moment.locale(locale); + return date.format(formats[locale]); }; const dayOfWeek = (date, locale) => { - moment.locale(locale); - return moment(date).format("dd"); + moment.locale(locale); + return moment(date).format("dd"); }; const isWe = (date) => { - const d = date.isoWeekday(); - return d === 6 || d === 7; + const d = date.isoWeekday(); + return d === 6 || d === 7; }; const isSelectedDay = (date, selectedDay) => { - return date.isSame(selectedDay, "day"); + return date.isSame(selectedDay, "day"); }; -const ItineraryCalendar = ({ - connectionData, - dateIndex, - updateConnIndex -}) => { - const { t, i18n } = useTranslation(); - let selectedDay = dateIndex; - let days = []; +const ItineraryCalendar = ({ connectionData, dateIndex, updateConnIndex }) => { + const { t, i18n } = useTranslation(); + let selectedDay = dateIndex; + let days = []; - if (!connectionData || (!dateIndex && dateIndex !== 0)) { - return <>; - } else { - days = _.map(connectionData, (con) => moment(con.date)); - } + if (!connectionData || (!dateIndex && dateIndex !== 0)) { + return <>; + } else { + days = connectionData?.map((con) => moment(con.date)); + } - return ( -
-
- {formatDate(moment(connectionData[selectedDay].date), i18n.language)} -
-
- {days.map((dd) => ( -
- {dayOfWeek(dd, i18n.language)} -
- ))} - {days.map((dd, index) => ( -
updateConnIndex(index)} - > - {dd.date()} -
- ))} -
-
- ); + return ( +
+
+ {formatDate( + moment(connectionData[selectedDay].date), + i18n.language + )} +
+
+ {days.map((dd) => ( +
+ {dayOfWeek(dd, i18n.language)} +
+ ))} + {days.map((dd, index) => ( +
updateConnIndex(index)} + > + {dd.date()} +
+ ))} +
+
+ ); }; export default ItineraryCalendar; diff --git a/src/components/Search/AutosuggestSearch.js b/src/components/Search/AutosuggestSearch.js index a261c34e..fe2cb31e 100644 --- a/src/components/Search/AutosuggestSearch.js +++ b/src/components/Search/AutosuggestSearch.js @@ -1,53 +1,48 @@ import React, { useState } from "react"; import { loadSuggestions } from "../../actions/crudActions"; import CustomSelect from "./CustomSelect"; -import { isArray } from "lodash"; +const AutosuggestSearchTour = ({ onSearchSuggestion, city, language }) => { + const [options, setOptions] = useState([]); + const urlSearchParams = new URLSearchParams(window.location.search); + let searchParam = urlSearchParams.get("search"); + const [searchPhrase, setSearchPhrase] = useState(searchParam ?? ""); -const AutosuggestSearchTour = ({ - onSearchSuggestion, - city, - language, -}) => { + const handleSelect = (phrase) => { + const value = phrase ? phrase : searchPhrase ? searchPhrase : ""; + onSearchSuggestion(value); + }; - const [options, setOptions] = useState([]); - const urlSearchParams = new URLSearchParams(window.location.search); - let searchParam = urlSearchParams.get("search"); - const [searchPhrase, setSearchPhrase] = useState(searchParam ?? ""); + //What the component should do while I type in values + const handleInputChange = (inputValue) => { + if (city !== null) { + setSearchPhrase(inputValue); + loadSuggestions(inputValue, city.value, language) //Call the backend + .then((suggestions) => { + const newOptions = suggestions?.map((suggestion) => ({ + //Get the New suggestions and format them the correct way + label: suggestion.suggestion, + value: suggestion.suggestion, + })); + newOptions && + Array.isArray(newOptions) && + setOptions([...newOptions]); + }) + .catch((err) => { + console.error(err); + }); + } + }; - const handleSelect = (phrase) => { - const value = phrase ? phrase : searchPhrase ? searchPhrase : ""; - onSearchSuggestion(value); - }; - - //What the component should do while I type in values - const handleInputChange = (inputValue) => { - if (city !== null) { - setSearchPhrase(inputValue); - loadSuggestions(inputValue, city.value, language) //Call the backend - .then((suggestions) => { - const newOptions = suggestions?.map((suggestion) => ({ - //Get the New suggestions and format them the correct way - label: suggestion.suggestion, - value: suggestion.suggestion, - })); - newOptions && isArray(newOptions) && setOptions([...newOptions]); - }) - .catch((err) => { - console.error(err); - }); - } - }; - - return ( -
- -
- ); + return ( +
+ +
+ ); }; export default AutosuggestSearchTour; diff --git a/src/components/Search/Search.js b/src/components/Search/Search.js index 9d8aadd5..62093975 100644 --- a/src/components/Search/Search.js +++ b/src/components/Search/Search.js @@ -1,34 +1,35 @@ /* eslint-disable react-hooks/exhaustive-deps */ -import * as React from "react"; -import { useRef } from "react"; +import { Modal, Typography, useMediaQuery } from "@mui/material"; import Box from "@mui/material/Box"; import Grid from "@mui/material/Grid"; -import {loadTours } from "../../actions/tourActions"; -import { compose } from "redux"; +import IconButton from "@mui/material/IconButton"; +import i18next from "i18next"; +import * as React from "react"; +import { Fragment, useEffect, useRef, useState } from "react"; +import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; -import { Fragment, useEffect, useState } from "react"; -import { useSearchParams, useParams } from "react-router-dom"; -import { - parseIfNeccessary, - setOrRemoveSearchParam, - getTopLevelDomain, -} from "../../utils/globals"; import { useNavigate } from "react-router"; +import { useParams, useSearchParams } from "react-router-dom"; +import { compose } from "redux"; +import { loadCities } from "../../actions/cityActions"; import { hideModal, showModal } from "../../actions/modalActions"; -import FullScreenCityInput from "./FullScreenCityInput"; -import { useTranslation } from "react-i18next"; -import i18next from "i18next"; +import { loadFavouriteTours, loadTours } from "../../actions/tourActions"; +import Close from "../../icons/Close"; import FilterIcon from "../../icons/FilterIcon"; -import IconButton from "@mui/material/IconButton"; import GoIcon from "../../icons/GoIcon"; -import AutosuggestSearchTour from "./AutosuggestSearch"; -import Filter from "../Filter/Filter"; import SearchIcon from "../../icons/SearchIcon"; import TransportTrain from "../../icons/TransportTrain"; -import { capitalize } from "lodash"; -import { Modal, Typography, useMediaQuery } from "@mui/material"; -import Close from "../../icons/Close"; -import '/src/config.js'; +import { + getTopLevelDomain, + parseIfNeccessary, + setOrRemoveSearchParam, +} from "../../utils/globals"; +import Filter from "../Filter/Filter"; +import AutosuggestSearchTour from "./AutosuggestSearch"; +import FullScreenCityInput from "./FullScreenCityInput"; +import "/src/config.js"; + +const capitalize = (str) => str?.charAt(0).toUpperCase() + str?.slice(1); export function Search({ loadTours, @@ -47,8 +48,8 @@ export function Search({ setFilterValues, filterValues, mapBounds, - filterOn, - setFilterOn + // idOne, + // cityOne }) { //navigation const navigate = useNavigate(); @@ -136,7 +137,7 @@ export function Search({ } //setting searchPhrase to the value of the search parameter - + if (!!search) { setSearchPhrase(search); //TODO : do we need to do actual search if search is a city? see line 138 comment @@ -185,6 +186,7 @@ export function Search({ } // flag active filter if count > 0 !!filterCountLocal && setActiveFilter(filterCountLocal > 0); + // filter && setActiveFilter(countFilterActive(searchParams, filter) > 0); const bounds = !!searchParams.get("map") && @@ -207,7 +209,7 @@ export function Search({ }); result.then((res) => { - let importedMarkersArray = res?.data?.markers; + let importedMarkersArray = res.data.markers; if ( !isMasterMarkersSet.current && @@ -247,32 +249,23 @@ export function Search({ localStorage.setItem("filterCount", 0); }; - - + // Filter modal constructed here const openFilter = () => { - setFilterOn(true) + showModal("MODAL_COMPONENT", { + CustomComponent: Filter, + title: t("filter.filter"), + page: "main", + modalSize: "lg", + doSubmit: handleFilterSubmit, + resetFilter: handleResetFilter, + onBack: () => { + hideModal(); + }, + searchParams, + setSearchParams, + }); }; - useEffect(() => { - if (filterOn) { - showModal("MODAL_COMPONENT", { - CustomComponent: Filter, - title: t("filter.filter"), - page: "main", - modalSize: "lg", - doSubmit: handleFilterSubmit, - resetFilter: handleResetFilter, - onBack: () => { - setFilterOn(false); // Reset filterOn when closing the modal - hideModal(); - }, - searchParams, - setSearchParams, - filterOn: filterOn, // Now filterOn is true when the modal opens - }); - } - }, [filterOn]); - //important: // state filterValues(from Main) should be set at submission here // or be set at at handleResetFilter to null @@ -304,7 +297,6 @@ export function Search({ setCounter(0); setFilterValues(null); // reset state in parent Main resetFilterLocalStorage(); - setFilterOn(false) }; const handleFilterChange = (entry) => { @@ -379,42 +371,39 @@ export function Search({ const showCityModal = () => { if (isMobile) { - setShowMobileModal(true) - }else{ - - showModal("MODAL_COMPONENT", { - CustomComponent: FullScreenCityInput, - searchParams, - initialCity: cityInput, - onSelect: async (city) => { - - if (!!city) { - setCityInput(city.label); - setCity(city); - pageKey === "start" && updateCapCity(city.label); - searchParams.set('city', city.value); - setSearchParams(searchParams) - window.location.reload() - } - - hideModal(); - }, - cityOne: cityOne , - idOne: idOne , - setSearchParams, - title: "", - sourceCall: "city", - page: page, - srhBoxScrollH: document - .querySelector(".main-search-bar") - .getBoundingClientRect().top, - modalSize: "lg", - onBack: () => { - hideModal(); - }, - }); - } + setShowMobileModal(true); + } else { + showModal("MODAL_COMPONENT", { + CustomComponent: FullScreenCityInput, + searchParams, + initialCity: cityInput, + onSelect: async (city) => { + if (!!city) { + setCityInput(city.label); + setCity(city); + pageKey === "start" && updateCapCity(city.label); + searchParams.set("city", city.value); + setSearchParams(searchParams); + window.location.reload(); + } + hideModal(); + }, + cityOne: cityOne, + idOne: idOne, + setSearchParams, + title: "", + sourceCall: "city", + page: page, + srhBoxScrollH: document + .querySelector(".main-search-bar") + .getBoundingClientRect().top, + modalSize: "lg", + onBack: () => { + hideModal(); + }, + }); + } }; const showCityModalMobile = () => { showModal("MODAL_COMPONENT", { @@ -422,7 +411,6 @@ export function Search({ searchParams, initialCity: cityInput, onSelect: async (city) => { - if (!!cityOne && !!idOne && pageKey === "detail") { setCityInput(city.label); setCity(city.value); @@ -433,12 +421,11 @@ export function Search({ pageKey === "start" && updateCapCity(city.label); searchParams.set("city", city.value); setSearchParams(searchParams); - } hideModal(); }, - cityOne: cityOne , - idOne: idOne , + cityOne: cityOne, + idOne: idOne, setSearchParams, title: "", sourceCall: "city", @@ -626,7 +613,11 @@ export function Search({ > - {t("search.dein_heimatbahnhof")} + {t("start.heimatbahnhof")} - - + {!cityInput && pageKey ? ( + + ) : ( + + )} {pageKey !== "detail" ? ( - - <> - {!isMobile && ( - - )} - {cityInput.length > 0 - ? `${t("search.ab_heimatbahnhof")} ${cityInput}` - : t("start.heimatbahnhof")} - - + + {cityInput.length > 0 + ? cityInput + : t("start.heimatbahnhof")} + ) : !cityInput && pageKey === "detail" ? ( { let _city = getCity(); if (!!_city) { - setLoading(true); + // setLoading(true); getTotalCityTours(city).then((data) => { setTotalToursFromCity(data.tours_city); - if (!!data.tours_city && data.tours_city > 0) setLoading(false); + // if (!!data.tours_city && data.tours_city > 0) setLoading(false); }); } }, [city]); @@ -70,7 +70,7 @@ export default function Header({ useEffect(() => { // city = searchParams.get("city"); if (!!city && !!allCities && allCities.length > 0) { - const cityObj = allCities.find((e) => e.value === city); // find the city object in array "allCities" + const cityObj = allCities.find((e) => e.value == city); // find the city object in array "allCities" if (!!cityObj) { updateCapCity(cityObj.label); searchParams.set("city", city); @@ -159,29 +159,20 @@ export default function Header({ > - + - - <> - {!loading && !!totalTours && totalToursFromCity === 0 && ( - - {!!totalTours && - totalTours !== 0 && - totalTours.toLocaleString() + - " " + - t("start.tourenanzahl_untertitel")} - - )} - {!loading && !!totalToursFromCity && ( - - {!!totalToursFromCity && - totalToursFromCity !== 0 && - totalToursFromCity.toLocaleString() + - " " + - t("start.tourenanzahl_untertitel_city", { capCity })} - - )} - + + {totalTours > 0 && ( + + {totalTours.toLocaleString()}{" "} + {t( + totalToursFromCity === 0 + ? "start.tourenanzahl_untertitel" + : "start.tourenanzahl_untertitel_city", + { capCity } + )} + + )} {!!allCities && allCities.length > 0 && ( @@ -36,6 +37,7 @@ function Start({ loadFavouriteTours, favouriteTours, loadCities, + loadTourConnections, totalTours, loadTour, loadTotalTours, @@ -189,96 +191,89 @@ function Start({ return ( {getPageHeader({ header: `Zuugle ${t(`${country}`)}` })} - { -
- } - - { - - - - {t("start.zuugle_sucht_fuer_dich_1")} {totalProvider}{" "} - {t("start.zuugle_sucht_fuer_dich_2")} - - +
+ + + + {t("start.zuugle_sucht_fuer_dich_1")} {totalProvider}{" "} + {t("start.zuugle_sucht_fuer_dich_2")} + - } - { - - + + + + - - {getFavouriteToursText()} - - - + {getFavouriteToursText()} + + + - - - {getRangeText()} - - - + + + {getRangeText()} + + + - - - + + - } + - { - - } + - {