From c05793f9d131cb6d0391593d1ac05938fbafc64d Mon Sep 17 00:00:00 2001 From: Martin Heppner <105971399+martinheppner@users.noreply.github.com> Date: Fri, 6 Sep 2024 23:51:25 +0200 Subject: [PATCH] Revert "Merge branch 'uat' into dev" This reverts commit 0f07cb7a91ed3021e5bd34041c107ab13d6b3d65, reversing changes made to 96b0806050f3f2645eee155bb280907f4313881b. --- 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 | 55 ++-- src/views/Start/Start.js | 184 +++++++------- 6 files changed, 429 insertions(+), 431 deletions(-) diff --git a/src/App.js b/src/App.js index 088896ba..b8565059 100644 --- a/src/App.js +++ b/src/App.js @@ -1,119 +1,97 @@ -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 ModalRoot from "./components/ModalRoot"; +import ThemeProvider from "@mui/material/styles/ThemeProvider"; import { theme } from "./theme"; -import Start from "./views/Start/Start"; +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 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(); + //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}); + }); - //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 }); - }, []); + return ( + <> + +
+ + +
+ } + > + + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> - return ( - <> - -
- - -
- } - > - - } /> - } /> - } /> - } - /> - } /> - } - /> - } /> - } /> - } /> - } /> + } /> + + + + +
+ - } - /> -
- - - -
- - ); + ); } export default App; diff --git a/src/components/Itinerary/ItineraryCalendar.js b/src/components/Itinerary/ItineraryCalendar.js index 83b86274..5dc62213 100644 --- a/src/components/Itinerary/ItineraryCalendar.js +++ b/src/components/Itinerary/ItineraryCalendar.js @@ -1,88 +1,87 @@ +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 = connectionData?.map((con) => moment(con.date)); - } + if (!connectionData || (!dateIndex && dateIndex !== 0)) { + return <>; + } else { + days = _.map(connectionData, (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 fe2cb31e..a261c34e 100644 --- a/src/components/Search/AutosuggestSearch.js +++ b/src/components/Search/AutosuggestSearch.js @@ -1,48 +1,53 @@ 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 handleSelect = (phrase) => { - const value = phrase ? phrase : searchPhrase ? searchPhrase : ""; - onSearchSuggestion(value); - }; +const AutosuggestSearchTour = ({ + onSearchSuggestion, + city, + language, +}) => { - //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 [options, setOptions] = useState([]); + const urlSearchParams = new URLSearchParams(window.location.search); + let searchParam = urlSearchParams.get("search"); + const [searchPhrase, setSearchPhrase] = useState(searchParam ?? ""); - return ( -
- -
- ); + 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 ( +
+ +
+ ); }; export default AutosuggestSearchTour; diff --git a/src/components/Search/Search.js b/src/components/Search/Search.js index 62093975..9d8aadd5 100644 --- a/src/components/Search/Search.js +++ b/src/components/Search/Search.js @@ -1,35 +1,34 @@ /* eslint-disable react-hooks/exhaustive-deps */ -import { Modal, Typography, useMediaQuery } from "@mui/material"; +import * as React from "react"; +import { useRef } from "react"; import Box from "@mui/material/Box"; import Grid from "@mui/material/Grid"; -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 {loadTours } from "../../actions/tourActions"; +import { compose } from "redux"; 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 { loadFavouriteTours, loadTours } from "../../actions/tourActions"; -import Close from "../../icons/Close"; +import FullScreenCityInput from "./FullScreenCityInput"; +import { useTranslation } from "react-i18next"; +import i18next from "i18next"; 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 { - 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); +import { capitalize } from "lodash"; +import { Modal, Typography, useMediaQuery } from "@mui/material"; +import Close from "../../icons/Close"; +import '/src/config.js'; export function Search({ loadTours, @@ -48,8 +47,8 @@ export function Search({ setFilterValues, filterValues, mapBounds, - // idOne, - // cityOne + filterOn, + setFilterOn }) { //navigation const navigate = useNavigate(); @@ -137,7 +136,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 @@ -186,7 +185,6 @@ export function Search({ } // flag active filter if count > 0 !!filterCountLocal && setActiveFilter(filterCountLocal > 0); - // filter && setActiveFilter(countFilterActive(searchParams, filter) > 0); const bounds = !!searchParams.get("map") && @@ -209,7 +207,7 @@ export function Search({ }); result.then((res) => { - let importedMarkersArray = res.data.markers; + let importedMarkersArray = res?.data?.markers; if ( !isMasterMarkersSet.current && @@ -249,23 +247,32 @@ export function Search({ localStorage.setItem("filterCount", 0); }; - // Filter modal constructed here + + const openFilter = () => { - showModal("MODAL_COMPONENT", { - CustomComponent: Filter, - title: t("filter.filter"), - page: "main", - modalSize: "lg", - doSubmit: handleFilterSubmit, - resetFilter: handleResetFilter, - onBack: () => { - hideModal(); - }, - searchParams, - setSearchParams, - }); + setFilterOn(true) }; + 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 @@ -297,6 +304,7 @@ export function Search({ setCounter(0); setFilterValues(null); // reset state in parent Main resetFilterLocalStorage(); + setFilterOn(false) }; const handleFilterChange = (entry) => { @@ -371,39 +379,42 @@ 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(); - } + 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(); + }, + }); + } - 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", { @@ -411,6 +422,7 @@ export function Search({ searchParams, initialCity: cityInput, onSelect: async (city) => { + if (!!cityOne && !!idOne && pageKey === "detail") { setCityInput(city.label); setCity(city.value); @@ -421,11 +433,12 @@ 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", @@ -613,11 +626,7 @@ export function Search({ > - {t("start.heimatbahnhof")} + {t("search.dein_heimatbahnhof")} - - {!cityInput && pageKey ? ( - - ) : ( - - )} + {pageKey !== "detail" ? ( - - {cityInput.length > 0 - ? cityInput - : t("start.heimatbahnhof")} - + + <> + {!isMobile && ( + + )} + {cityInput.length > 0 + ? `${t("search.ab_heimatbahnhof")} ${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,20 +159,29 @@ export default function Header({ > - + - - {totalTours > 0 && ( - - {totalTours.toLocaleString()}{" "} - {t( - totalToursFromCity === 0 - ? "start.tourenanzahl_untertitel" - : "start.tourenanzahl_untertitel_city", - { capCity } - )} - - )} + + <> + {!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 })} + + )} + {!!allCities && allCities.length > 0 && ( @@ -37,7 +36,6 @@ function Start({ loadFavouriteTours, favouriteTours, loadCities, - loadTourConnections, totalTours, loadTour, loadTotalTours, @@ -191,89 +189,96 @@ function Start({ return ( {getPageHeader({ header: `Zuugle ${t(`${country}`)}` })} -
- - - - {t("start.zuugle_sucht_fuer_dich_1")} {totalProvider}{" "} - {t("start.zuugle_sucht_fuer_dich_2")} - - - + { +
+ } - - - - {getFavouriteToursText()} - - + { + + + + {t("start.zuugle_sucht_fuer_dich_1")} {totalProvider}{" "} + {t("start.zuugle_sucht_fuer_dich_2")} + + - - - + - {getRangeText()} - - - + + {getFavouriteToursText()} + + + - - + + + {getRangeText()} + + + + + + + - + } - + { + + } -