From a69fbe6c4b0a6e846e6f1fb83046ee3d922b896c Mon Sep 17 00:00:00 2001 From: Margarita Date: Fri, 7 Apr 2023 12:02:17 +0400 Subject: [PATCH 1/2] feat(in-454): default landing --- src/config/lexics/indexLexics.tsx | 2 + src/config/lexics/landingLexics.tsx | 9 + src/features/App/AuthenticatedApp.tsx | 4 +- src/features/AuthStore/hooks/useAuth.tsx | 27 ++- .../TeamLogoImg/index.tsx | 6 +- .../helpers.tsx | 0 src/features/Landings/hooks.tsx | 163 +++++++++++++++ src/features/Landings/index.tsx | 193 ++++++++++++++++++ .../styled.tsx | 54 ++--- src/features/MatchPage/store/hooks/index.tsx | 28 ++- src/features/TournamentLanding/hooks.tsx | 96 --------- src/features/TournamentLanding/index.tsx | 134 ------------ src/features/TournamentPage/hooks.tsx | 46 ++++- ...etTournamentLanding.tsx => getLanding.tsx} | 24 ++- src/requests/getLandingMedia.tsx | 25 +++ src/requests/getLandingStatus.tsx | 20 +- src/requests/index.tsx | 2 +- 17 files changed, 549 insertions(+), 284 deletions(-) create mode 100644 src/config/lexics/landingLexics.tsx rename src/features/{TournamentLanding => Landings}/TeamLogoImg/index.tsx (76%) rename src/features/{TournamentLanding => Landings}/helpers.tsx (100%) create mode 100644 src/features/Landings/hooks.tsx create mode 100644 src/features/Landings/index.tsx rename src/features/{TournamentLanding => Landings}/styled.tsx (88%) delete mode 100644 src/features/TournamentLanding/hooks.tsx delete mode 100644 src/features/TournamentLanding/index.tsx rename src/requests/{getTournamentLanding.tsx => getLanding.tsx} (64%) create mode 100644 src/requests/getLandingMedia.tsx diff --git a/src/config/lexics/indexLexics.tsx b/src/config/lexics/indexLexics.tsx index 95118ce8..7830ed5e 100644 --- a/src/config/lexics/indexLexics.tsx +++ b/src/config/lexics/indexLexics.tsx @@ -3,6 +3,7 @@ import { publicLexics } from './public' import { highlightsPageLexic } from './highlightsPageLexic' import { mailingsLexics } from './mailings' import { sportsLexic } from './sportsLexic' +import { landingLexics } from './landingLexics' const matchPopupLexics = { actions: 1020, @@ -219,4 +220,5 @@ export const indexLexics = { ...paymentLexics, ...sportsLexic, ...sportsPopup, + ...landingLexics, } diff --git a/src/config/lexics/landingLexics.tsx b/src/config/lexics/landingLexics.tsx new file mode 100644 index 00000000..fb81f158 --- /dev/null +++ b/src/config/lexics/landingLexics.tsx @@ -0,0 +1,9 @@ +export const landingLexics = { + default_season: 19983, + inactive_button: 20083, + inactive_description_1: 20084, + inactive_description_2: 20086, + inactive_period: 801, + inactive_title_1: 20087, + inactive_title_2: 20088, +} diff --git a/src/features/App/AuthenticatedApp.tsx b/src/features/App/AuthenticatedApp.tsx index 9d010011..cddfc571 100644 --- a/src/features/App/AuthenticatedApp.tsx +++ b/src/features/App/AuthenticatedApp.tsx @@ -35,7 +35,7 @@ const MatchPage = lazy(() => import('features/MatchPage')) const PlayerPage = lazy(() => import('features/PlayerPage')) const TournamentPage = lazy(() => import('features/TournamentPage')) const SystemSettings = lazy(() => import('features/SystemSettings')) -const TournamentLanding = lazy(() => import('features/TournamentLanding')) +const Landings = lazy(() => import('features/Landings')) const HighlightsPage = lazy(() => import('pages/HighlightsPage')) const ThanksPage = lazy(() => import('pages/ThanksPage')) @@ -96,7 +96,7 @@ export const AuthenticatedApp = () => { - + diff --git a/src/features/AuthStore/hooks/useAuth.tsx b/src/features/AuthStore/hooks/useAuth.tsx index 54e701bf..b2d18ce0 100644 --- a/src/features/AuthStore/hooks/useAuth.tsx +++ b/src/features/AuthStore/hooks/useAuth.tsx @@ -10,6 +10,7 @@ import type { User } from 'oidc-client' import isString from 'lodash/isString' import isBoolean from 'lodash/isBoolean' +import includes from 'lodash/includes' import { PAGES } from 'config' @@ -20,7 +21,6 @@ import { readToken, setCookie, removeCookie, - isMatchPage, TOKEN_KEY, } from 'helpers' @@ -125,15 +125,12 @@ export const useAuth = () => { validator: isBoolean, }) - useEffect(() => { - if (isMatchPage()) setPage(history.location.pathname) - if (history.location.pathname !== page) setIsFromLanding(false) - }, [ - history.location.pathname, - page, - setIsFromLanding, - setPage, - ]) + const [landingUrlFrom, setLandingUrlFrom] = useSessionStore({ + clearOnUnmount: true, + defaultValue: '', + key: 'landingUrlFrom', + validator: isString, + }) const getTemporaryToken = async () => { try { @@ -281,7 +278,11 @@ export const useAuth = () => { setUserInfo(userInfoFetched) - userInfoFetched.language.iso && changeLang(userInfoFetched.language.iso) + if (includes(window.location.pathname, PAGES.landing)) { + changeLang(navigator.language.substring(0, 2)) + } else { + userInfoFetched.language.iso && changeLang(userInfoFetched.language.iso) + } // eslint-disable-next-line no-empty } catch (error) {} @@ -295,11 +296,13 @@ export const useAuth = () => { fetchUserInfo, isFromLanding, isNewDeviceLogin, + landingUrlFrom, loadingUser, login, logout, page, setIsFromLanding, + setLandingUrlFrom, setPage, setSearch, setUserInfo, @@ -311,6 +314,7 @@ export const useAuth = () => { logout, user, userInfo, + landingUrlFrom, login, loadingUser, setSearch, @@ -318,6 +322,7 @@ export const useAuth = () => { setUserInfo, page, setIsFromLanding, + setLandingUrlFrom, isFromLanding, ]) diff --git a/src/features/TournamentLanding/TeamLogoImg/index.tsx b/src/features/Landings/TeamLogoImg/index.tsx similarity index 76% rename from src/features/TournamentLanding/TeamLogoImg/index.tsx rename to src/features/Landings/TeamLogoImg/index.tsx index 59af1775..862cdabe 100644 --- a/src/features/TournamentLanding/TeamLogoImg/index.tsx +++ b/src/features/Landings/TeamLogoImg/index.tsx @@ -24,14 +24,16 @@ type Props = { export const TeamLogoImg = ({ src, }: Props) => { - const [isLogoError, setIsImgError] = useState(false) + const [isLogoError, setIsLogoError] = useState(true) - const onError = () => setIsImgError(true) + const onError = () => setIsLogoError(true) + const onLoad = () => setIsLogoError(false) return ( ) diff --git a/src/features/TournamentLanding/helpers.tsx b/src/features/Landings/helpers.tsx similarity index 100% rename from src/features/TournamentLanding/helpers.tsx rename to src/features/Landings/helpers.tsx diff --git a/src/features/Landings/hooks.tsx b/src/features/Landings/hooks.tsx new file mode 100644 index 00000000..3bf3e02e --- /dev/null +++ b/src/features/Landings/hooks.tsx @@ -0,0 +1,163 @@ +import { + useEffect, + useState, +} from 'react' + +import size from 'lodash/size' +import includes from 'lodash/includes' + +import type { TournamentInfo } from 'requests/getTournamentInfo' +import type { Landing } from 'requests/getLanding' +import { getLanding } from 'requests/getLanding' +import { getLandingLogo } from 'requests/getLandingMedia' +import { getTournamentInfo } from 'requests/getTournamentInfo' + +import { PAGES } from 'config/pages' + +import { redirectToUrl } from 'helpers/redirectToUrl' + +import { useLexicsStore } from 'features/LexicsStore' +import { useAuthStore } from 'features/AuthStore' + +import { getLandingName, isPastLandingDate } from './helpers' +import { getName, useName } from '../Name' + +export const useLandings = () => { + const [tournamentInfo, setTournamentInfo] = useState(null) + const [isInactiveLanding, setIsInactiveLanding] = useState(false) + const [isNonExistLanding, setIsNonExistLanding] = useState(false) + const [nonExistLogoSrc, setNonExistLogoSrc] = useState('') + const [tournamentProfile, setTournamentProfile] = useState(null) + + const { addLexicsConfig, suffix } = useLexicsStore() + const { + landingUrlFrom, + setIsFromLanding, + user, + } = useAuthStore() + + const buttonLexic = tournamentInfo?.lexic_button || '' + const period = tournamentInfo?.lexic_period || '' + const title = tournamentInfo?.lexic_title || '' + const description = tournamentInfo?.lexic_description || '' + const gallery = tournamentInfo?.media.gallery + + useEffect(() => { + const lexics = [buttonLexic, period, title, description] + addLexicsConfig(lexics) + }, [ + addLexicsConfig, + buttonLexic, + description, + period, + title, + ]) + + const redirectToHomePage = () => redirectToUrl(PAGES.home) + const onButtonClick = () => { + if (includes(landingUrlFrom, PAGES.match) || includes(landingUrlFrom, PAGES.tournament)) { + setIsFromLanding(true) + redirectToUrl(landingUrlFrom) + sessionStorage.removeItem('landingUrlFrom') + } else { + redirectToUrl(tournamentInfo?.url_button || '') + } + } + + useEffect(() => { + (async () => { + const landingData = sessionStorage.getItem('landingData') + const parseLandingDate = landingData && JSON.parse(landingData) + + if (parseLandingDate && parseLandingDate.defaultLanding) { + setIsNonExistLanding(true) + getTournamentInfo(parseLandingDate.sportType, parseLandingDate.tournamentId) + .then(setTournamentProfile) + return getLandingLogo({ + sport_id: parseLandingDate.sportType, + tournament_id: parseLandingDate.tournamentId, + }) + .then(({ logo_url }) => setNonExistLogoSrc(logo_url || '/images/tournament-fallback.png')) + } + + try { + const data = landingUrlFrom + ? await getLanding({ + landingName: parseLandingDate.landing_id || parseLandingDate.url_landing, + seasonId: parseLandingDate.season_id, + sportId: parseLandingDate.sport_id, + tournamentId: parseLandingDate.tournament_id, + }) + : await getLanding({ landingName: getLandingName() }) + + if (user) return redirectToUrl(data.url_button || '') + if (isPastLandingDate(data.date_to)) setIsInactiveLanding(true) + return setTournamentInfo(data) + } catch (err) { + return redirectToHomePage() + } + })() + }, [landingUrlFrom, user]) + + const [sliderItemId, setSliderItemId] = useState(0) + + const onSliderSwitchClick = (itemId: number) => setSliderItemId(itemId) + + const imgCounter = size(gallery) + + useEffect(() => { + if (sliderItemId === imgCounter) { + setSliderItemId(0) + } + const getSliderInterval = setInterval(() => { + setSliderItemId(sliderItemId + 1) + }, 5000) + return () => clearInterval(getSliderInterval) + }, [imgCounter, sliderItemId]) + + const isInactiveLandingData = () => { + if (!tournamentInfo?.tournaments || !isInactiveLanding) return null + + const { + season, + tournament_eng, + tournament_rus, + } = tournamentInfo.tournaments[0] + + const currentTournamentsTitle = { + name_eng: tournament_eng, + name_rus: tournament_rus, + } + + const tournamentsTitle = getName({ nameObj: currentTournamentsTitle, suffix }) + + return { + season, + tournamentsTitle, + } + } + + const defaultTournamentName = useName(tournamentProfile || {}) + + return { + buttonColor: tournamentInfo?.button_color, + buttonLexic, + defaultTournamentName, + description, + gallery, + isInactiveLanding, + isInactiveLandingData: isInactiveLandingData(), + isNonExistLanding, + logo: tournamentInfo?.media.logo, + logoInsports: tournamentInfo?.logo_insports, + nonExistLogoSrc, + onButtonClick, + onSliderSwitchClick, + period, + redirectToHomePage, + sliderItemId, + teams: tournamentInfo?.teams, + title, + tournamentInfo, + } +} diff --git a/src/features/Landings/index.tsx b/src/features/Landings/index.tsx new file mode 100644 index 00000000..c2deea0c --- /dev/null +++ b/src/features/Landings/index.tsx @@ -0,0 +1,193 @@ +import { + BaseSyntheticEvent, + Fragment, + useCallback, +} from 'react' + +import format from 'date-fns/format' + +import map from 'lodash/map' + +import { isMobileDevice } from 'config/userAgent' + +import { T9n } from 'features/T9n' + +import { useLandings } from './hooks' +import { TeamLogoImg } from './TeamLogoImg' + +import { + Wrapper, + InsportsLogo, + HeaderWrapper, + Footer, + BlockWrapper, + TournamentInfo, + DateInfo, + InsportsImg, + TournamentMedia, + TournamentLogo, + TournamentTitle, + TournamentButton, + MainInfoContainer, + TournamentDescription, + TeamsLogo, + SliderContainer, + SliderWrapper, + MainLogoImg, + MainLogoWrapper, + SliderSwitch, + SliderSwitchItem, + SliderImg, + LogoBackground, + TournamentInfoContainer, +} from './styled' + +const Landings = () => { + const { + buttonColor, + buttonLexic, + defaultTournamentName, + description, + gallery, + isInactiveLanding, + isInactiveLandingData, + isNonExistLanding, + logo, + logoInsports, + nonExistLogoSrc, + onButtonClick, + onSliderSwitchClick, + period, + redirectToHomePage, + sliderItemId, + teams, + title, + tournamentInfo, + } = useLandings() + + const fallbackSrc = '/images/tournament-fallback.png' + const onError = useCallback((e: BaseSyntheticEvent) => { + // eslint-disable-next-line no-param-reassign + e.target.onError = '' + // eslint-disable-next-line no-param-reassign + e.target.src = fallbackSrc + }, [fallbackSrc]) + + if ((!tournamentInfo && !isNonExistLanding) + || (isNonExistLanding && !nonExistLogoSrc)) return null + + const currentYear = format(new Date(), 'Y') + + return ( + + + {isMobileDevice && } + + + + + { + gallery && !isInactiveLanding && !isNonExistLanding + ? ( + + + {map(gallery, (img, itemId) => ( + + ))} + + + {map(gallery, (img, itemId) => ( + onSliderSwitchClick(itemId)} + slideOpacity={itemId === sliderItemId} + key={img.id} + /> + ))} + + + ) + : ( + + + + + ) + } + + + {isInactiveLanding || isNonExistLanding + ? ( + + + {isInactiveLanding + ? + : }  + {isInactiveLandingData?.season} + + +   + {isInactiveLandingData?.tournamentsTitle || defaultTournamentName}  + + + +   + {isInactiveLandingData?.tournamentsTitle || defaultTournamentName}  + + + + ) + : ( + + + + + + + + + + + + )} + + + + + {(teams || ((logo || logoInsports) && !isInactiveLanding)) && ( + + {gallery && !isInactiveLanding && } + {teams && ( + + {map(teams, (item) => ( + + ))} + + )} + {(logoInsports && !isInactiveLanding) && } + + )} + + + +
©inSports.tv {currentYear}
+
+ ) +} + +export default Landings diff --git a/src/features/TournamentLanding/styled.tsx b/src/features/Landings/styled.tsx similarity index 88% rename from src/features/TournamentLanding/styled.tsx rename to src/features/Landings/styled.tsx index d67717db..f3e02e83 100644 --- a/src/features/TournamentLanding/styled.tsx +++ b/src/features/Landings/styled.tsx @@ -2,9 +2,8 @@ import styled, { css } from 'styled-components/macro' import { isMobileDevice } from 'config/userAgent' -import { ButtonSolid } from 'features/Common' +import { ButtonSolid, customScrollbar } from 'features/Common' import { Logo } from 'features/Logo' -import { T9n } from 'features/T9n' type ButtonProps = { buttonColor?: string, @@ -24,6 +23,10 @@ export const Wrapper = styled.div` color: white; display: flex; flex-direction: column; + overflow-y: scroll; + justify-content: ${(isMobileDevice ? '' : 'space-between')}; + + ${customScrollbar} ` export const HeaderWrapper = styled.div` @@ -56,12 +59,11 @@ export const InsportsLogo = styled(Logo)` ` export const MainInfoContainer = styled.div` - height: 100%; - ${isMobileDevice ? css` overflow: scroll; position: relative; + height: 87%; ` : ''}; ` @@ -101,6 +103,7 @@ export const MainLogoWrapper = styled.div` width: 50%; position: relative; align-items: center; + margin-right: 1%; ${isMobileDevice ? css` @@ -113,8 +116,8 @@ export const MainLogoWrapper = styled.div` ` export const MainLogoImg = styled.img` - width: 35%; - height: 35%; + width: 48%; + height: 48%; position: relative; ${isMobileDevice @@ -198,7 +201,7 @@ export const SliderSwitchItem = styled.div` height: 4px; border-radius: 2px; background-color: white; - opacity: ${({ slideOpacity }) => (slideOpacity ? '1' : '.3')};; + opacity: ${({ slideOpacity }) => (slideOpacity ? '1' : '.3')}; margin-right: 10px; cursor: pointer; transition: .7s; @@ -231,17 +234,17 @@ export const TournamentInfo = styled.div` display: flex; flex-direction: column; justify-content: center; - margin-top: ${(isMobileDevice ? 'none' : '90px')}; + margin-top: ${(isMobileDevice ? 'none' : '4.25rem')}; ` -export const DateInfo = styled(T9n)` +export const DateInfo = styled.div` text-transform: uppercase; background-color: rgba(0, 0, 0, 0.4); padding: 8px 25px; color: #B9B9B9; width: fit-content; border-radius: 5px; - font-size: 13px; + font-size: .62rem; font-weight: 600; ${isMobileDevice @@ -249,14 +252,14 @@ export const DateInfo = styled(T9n)` font-size: 10px; border-radius: 3px; background-color: rgba(0, 0, 0, 0.7); - padding: 5px 10px;` + padding: 3px 10px;` : ''}; ` -export const TournamentTitle = styled(T9n)` +export const TournamentTitle = styled.div` font-weight: 700; - font-size: 50px; - margin-top: 50px; + font-size: 2.36rem; + margin-top: 2.4rem; ${isMobileDevice ? css` @@ -271,11 +274,13 @@ export const TournamentTitle = styled(T9n)` export const TournamentButton = styled(ButtonSolid)` width: 320px; height: fit-content; - font-size: 24px; + font-size: 1.13rem;; font-weight: 600; border-radius: 5px; - margin-bottom: 90px; - padding: 20px 0; + margin-bottom: 4.25rem; + padding: 0.94rem 3rem; + display: flex; + justify-content: center; background-color: ${({ buttonColor }) => (buttonColor ? `${buttonColor}` : '#294FC3')}; ${isMobileDevice @@ -288,16 +293,17 @@ export const TournamentButton = styled(ButtonSolid)` : ''}; ` -export const TournamentDescription = styled(T9n)` - max-width: 400px; - margin: 50px 0; - font-size: 17px; +export const TournamentDescription = styled.div` + max-width: 26.6rem; + margin: 2.4rem 0; + font-size: 0.8rem; + letter-spacing: 0.1px; + line-height: 150%; ${isMobileDevice ? css` + max-width: 100%; font-size: 12px; - line-height: 150%; - letter-spacing: 0.1px; margin: 25px 0 30px; ` : ''}; @@ -307,7 +313,7 @@ export const TournamentMedia = styled.div` display: flex; align-items: center; height: 130px; - margin-bottom: 25px; + margin-bottom: 1.2rem; ${isMobileDevice ? css` diff --git a/src/features/MatchPage/store/hooks/index.tsx b/src/features/MatchPage/store/hooks/index.tsx index 6450a4b5..ec788b1f 100644 --- a/src/features/MatchPage/store/hooks/index.tsx +++ b/src/features/MatchPage/store/hooks/index.tsx @@ -3,6 +3,7 @@ import { useState, useMemo, } from 'react' +import { useHistory } from 'react-router' import includes from 'lodash/includes' import filter from 'lodash/filter' @@ -79,10 +80,13 @@ export const useMatchPage = () => { const { isFromLanding, + landingUrlFrom, setIsFromLanding, + setLandingUrlFrom, user, userInfo, } = useAuthStore() + const history = useHistory() const { close: hideProfileCard, @@ -138,14 +142,32 @@ export const useMatchPage = () => { })) useEffect(() => { - if (user || isFromLanding) return + if (user || isFromLanding || history.length > 1) return + setLandingUrlFrom(window.location.pathname) getLandingStatus({ matchId, sportType }) - .then(({ landing_id }) => { + .then((data) => { + sessionStorage.setItem( + 'landingData', + JSON.stringify({ ...data, defaultLanding: false }), + ) setIsFromLanding(false) - if (landing_id) redirectToUrl(`${PAGES.landing}/${landing_id}`) + if (data.landing_id) redirectToUrl(`${PAGES.landing}/${data.landing_id}`) }) + .catch(() => { + getMatchInfo(sportType, matchId).then((data) => { + sessionStorage.setItem('landingData', JSON.stringify({ + defaultLanding: true, + sportType, + tournamentId: data?.tournament.id, + })) + redirectToUrl(`${PAGES.landing}/default`) + }) + }) + // eslint-disable-next-line react-hooks/exhaustive-deps }, [ + setLandingUrlFrom, isFromLanding, + landingUrlFrom, matchId, setIsFromLanding, sportType, diff --git a/src/features/TournamentLanding/hooks.tsx b/src/features/TournamentLanding/hooks.tsx deleted file mode 100644 index 52d3d493..00000000 --- a/src/features/TournamentLanding/hooks.tsx +++ /dev/null @@ -1,96 +0,0 @@ -import { - useEffect, - useState, -} from 'react' - -import size from 'lodash/size' -import includes from 'lodash/includes' - -import type { TournamentLanding } from 'requests/getTournamentLanding' -import { getTournamentLanding } from 'requests/getTournamentLanding' - -import { PAGES } from 'config/pages' - -import { redirectToUrl } from 'helpers/redirectToUrl' - -import { useLexicsStore } from 'features/LexicsStore' -import { useAuthStore } from 'features/AuthStore' - -import { getLandingName, isPastLandingDate } from './helpers' - -export const useTournamentLanding = () => { - const [tournamentInfo, setTournamentInfo] = useState(null) - - const { addLexicsConfig } = useLexicsStore() - const { page, setIsFromLanding } = useAuthStore() - - const buttonLexic = tournamentInfo?.lexic_button || '' - const period = tournamentInfo?.lexic_period || '' - const title = tournamentInfo?.lexic_title || '' - const description = tournamentInfo?.lexic_description || '' - const gallery = tournamentInfo?.media.gallery - - useEffect(() => { - const lexics = [buttonLexic, period, title, description] - addLexicsConfig(lexics) - }, [ - addLexicsConfig, - buttonLexic, - description, - period, - title, - ]) - - const redirectToHomePage = () => redirectToUrl(PAGES.home) - const onButtonClick = () => { - if (includes(page, 'matches')) { - setIsFromLanding(true) - redirectToUrl(page) - } else { - redirectToUrl(tournamentInfo?.url_button || '') - } - } - - useEffect(() => { - getTournamentLanding(getLandingName()) - .then((data) => ( - isPastLandingDate(data.date_to) - ? redirectToHomePage() - : setTournamentInfo(data) - )) - .catch(redirectToHomePage) - }, []) - - const [sliderItemId, setSliderItemId] = useState(0) - - const onSliderSwitchClick = (itemId: number) => setSliderItemId(itemId) - - const imgCounter = size(gallery) - - useEffect(() => { - if (sliderItemId === imgCounter) { - setSliderItemId(0) - } - const getSliderInterval = setInterval(() => { - setSliderItemId(sliderItemId + 1) - }, 5000) - return () => clearInterval(getSliderInterval) - }, [imgCounter, sliderItemId]) - - return { - buttonColor: tournamentInfo?.button_color, - buttonLexic, - description, - gallery, - logo: tournamentInfo?.media.logo, - logoInsports: tournamentInfo?.logo_insports, - onButtonClick, - onSliderSwitchClick, - period, - redirectToHomePage, - sliderItemId, - teams: tournamentInfo?.teams, - title, - tournamentInfo, - } -} diff --git a/src/features/TournamentLanding/index.tsx b/src/features/TournamentLanding/index.tsx deleted file mode 100644 index 16f57b5d..00000000 --- a/src/features/TournamentLanding/index.tsx +++ /dev/null @@ -1,134 +0,0 @@ -import format from 'date-fns/format' - -import map from 'lodash/map' - -import { isMobileDevice } from 'config/userAgent' - -import { T9n } from 'features/T9n' - -import { useTournamentLanding } from './hooks' -import { TeamLogoImg } from './TeamLogoImg' - -import { - Wrapper, - InsportsLogo, - HeaderWrapper, - Footer, - BlockWrapper, - TournamentInfo, - DateInfo, - InsportsImg, - TournamentMedia, - TournamentLogo, - TournamentTitle, - TournamentButton, - MainInfoContainer, - TournamentDescription, - TeamsLogo, - SliderContainer, - SliderWrapper, - MainLogoImg, - MainLogoWrapper, - SliderSwitch, - SliderSwitchItem, - SliderImg, - LogoBackground, - TournamentInfoContainer, -} from './styled' - -const TournamentLanding = () => { - const { - buttonColor, - buttonLexic, - description, - gallery, - logo, - logoInsports, - onButtonClick, - onSliderSwitchClick, - period, - redirectToHomePage, - sliderItemId, - teams, - title, - tournamentInfo, - } = useTournamentLanding() - - if (!tournamentInfo) return null - - const currentYear = format(new Date(), 'Y') - - return ( - - - {isMobileDevice && } - - - - - { - gallery - ? ( - - - {map(gallery, (img, itemId) => ( - - ))} - - - {map(gallery, (img, itemId) => ( - onSliderSwitchClick(itemId)} - slideOpacity={itemId === sliderItemId} - key={img.id} - /> - ))} - - - ) - : ( - - - - - ) - } - - - - - - - - - - - {gallery && } - {teams && ( - - {map(teams, (item) => ( - - ))} - - )} - {logoInsports && } - - - - -
©inSports.tv {currentYear}
-
- ) -} - -export default TournamentLanding diff --git a/src/features/TournamentPage/hooks.tsx b/src/features/TournamentPage/hooks.tsx index dcce2e99..c7986e23 100644 --- a/src/features/TournamentPage/hooks.tsx +++ b/src/features/TournamentPage/hooks.tsx @@ -11,13 +11,18 @@ import { getTournamentMatches, } from 'requests' +import { openSubscribePopup, redirectToUrl } from 'helpers' + +import { PAGES } from 'config/pages' + +import { useName } from 'features/Name' + import { checkUrlParams } from 'helpers/parseUrlParams/parseUrlParams' import { usePageParams } from 'hooks/usePageParams' -import { openSubscribePopup } from 'helpers' -import { useName } from 'features/Name' import { isPermittedTournament } from '../../helpers/isPermittedTournament' +import { getLandingStatus } from '../../requests/getLandingStatus' import { useProfileCard } from '../ProfileCard/hooks' import { useBuyMatchPopupStore } from '../BuyMatchPopup' import { MATCH_CONFIG } from '../BuyMatchPopup/store/hooks/useSubscriptions' @@ -30,7 +35,12 @@ export const useTournamentPage = () => { const country = useName(tournamentProfile?.country || {}) const history = useHistory() - const { user } = useAuthStore() + const { + isFromLanding, + setIsFromLanding, + setLandingUrlFrom, + user, + } = useAuthStore() const { isFavorite, toggleFavorites } = useProfileCard() @@ -49,6 +59,36 @@ export const useTournamentPage = () => { ], ) + useEffect(() => { + if (user || isFromLanding || history.length > 1) return + setLandingUrlFrom(window.location.pathname) + getLandingStatus({ sportType, tournamentId }) + .then((data) => { + sessionStorage.setItem( + 'landingData', + JSON.stringify({ ...data, defaultLanding: false }), + ) + setIsFromLanding(false) + if (data.landing_id) redirectToUrl(`${PAGES.landing}/${data.landing_id}`) + }) + .catch(() => { + sessionStorage.setItem('landingData', JSON.stringify({ + defaultLanding: true, + sportType, + tournamentId, + })) + redirectToUrl(`${PAGES.landing}/default`) + }) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [ + setLandingUrlFrom, + isFromLanding, + tournamentId, + setIsFromLanding, + sportType, + user, + ]) + useEffect(() => { !isFavorite && checkUrlParams('from') === 'landing' diff --git a/src/requests/getTournamentLanding.tsx b/src/requests/getLanding.tsx similarity index 64% rename from src/requests/getTournamentLanding.tsx rename to src/requests/getLanding.tsx index 905f0513..6947aa1d 100644 --- a/src/requests/getTournamentLanding.tsx +++ b/src/requests/getLanding.tsx @@ -1,3 +1,5 @@ +import isUndefined from 'lodash/isUndefined' + import { API_ROOT } from 'config' import { callApi } from 'helpers' @@ -25,7 +27,7 @@ type Gallery = { url: string, } -export type TournamentLanding = { +export type Landing = { button_color?: string, date_from: string, date_to: string, @@ -42,19 +44,31 @@ export type TournamentLanding = { }, name: string, teams: Array, - tournaments: Array, + tournaments: Array | null, url_button?: string, } -export const getTournamentLanding = async ( +type Args = { landingName: number | string, -): Promise => { + seasonId?: number, + sportId?: number, + tournamentId?: number, +} + +export const getLanding = async ({ + landingName, + seasonId, + sportId, + tournamentId, +}: Args): Promise => { const config = { method: 'GET', } return callApi({ config, - url: `${API_ROOT}/v1/landings/${landingName}`, + url: `${API_ROOT}/v1/landings/${landingName}${isUndefined(seasonId) + ? '' + : `?season_id=${seasonId}&sport_id=${sportId}&tournament_id=${tournamentId}`}`, }) } diff --git a/src/requests/getLandingMedia.tsx b/src/requests/getLandingMedia.tsx new file mode 100644 index 00000000..75f7b0a2 --- /dev/null +++ b/src/requests/getLandingMedia.tsx @@ -0,0 +1,25 @@ +import { API_ROOT } from 'config' +import { callApi } from 'helpers' + +export type LandingMedia = { + logo_url: string, +} + +type Args = { + sport_id: number, + tournament_id?: number, +} + +export const getLandingLogo = async ({ + sport_id, + tournament_id, +}: Args): Promise => { + const config = { + method: 'GET', + } + + return callApi({ + config, + url: `${API_ROOT}/v1/tournaments/${sport_id}/${tournament_id}/media`, + }) +} diff --git a/src/requests/getLandingStatus.tsx b/src/requests/getLandingStatus.tsx index d4ef5879..80e6d564 100644 --- a/src/requests/getLandingStatus.tsx +++ b/src/requests/getLandingStatus.tsx @@ -1,21 +1,35 @@ +import isUndefined from 'lodash/isUndefined' + import { API_ROOT } from 'config' import { callApi } from 'helpers' type Args = { - matchId: number, + matchId?: number, sportType: number, + tournamentId?: number, +} + +type LandingStatus = { + landing_id: number, + season_id: number, + sport_id: number, + tournament_id: number, + url_landing: string, } export const getLandingStatus = async ({ matchId, sportType, -}: Args): Promise<{landing_id: number | null}> => { + tournamentId, +}: Args): Promise => { const config = { method: 'GET', } return callApi({ config, - url: `${API_ROOT}/v1/landings/${sportType}/${matchId}/status`, + url: `${API_ROOT}/v1/landings/status/${sportType}?${ + isUndefined(matchId) ? '' : `match_id=${matchId}`}${ + isUndefined(tournamentId) ? '' : `tournament_id=${tournamentId}`}`, }) } diff --git a/src/requests/index.tsx b/src/requests/index.tsx index 494e9a3a..c9d79f20 100644 --- a/src/requests/index.tsx +++ b/src/requests/index.tsx @@ -8,7 +8,7 @@ export * from './getUserSportFavs' export * from './modifyUserSportFavs' export * from './getSportTournaments' export * from './getTournamentInfo' -export * from './getTournamentLanding' +export * from './getLanding' export * from './getTeamInfo' export * from './getUserInfo' export * from './getMatchInfo' -- 2.30.2 From c0a594d7c895b9985d4071c20aff68e40a4121e3 Mon Sep 17 00:00:00 2001 From: Margarita Date: Wed, 12 Apr 2023 15:35:11 +0400 Subject: [PATCH 2/2] feat(in-454): pr fix --- src/features/Landings/hooks.tsx | 4 ++-- src/features/Landings/index.tsx | 16 +++------------- src/features/Landings/styled.tsx | 8 ++++++-- src/features/MatchPage/store/hooks/index.tsx | 4 ++-- src/features/TournamentPage/hooks.tsx | 2 +- 5 files changed, 14 insertions(+), 20 deletions(-) diff --git a/src/features/Landings/hooks.tsx b/src/features/Landings/hooks.tsx index 3bf3e02e..3683c5a6 100644 --- a/src/features/Landings/hooks.tsx +++ b/src/features/Landings/hooks.tsx @@ -6,14 +6,14 @@ import { import size from 'lodash/size' import includes from 'lodash/includes' +import { PAGES } from 'config' + import type { TournamentInfo } from 'requests/getTournamentInfo' import type { Landing } from 'requests/getLanding' import { getLanding } from 'requests/getLanding' import { getLandingLogo } from 'requests/getLandingMedia' import { getTournamentInfo } from 'requests/getTournamentInfo' -import { PAGES } from 'config/pages' - import { redirectToUrl } from 'helpers/redirectToUrl' import { useLexicsStore } from 'features/LexicsStore' diff --git a/src/features/Landings/index.tsx b/src/features/Landings/index.tsx index c2deea0c..03150bde 100644 --- a/src/features/Landings/index.tsx +++ b/src/features/Landings/index.tsx @@ -1,14 +1,10 @@ -import { - BaseSyntheticEvent, - Fragment, - useCallback, -} from 'react' +import { Fragment } from 'react' import format from 'date-fns/format' import map from 'lodash/map' -import { isMobileDevice } from 'config/userAgent' +import { isMobileDevice } from 'config' import { T9n } from 'features/T9n' @@ -66,12 +62,6 @@ const Landings = () => { } = useLandings() const fallbackSrc = '/images/tournament-fallback.png' - const onError = useCallback((e: BaseSyntheticEvent) => { - // eslint-disable-next-line no-param-reassign - e.target.onError = '' - // eslint-disable-next-line no-param-reassign - e.target.src = fallbackSrc - }, [fallbackSrc]) if ((!tournamentInfo && !isNonExistLanding) || (isNonExistLanding && !nonExistLogoSrc)) return null @@ -115,7 +105,7 @@ const Landings = () => { ) diff --git a/src/features/Landings/styled.tsx b/src/features/Landings/styled.tsx index f3e02e83..9cee03a1 100644 --- a/src/features/Landings/styled.tsx +++ b/src/features/Landings/styled.tsx @@ -2,7 +2,11 @@ import styled, { css } from 'styled-components/macro' import { isMobileDevice } from 'config/userAgent' -import { ButtonSolid, customScrollbar } from 'features/Common' +import { + ButtonSolid, + customScrollbar, + Image, +} from 'features/Common' import { Logo } from 'features/Logo' type ButtonProps = { @@ -115,7 +119,7 @@ export const MainLogoWrapper = styled.div` : ''}; ` -export const MainLogoImg = styled.img` +export const MainLogoImg = styled(Image)` width: 48%; height: 48%; position: relative; diff --git a/src/features/MatchPage/store/hooks/index.tsx b/src/features/MatchPage/store/hooks/index.tsx index ec788b1f..d4438600 100644 --- a/src/features/MatchPage/store/hooks/index.tsx +++ b/src/features/MatchPage/store/hooks/index.tsx @@ -9,14 +9,14 @@ import includes from 'lodash/includes' import filter from 'lodash/filter' import isEmpty from 'lodash/isEmpty' +import { PAGES } from 'config' + import { useAuthStore } from 'features/AuthStore' import { Tabs } from 'features/MatchSidePlaylists/config' import { initialCircleAnimation } from 'features/CircleAnimationBar' import type { TCircleAnimation } from 'features/CircleAnimationBar' import { StatsType } from 'features/MatchSidePlaylists/components/TabStats/config' -import { PAGES } from 'config/pages' - import type { MatchInfo } from 'requests/getMatchInfo' import { getMatchInfo } from 'requests/getMatchInfo' import { getViewMatchDuration } from 'requests/getViewMatchDuration' diff --git a/src/features/TournamentPage/hooks.tsx b/src/features/TournamentPage/hooks.tsx index c7986e23..2e93603f 100644 --- a/src/features/TournamentPage/hooks.tsx +++ b/src/features/TournamentPage/hooks.tsx @@ -13,7 +13,7 @@ import { import { openSubscribePopup, redirectToUrl } from 'helpers' -import { PAGES } from 'config/pages' +import { PAGES } from 'config' import { useName } from 'features/Name' -- 2.30.2