From ee838f0e224d55913576a6ec474dd1b71b1da7dd Mon Sep 17 00:00:00 2001 From: Mirlan Date: Thu, 30 Jul 2020 17:18:44 +0600 Subject: [PATCH] Ott 253 login error message (#66) --- src/config/colors.tsx | 5 - src/config/index.tsx | 3 +- src/config/profileTypes.tsx | 11 ++ src/config/routes.tsx | 60 -------- src/config/sportTypes.tsx | 11 ++ src/features/Common/Input/styled.tsx | 12 +- .../components/TournamentFilter/helpers.tsx | 30 ++-- .../components/TournamentList/index.tsx | 13 +- .../HeaderFilters/store/hooks/index.tsx | 9 +- src/features/HomePage/index.tsx | 4 +- src/features/ItemsList/index.tsx | 13 +- src/features/Login/index.tsx | 3 +- src/features/Search/config/index.tsx | 8 -- .../Search/hooks/useNormalizedItems.tsx | 71 ++++++---- .../TooltipBlock/index.tsx | 18 ++- .../TooltipBlock/styled.tsx | 6 +- src/features/UserFavorites/helpers.tsx | 41 ++++++ src/features/UserFavorites/hooks/index.tsx | 36 +++++ src/features/UserFavorites/index.tsx | 61 ++++++++ .../styled.tsx | 0 .../UserSportFav/TooltipBlock/hooks/index.tsx | 27 ---- src/features/UserSportFav/hooks/index.tsx | 132 ------------------ src/features/UserSportFav/index.tsx | 68 --------- src/helpers/getLogo/__tests__/index.tsx | 23 --- src/helpers/getLogo/index.tsx | 23 --- src/helpers/getProfileFallbackLogo/index.tsx | 33 +++++ .../getProfileLogo/__tests__/index.tsx | 25 ++++ src/helpers/getProfileLogo/index.tsx | 27 ++++ src/helpers/getProfileUrl/index.tsx | 20 +++ src/helpers/getSportColor/index.tsx | 9 ++ src/helpers/getSportLexic/index.tsx | 9 ++ src/helpers/handleImg/index.tsx | 32 ++--- src/helpers/index.tsx | 6 +- src/requests/getMatches.tsx | 8 +- src/requests/getSearchItems.tsx | 14 +- src/requests/getSportTournaments.tsx | 7 +- src/requests/getUserSportFavs.tsx | 70 +++++----- src/requests/modifyUserSportFavs.tsx | 28 ++-- 38 files changed, 481 insertions(+), 495 deletions(-) delete mode 100644 src/config/colors.tsx create mode 100644 src/config/profileTypes.tsx create mode 100644 src/config/sportTypes.tsx rename src/features/{UserSportFav => UserFavorites}/TooltipBlock/index.tsx (78%) rename src/features/{UserSportFav => UserFavorites}/TooltipBlock/styled.tsx (92%) create mode 100644 src/features/UserFavorites/helpers.tsx create mode 100644 src/features/UserFavorites/hooks/index.tsx create mode 100644 src/features/UserFavorites/index.tsx rename src/features/{UserSportFav => UserFavorites}/styled.tsx (100%) delete mode 100644 src/features/UserSportFav/TooltipBlock/hooks/index.tsx delete mode 100644 src/features/UserSportFav/hooks/index.tsx delete mode 100644 src/features/UserSportFav/index.tsx delete mode 100644 src/helpers/getLogo/__tests__/index.tsx delete mode 100644 src/helpers/getLogo/index.tsx create mode 100644 src/helpers/getProfileFallbackLogo/index.tsx create mode 100644 src/helpers/getProfileLogo/__tests__/index.tsx create mode 100644 src/helpers/getProfileLogo/index.tsx create mode 100644 src/helpers/getProfileUrl/index.tsx create mode 100644 src/helpers/getSportColor/index.tsx create mode 100644 src/helpers/getSportLexic/index.tsx diff --git a/src/config/colors.tsx b/src/config/colors.tsx deleted file mode 100644 index ef4a7dd8..00000000 --- a/src/config/colors.tsx +++ /dev/null @@ -1,5 +0,0 @@ -export const SPORT_COLORS = { - basketball: '#f1903b', - football: '#00a435', - hockey: '#5eb1ff', -} diff --git a/src/config/index.tsx b/src/config/index.tsx index 371ac95d..4f34c197 100644 --- a/src/config/index.tsx +++ b/src/config/index.tsx @@ -2,4 +2,5 @@ export * from './routes' export * from './pages' export * from './authKeys' export * from './procedures' -export * from './colors' +export * from './sportTypes' +export * from './profileTypes' diff --git a/src/config/profileTypes.tsx b/src/config/profileTypes.tsx new file mode 100644 index 00000000..1c6c1cd9 --- /dev/null +++ b/src/config/profileTypes.tsx @@ -0,0 +1,11 @@ +export enum ProfileTypes { + TOURNAMENTS = 1, + TEAMS = 2, + PLAYERS = 3, +} + +export const PROFILE_NAMES = { + [ProfileTypes.TOURNAMENTS]: 'tournaments', + [ProfileTypes.TEAMS]: 'teams', + [ProfileTypes.PLAYERS]: 'players', +} as const diff --git a/src/config/routes.tsx b/src/config/routes.tsx index 712d2eaf..c953de0c 100644 --- a/src/config/routes.tsx +++ b/src/config/routes.tsx @@ -1,62 +1,2 @@ export const API_ROOT = 'https://api-staging.instat.tv' export const DATA_URL = `${API_ROOT}/data` - -export const LOGOS_FALLBACKS = { - basketball: { - players: 'https://basketball.instatscout.com/images/player-no-photo.png', - teams: 'https://basketball.instatscout.com/images/team-no-photo.png', - tournaments: 'https://basketball.instatscout.com/images/tournaments/180/no-photo.png', - }, - - football: { - players: 'https://football.instatscout.com/images/player-no-photo.png', - teams: 'https://football.instatscout.com/images/team-no-photo.png', - tournaments: 'https://football.instatscout.com/images/tournament-no-photo.png', - }, - - hockey: { - players: 'https://hockey.instatscout.com/images/player-no-photo.png', - teams: 'https://hockey.instatscout.com/images/team-no-photo.png', - tournaments: 'https://hockey.instatscout.com/images/tournaments/180/no-photo.png', - }, -} as const - -export const LOGOS_URLS = { - basketball: { - players: 'https://basketball.instatscout.com/images/players/180', - teams: 'https://basketball.instatscout.com/images/teams/180', - tournaments: 'https://basketball.instatscout.com/images/tournaments/180', - }, - - football: { - players: 'https://instatscout.com/images/players/180', - teams: 'https://instatscout.com/images/teams/180', - tournaments: 'https://instatscout.com/images/tournaments/180', - }, - - hockey: { - players: 'https://hockey.instatscout.com/images/players/180', - teams: 'https://hockey.instatscout.com/images/teams/180', - tournaments: 'https://hockey.instatscout.com/images/tournaments/180', - }, -} as const - -export const FAV_SPORT_URLS = { - basketball: { - players: '/basketball/players', - teams: '/basketball/teams', - tournaments: '/basketball/tournaments', - }, - - football: { - players: '/football/players', - teams: '/football/teams', - tournaments: '/football/tournaments', - }, - - hockey: { - players: '/hockey/players', - teams: '/hockey/teams', - tournaments: '/hockey/tournaments', - }, -} as const diff --git a/src/config/sportTypes.tsx b/src/config/sportTypes.tsx new file mode 100644 index 00000000..1eaedd7c --- /dev/null +++ b/src/config/sportTypes.tsx @@ -0,0 +1,11 @@ +export enum SportTypes { + FOOTBALL = 1, + HOCKEY = 2, + BASKETBALL = 3, +} + +export const SPORT_NAMES = { + [SportTypes.BASKETBALL]: 'basketball', + [SportTypes.FOOTBALL]: 'football', + [SportTypes.HOCKEY]: 'hockey', +} diff --git a/src/features/Common/Input/styled.tsx b/src/features/Common/Input/styled.tsx index 2f76daea..f689f7d2 100644 --- a/src/features/Common/Input/styled.tsx +++ b/src/features/Common/Input/styled.tsx @@ -90,7 +90,11 @@ export const Column = styled.div` flex-direction: column; ` -export const Error = styled(T9n)` +type ErrorProps = { + marginBottom?: number, +} + +export const Error = styled(T9n)` min-height: 16px; margin-top: 5px; font-style: normal; @@ -99,4 +103,10 @@ export const Error = styled(T9n)` line-height: 16px; letter-spacing: -0.078px; color: #E64646; + + ${({ marginBottom }) => ( + marginBottom + ? `margin-bottom: ${marginBottom}px` + : '' + )} ` diff --git a/src/features/HeaderFilters/components/TournamentFilter/helpers.tsx b/src/features/HeaderFilters/components/TournamentFilter/helpers.tsx index 8ac0b699..fe3e6802 100644 --- a/src/features/HeaderFilters/components/TournamentFilter/helpers.tsx +++ b/src/features/HeaderFilters/components/TournamentFilter/helpers.tsx @@ -1,35 +1,47 @@ import map from 'lodash/map' -import type { Tournaments } from 'requests' +import { Tournaments } from 'requests' -import { LOGOS_FALLBACKS } from 'config' -import { getLogo, SPORT_TYPES } from 'helpers' +import { ProfileTypes } from 'config' +import { + getProfileLogo, + getSportColor, + getSportLexic, + getProfileFallbackLogo, +} from 'helpers' type Name = 'name_rus' | 'name_eng' type ShortName = 'short_name_rus' | 'short_name_eng' export const normalizeTournaments = (tournaments: Tournaments, suffix: string) => ( map(tournaments, (tournament) => { - const { c_sport, id } = tournament - const sportType = SPORT_TYPES[c_sport] + const profileType = ProfileTypes.TOURNAMENTS + const { c_sport: sportType, id } = tournament + const color = getSportColor(sportType) + const sportLexic = getSportLexic(sportType) const name = tournament[`name_${suffix}` as Name] const shortName = tournament[`short_name_${suffix}` as ShortName] || name const country = tournament.country?.[`name_${suffix}` as Name] - const logo = getLogo({ + const logo = getProfileLogo({ id, + profileType, + sportType, + }) + const fallbackImage = getProfileFallbackLogo({ + profileType, sportType, - type: 'tournaments', }) return { + color, country, - fallbackImage: LOGOS_FALLBACKS[sportType].tournaments, + fallbackImage, id, logo, name, shortName, - sportType, + sportLexic, } }) ) diff --git a/src/features/HeaderFilters/components/TournamentList/index.tsx b/src/features/HeaderFilters/components/TournamentList/index.tsx index 0e31c466..79b3a8b4 100644 --- a/src/features/HeaderFilters/components/TournamentList/index.tsx +++ b/src/features/HeaderFilters/components/TournamentList/index.tsx @@ -2,9 +2,6 @@ import React from 'react' import map from 'lodash/map' -import { SPORT_COLORS } from 'config' -import type { SportType } from 'features/Search/config' - import { useItemsList } from 'features/ItemsList/hooks' import { Logo, @@ -19,12 +16,13 @@ import { import { ListItem } from './styled' type Tournament = { + color: string, country?: string, fallbackImage: string, id: number, logo: string, name: string, - sportType: SportType, + sportLexic: string, } type TournamentListProps = { @@ -41,12 +39,13 @@ export const TournamentList = ({ onSelect, tournaments }: TournamentListProps) = return ( {map(tournaments, ({ + color, country, fallbackImage, id, logo, name, - sportType, + sportLexic, }) => ( onSelect(id)}> @@ -59,8 +58,8 @@ export const TournamentList = ({ onSelect, tournaments }: TournamentListProps) = {name} {country} diff --git a/src/features/HeaderFilters/store/hooks/index.tsx b/src/features/HeaderFilters/store/hooks/index.tsx index 013f8f13..494f4367 100644 --- a/src/features/HeaderFilters/store/hooks/index.tsx +++ b/src/features/HeaderFilters/store/hooks/index.tsx @@ -9,6 +9,7 @@ import debounce from 'lodash/debounce' import format from 'date-fns/format' import startOfDay from 'date-fns/startOfDay' +import { SportTypes } from 'config' import { getMatches } from 'requests' export enum MatchStatuses { @@ -17,18 +18,12 @@ export enum MatchStatuses { Soon = 3, } -export enum SportTypes { - Football = 1, - Basketball = 3, - Hockey = 2, -} - const dateFormat = 'dd/MM/yyyy HH:mm:ss' export const useFilters = () => { const [selectedDate, setSelectedDate] = useState(new Date()) const [selectedMatchStatus, setSelectedMatchStatus] = useState(MatchStatuses.Live) - const [selectedSportType, setSelectedSportTypes] = useState(SportTypes.Football) + const [selectedSportType, setSelectedSportTypes] = useState(SportTypes.FOOTBALL) const [selectedTournamentId, setSelectedTournamentId] = useState(null) const fetchMatches = useCallback(debounce(getMatches, 300), []) diff --git a/src/features/HomePage/index.tsx b/src/features/HomePage/index.tsx index 51746c8e..c04e4986 100644 --- a/src/features/HomePage/index.tsx +++ b/src/features/HomePage/index.tsx @@ -10,7 +10,7 @@ import { TournamentFilter, HeaderFiltersStore, } from 'features/HeaderFilters' -import { UserSportFav } from 'features/UserSportFav' +import { UserFavorites } from 'features/UserFavorites' import { FilterWrapper, @@ -19,7 +19,7 @@ import { export const HomePage = () => ( - +
diff --git a/src/features/ItemsList/index.tsx b/src/features/ItemsList/index.tsx index 27913aa4..a79dc75a 100644 --- a/src/features/ItemsList/index.tsx +++ b/src/features/ItemsList/index.tsx @@ -2,9 +2,6 @@ import React from 'react' import map from 'lodash/map' -import { SPORT_COLORS } from 'config' -import type { SportType } from 'features/Search/config' - import { useItemsList } from './hooks' import { Logo, @@ -20,12 +17,13 @@ import { type SearchItemsListProps = { list: Array<{ + color: string, fallbackImage: string, id: number, logo: string, name: string, profileUrl: string, - sportType: SportType, + sportLexic: string, teamOrCountry?: string, }>, } @@ -39,12 +37,13 @@ export const ItemsList = ({ list }: SearchItemsListProps) => { return ( {map(list, ({ + color, fallbackImage, id, logo, name, profileUrl, - sportType, + sportLexic, teamOrCountry, }) => ( @@ -59,8 +58,8 @@ export const ItemsList = ({ list }: SearchItemsListProps) => { {name} {teamOrCountry} diff --git a/src/features/Login/index.tsx b/src/features/Login/index.tsx index 8c1a4d39..9a49d87e 100644 --- a/src/features/Login/index.tsx +++ b/src/features/Login/index.tsx @@ -39,8 +39,6 @@ const LoginForm = () => { - {requestError && } - { /> + diff --git a/src/features/Search/config/index.tsx b/src/features/Search/config/index.tsx index 782336ae..cb6ca2d5 100644 --- a/src/features/Search/config/index.tsx +++ b/src/features/Search/config/index.tsx @@ -1,11 +1,3 @@ export const SEARCH_DELAY = 1500 // Задержка поиска в мс export const MIN_CHARACTERS_LENGTH = 3 // Минимальное число символов для поиска - -export type SportType = 'football' | 'basketball' | 'hockey' - -export const SPORT_TYPES = { - 1: 'football', - 2: 'hockey', - 3: 'basketball', -} as const diff --git a/src/features/Search/hooks/useNormalizedItems.tsx b/src/features/Search/hooks/useNormalizedItems.tsx index 313db36f..32a296ff 100644 --- a/src/features/Search/hooks/useNormalizedItems.tsx +++ b/src/features/Search/hooks/useNormalizedItems.tsx @@ -1,12 +1,15 @@ import map from 'lodash/map' -import type { SearchItems } from 'requests' -import { LOGOS_FALLBACKS } from 'config' -import { getLogo } from 'helpers' +import { SearchItems } from 'requests' +import { ProfileTypes } from 'config' +import { + getProfileLogo, + getSportColor, + getSportLexic, + getProfileFallbackLogo, +} from 'helpers' import { useLexicsStore } from 'features/LexicsStore' -import { SPORT_TYPES } from '../config' - type Firstname = 'firstname_eng' | 'firstname_rus' type Lastname = 'lastname_eng' | 'lastname_rus' type Name = 'name_eng' | 'name_rus' @@ -17,81 +20,95 @@ export const useNormalizedItems = (searchItems: SearchItems) => { } = useLexicsStore() const players = map(searchItems.players, (player) => { - const type = 'players' + const { id, sport: sportType } = player + const profileType = ProfileTypes.PLAYERS const firstName = player[`firstname_${suffix}` as Firstname] const lastName = player[`lastname_${suffix}` as Lastname] const teamName = player.team?.[`name_${suffix}` as Name] - const sportType = SPORT_TYPES[player.sport] - - const { id } = player + const sportLexic = getSportLexic(sportType) - const logo = getLogo({ + const logo = getProfileLogo({ id, + profileType, + sportType, + }) + const fallbackImage = getProfileFallbackLogo({ + profileType, sportType, - type, }) return { - fallbackImage: LOGOS_FALLBACKS[sportType].players, + color: getSportColor(sportType), + fallbackImage, id, logo, name: `${firstName} ${lastName}`, profileUrl: `/players/${id}`, - sportType, + sportLexic, teamOrCountry: teamName, } }) const teams = map(searchItems.teams, (team) => { + const { id, sport: sportType } = team + const profileType = ProfileTypes.TEAMS const name = team[`name_${suffix}` as Name] - const sportType = SPORT_TYPES[team.sport] - - const { id } = team + const sportLexic = getSportLexic(sportType) - const logo = getLogo({ + const logo = getProfileLogo({ id, + profileType, + sportType, + }) + const fallbackImage = getProfileFallbackLogo({ + profileType, sportType, - type: 'teams', }) const country = team.country?.[`name_${suffix}` as Name] return { - fallbackImage: LOGOS_FALLBACKS[sportType].teams, + color: getSportColor(sportType), + fallbackImage, id, logo, name, profileUrl: `/teams/${id}`, - sportType, + sportLexic, teamOrCountry: country, } }) const tournaments = map(searchItems.tournaments, (tournament) => { + const profileType = ProfileTypes.TOURNAMENTS + const { id, sport: sportType } = tournament const name = tournament[`name_${suffix}` as Name] - const sportType = SPORT_TYPES[tournament.sport] - - const { id } = tournament + const sportLexic = getSportLexic(sportType) - const logo = getLogo({ + const logo = getProfileLogo({ id, + profileType, + sportType, + }) + const fallbackImage = getProfileFallbackLogo({ + profileType, sportType, - type: 'tournaments', }) const country = tournament.country?.[`name_${suffix}` as Name] return { - fallbackImage: LOGOS_FALLBACKS[sportType].tournaments, + color: getSportColor(sportType), + fallbackImage, id, logo, name, profileUrl: `/tournaments/${id}`, - sportType, + sportLexic, teamOrCountry: country, } }) diff --git a/src/features/UserSportFav/TooltipBlock/index.tsx b/src/features/UserFavorites/TooltipBlock/index.tsx similarity index 78% rename from src/features/UserSportFav/TooltipBlock/index.tsx rename to src/features/UserFavorites/TooltipBlock/index.tsx index 5c031eb6..abba1146 100644 --- a/src/features/UserSportFav/TooltipBlock/index.tsx +++ b/src/features/UserFavorites/TooltipBlock/index.tsx @@ -1,9 +1,9 @@ import React from 'react' -import { - getSportName, - getSportColor, -} from './hooks' +import { SportTypes } from 'config' +import { getSportColor, getSportLexic } from 'helpers' +import { T9n } from 'features/T9n' + import { TooltipBlockWrapper, TooltipBlockItem, @@ -11,14 +11,13 @@ import { TooltipBlockItemThin, } from './styled' -type TTooltipBlock = { +type TooltipBlockProps = { countryName?: string, date?: string, playerFirstName?: string, playerLastName?: string, playerTeamName?: string, - sport: number, - suffix: string, + sport: SportTypes, teamName?: string, } @@ -28,9 +27,8 @@ export const TooltipBlock = ({ playerLastName, playerTeamName, sport, - suffix, teamName, -}: TTooltipBlock) => ( +}: TooltipBlockProps) => ( {playerFirstName && playerLastName && `${playerFirstName} ${playerLastName}`} @@ -40,7 +38,7 @@ export const TooltipBlock = ({ - {getSportName(sport, suffix)} + {' '} {playerTeamName || countryName} diff --git a/src/features/UserSportFav/TooltipBlock/styled.tsx b/src/features/UserFavorites/TooltipBlock/styled.tsx similarity index 92% rename from src/features/UserSportFav/TooltipBlock/styled.tsx rename to src/features/UserFavorites/TooltipBlock/styled.tsx index 79a97bba..341afa74 100644 --- a/src/features/UserSportFav/TooltipBlock/styled.tsx +++ b/src/features/UserFavorites/TooltipBlock/styled.tsx @@ -15,18 +15,18 @@ export const TooltipBlockWrapper = styled.div` } ` -export type TTooltipProps = { +type TooltipProps = { color?: string, } -export const TooltipStyles = css` +export const TooltipStyles = css` display: block; font-family: Montserrat, Tahoma, sans-serif; font-size: 14px; line-height: 18px; color: ${({ color }) => (color ? `${color}` : '#2c2d2e')}; font-weight: 600; - + &:hover { background-color: rgba(255, 255, 255, 0.7); } diff --git a/src/features/UserFavorites/helpers.tsx b/src/features/UserFavorites/helpers.tsx new file mode 100644 index 00000000..9db58aaa --- /dev/null +++ b/src/features/UserFavorites/helpers.tsx @@ -0,0 +1,41 @@ +import map from 'lodash/map' + +import { getProfileLogo, getProfileUrl } from 'helpers' +import type { UserFavorites } from 'requests' + +type Names = 'name_eng' | 'name_rus' +type ShortNames = 'short_name_eng' | 'short_name_rus' +type FirstNames = 'firstname_eng' | 'firstname_rus' +type LastNames = 'lastname_eng' | 'firstname_rus' +type NickNames = 'nickname_eng' | 'nickname_rus' + +export const normalizeUserFavorites = (favorites: UserFavorites, suffix: string) => { + const nameField = `name_${suffix}` as Names + const shortNameField = `short_name_${suffix}` as ShortNames + const firtsNameField = `firstname_${suffix}` as FirstNames + const lastNameField = `lastname_${suffix}` as LastNames + const nickNameField = `nickname_${suffix}` as NickNames + + return map(favorites, (item) => ({ + countryName: item.info.country?.[nameField], + firstname: item.info[firtsNameField], + id: item.id, + lastname: item.info[lastNameField], + name: item.info[nameField], + nickname: item.info[nickNameField], + profileLogo: getProfileLogo({ + id: item.id, + profileType: item.type, + sportType: item.sport, + }), + profileUrl: getProfileUrl({ + id: item.id, + profileType: item.type, + sportType: item.sport, + }), + shortName: item.info[shortNameField], + sport: item.sport, + teamName: item.info.team?.[nameField], + type: item.type, + })) +} diff --git a/src/features/UserFavorites/hooks/index.tsx b/src/features/UserFavorites/hooks/index.tsx new file mode 100644 index 00000000..a02e542d --- /dev/null +++ b/src/features/UserFavorites/hooks/index.tsx @@ -0,0 +1,36 @@ +import { + useEffect, + useState, + useMemo, +} from 'react' + +import type { UserFavorites } from 'requests' +import { modifyUserFavorites, getUserFavorites } from 'requests' +import { useLexicsStore } from 'features/LexicsStore' + +import { normalizeUserFavorites } from '../helpers' + +type Args = Parameters[0] + +export const useUserFavorites = () => { + const { suffix } = useLexicsStore() + const [userFavorites, setUserFavorites] = useState([]) + + useEffect(() => { + getUserFavorites().then(setUserFavorites) + }, []) + + const addRemoveFavorite = (args: Args) => { + modifyUserFavorites(args).then(setUserFavorites) + } + + const memoizedUserFavorites = useMemo( + () => normalizeUserFavorites(userFavorites, suffix), + [userFavorites, suffix], + ) + + return { + addRemoveFavorite, + userFavorites: memoizedUserFavorites, + } +} diff --git a/src/features/UserFavorites/index.tsx b/src/features/UserFavorites/index.tsx new file mode 100644 index 00000000..3a27eacc --- /dev/null +++ b/src/features/UserFavorites/index.tsx @@ -0,0 +1,61 @@ +import React from 'react' + +import map from 'lodash/map' + +import { handleImageError } from 'helpers' + +import { useUserFavorites } from './hooks' +import { TooltipBlock } from './TooltipBlock' +import { + StyledLink, + UserSportFavItemLogoWrapper, + UserSportFavXWrapper, + UserSportFavImgWrapper, + UserSportFavStar, + UserSportFavLogoWrapper, + UserSportFavWrapper, +} from './styled' + +export const UserFavorites = () => { + const { addRemoveFavorite, userFavorites } = useUserFavorites() + + return ( + + + + { + map(userFavorites, (item) => ( + + addRemoveFavorite({ + action: 2, + id: item.id, + sport: item.sport, + type: item.type, + })} + /> + + + handleImageError({ + e, + sport: item.sport, + type: item.type, + })} + /> + + + )) + } + + ) +} diff --git a/src/features/UserSportFav/styled.tsx b/src/features/UserFavorites/styled.tsx similarity index 100% rename from src/features/UserSportFav/styled.tsx rename to src/features/UserFavorites/styled.tsx diff --git a/src/features/UserSportFav/TooltipBlock/hooks/index.tsx b/src/features/UserSportFav/TooltipBlock/hooks/index.tsx deleted file mode 100644 index 9968062f..00000000 --- a/src/features/UserSportFav/TooltipBlock/hooks/index.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { SPORT_COLORS } from 'config' - -export const getSportName = (sport: number, suffix: string): string => { - switch (sport) { - case 1: - return suffix === 'eng' ? 'Football' : 'Футбол' - case 2: - return suffix === 'eng' ? 'Hockey' : 'Хоккей' - case 3: - return suffix === 'eng' ? 'Basketball' : 'Баскетбол' - default: - return '' - } -} - -export const getSportColor = (sport: number): string => { - switch (sport) { - case 1: - return SPORT_COLORS.football - case 2: - return SPORT_COLORS.hockey - case 3: - return SPORT_COLORS.basketball - default: - return '' - } -} diff --git a/src/features/UserSportFav/hooks/index.tsx b/src/features/UserSportFav/hooks/index.tsx deleted file mode 100644 index 67225785..00000000 --- a/src/features/UserSportFav/hooks/index.tsx +++ /dev/null @@ -1,132 +0,0 @@ -import { - useEffect, - useState, - useMemo, -} from 'react' - -import map from 'lodash/map' - -import { - LOGOS_URLS, - FAV_SPORT_URLS, -} from 'config' -import { - SPORT_TYPES, - DATA_TYPES, -} from 'helpers' -import { - modifyUserSportFavs, - ModifyUserSportFavsArgs, - getUserSportFavs, - UserSportFavItem, -} from 'requests' -import { useLexicsStore } from 'features/LexicsStore' - -type TNames = 'name_eng' | 'name_rus' -type TShortNames = 'short_name_eng' | 'short_name_rus' -type TFirstNames = 'firstname_eng' | 'firstname_rus' -type TLastNames = 'lastname_eng' | 'firstname_rus' -type TNickNames = 'nickname_eng' | 'nickname_rus' - -export type TMemoizedUserSportFavItem = { - countryName?: string, - firstname?: string, - id: number, - lastname?: string, - name?: string, - nickname?: string, - shortName?: string, - sport: number, - teamName?: string, - type: number, -} - -type TMakeUrlArgs = { - id: number, - sport: number, - type: number, -} - -export const useUserSportFavs = () => { - const { suffix } = useLexicsStore() - const [userSportFavItems, setUserSportFavItems] = useState>([]) - - const nameField = `name_${suffix}` as TNames - const shortNameField = `short_name_${suffix}` as TShortNames - const firtsNameField = `firstname_${suffix}` as TFirstNames - const lastNameField = `lastname_${suffix}` as TLastNames - const nickNameField = `nickname_${suffix}` as TNickNames - - useEffect(() => { - getUserSportFavs().then(setUserSportFavItems) - }, []) - - const addRemoveSportFav = ({ - action, - id, - sport, - type, - }: ModifyUserSportFavsArgs) => { - // при добавлении дубликата userSportFavItem back возвращает {} - modifyUserSportFavs({ - action, - id, - sport, - type, - }).then((userSportFavs) => Array.isArray(userSportFavs) && setUserSportFavItems(userSportFavs)) - } - - const memoizedUserSportFavItems = useMemo(() => map(userSportFavItems, (item) => ({ - countryName: item.info.country?.[nameField], - firstname: item.info[firtsNameField], - id: item.id, - lastname: item.info[lastNameField], - name: item.info[nameField], - nickname: item.info[nickNameField], - shortName: item.info[shortNameField], - sport: item.sport, - teamName: item.info.team?.[nameField], - type: item.type, - })), - [ - firtsNameField, - lastNameField, - userSportFavItems, - nameField, - nickNameField, - shortNameField, - ]) - - return { - addRemoveSportFav, - userSportFavItems: memoizedUserSportFavItems, - } -} - -export const makePicUrl = (arg: TMakeUrlArgs) => ( - // @ts-expect-error - `${LOGOS_URLS[SPORT_TYPES[arg.sport]][DATA_TYPES[arg.type]]}/${arg.id}.png` -) - -export const makeProfileUrl = (arg: TMakeUrlArgs) => ( - // @ts-expect-error - `${FAV_SPORT_URLS[SPORT_TYPES[arg.sport]][DATA_TYPES[arg.type]]}/${arg.id}` -) - -export const userSportFavs = ( - userSportFavItems: Array, -) => userSportFavItems?.length > 0 && map( - userSportFavItems, (fav) => ({ - ...fav, - pic_url: makePicUrl({ - id: fav.id, - sport: fav.sport, - type: fav.type, - }), - profile_url: makeProfileUrl({ - id: fav.id, - sport: fav.sport, - type: fav.type, - }), - }), -) diff --git a/src/features/UserSportFav/index.tsx b/src/features/UserSportFav/index.tsx deleted file mode 100644 index 61c82331..00000000 --- a/src/features/UserSportFav/index.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import React from 'react' - -import map from 'lodash/map' - -import { useLexicsStore } from 'features/LexicsStore' -import { handleImageError } from 'helpers' - -import { - useUserSportFavs, - userSportFavs, -} from './hooks' -import { TooltipBlock } from './TooltipBlock' -import { - StyledLink, - UserSportFavItemLogoWrapper, - UserSportFavXWrapper, - UserSportFavImgWrapper, - UserSportFavStar, - UserSportFavLogoWrapper, - UserSportFavWrapper, -} from './styled' - -export const UserSportFav = () => { - const { addRemoveSportFav, userSportFavItems } = useUserSportFavs() - - const { suffix } = useLexicsStore() - - const userSportFavList = userSportFavs(userSportFavItems) - - return ( - - - - {userSportFavList && map(userSportFavList, (item) => ( - - addRemoveSportFav({ - action: 2, - id: item.id, - sport: item.sport, - type: item.type, - })} - /> - - - handleImageError({ - e, - sport: item.sport, - type: item.type, - })} - /> - - - ))} - - ) -} diff --git a/src/helpers/getLogo/__tests__/index.tsx b/src/helpers/getLogo/__tests__/index.tsx deleted file mode 100644 index b96aa7f9..00000000 --- a/src/helpers/getLogo/__tests__/index.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import { getLogo } from '..' - -describe('getLogo helper', () => { - it('returns logo url', () => { - expect(getLogo({ - id: 1, - sportType: 'football', - type: 'players', - })).toBe('https://instatscout.com/images/players/180/1.png') - - expect(getLogo({ - id: 1, - sportType: 'basketball', - type: 'teams', - })).toBe('https://basketball.instatscout.com/images/teams/180/1.png') - - expect(getLogo({ - id: 1, - sportType: 'hockey', - type: 'tournaments', - })).toBe('https://hockey.instatscout.com/images/tournaments/180/1.png') - }) -}) diff --git a/src/helpers/getLogo/index.tsx b/src/helpers/getLogo/index.tsx deleted file mode 100644 index dc46ee32..00000000 --- a/src/helpers/getLogo/index.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import type { SportType } from 'features/Search/config' - -const IMAGES_URLS = { - basketball: 'https://basketball.instatscout.com/images', - football: 'https://instatscout.com/images', - hockey: 'https://hockey.instatscout.com/images', -} - -type GetLogoArgs = { - id: number, - size?: number, - sportType: SportType, - type: 'players' | 'teams' | 'tournaments', -} - -export const getLogo = ({ - id, - size = 180, - sportType, - type, -}: GetLogoArgs) => ( - `${IMAGES_URLS[sportType]}/${type}/${size}/${id}.png` -) diff --git a/src/helpers/getProfileFallbackLogo/index.tsx b/src/helpers/getProfileFallbackLogo/index.tsx new file mode 100644 index 00000000..e1392e52 --- /dev/null +++ b/src/helpers/getProfileFallbackLogo/index.tsx @@ -0,0 +1,33 @@ +import { SportTypes, ProfileTypes } from 'config' + +const FALLBACK_LOGOS = { + [SportTypes.BASKETBALL]: { + [ProfileTypes.PLAYERS]: 'https://basketball.instatscout.com/images/player-no-photo.png', + [ProfileTypes.TEAMS]: 'https://basketball.instatscout.com/images/team-no-photo.png', + [ProfileTypes.TOURNAMENTS]: 'https://basketball.instatscout.com/images/tournaments/180/no-photo.png', + }, + + [SportTypes.FOOTBALL]: { + [ProfileTypes.PLAYERS]: 'https://football.instatscout.com/images/player-no-photo.png', + [ProfileTypes.TEAMS]: 'https://football.instatscout.com/images/team-no-photo.png', + [ProfileTypes.TOURNAMENTS]: 'https://football.instatscout.com/images/tournament-no-photo.png', + }, + + [SportTypes.HOCKEY]: { + [ProfileTypes.PLAYERS]: 'https://hockey.instatscout.com/images/player-no-photo.png', + [ProfileTypes.TEAMS]: 'https://hockey.instatscout.com/images/team-no-photo.png', + [ProfileTypes.TOURNAMENTS]: 'https://hockey.instatscout.com/images/tournaments/180/no-photo.png', + }, +} + +type Args = { + profileType: ProfileTypes, + sportType: SportTypes, +} + +export const getProfileFallbackLogo = ({ + profileType, + sportType, +}: Args) => ( + FALLBACK_LOGOS[sportType][profileType] +) diff --git a/src/helpers/getProfileLogo/__tests__/index.tsx b/src/helpers/getProfileLogo/__tests__/index.tsx new file mode 100644 index 00000000..fb5ed965 --- /dev/null +++ b/src/helpers/getProfileLogo/__tests__/index.tsx @@ -0,0 +1,25 @@ +import { SportTypes, ProfileTypes } from 'config' + +import { getProfileLogo } from '..' + +describe('getLogo helper', () => { + it('returns logo url', () => { + expect(getProfileLogo({ + id: 1, + profileType: ProfileTypes.PLAYERS, + sportType: SportTypes.FOOTBALL, + })).toBe('https://instatscout.com/images/players/180/1.png') + + expect(getProfileLogo({ + id: 1, + profileType: ProfileTypes.TEAMS, + sportType: SportTypes.BASKETBALL, + })).toBe('https://basketball.instatscout.com/images/teams/180/1.png') + + expect(getProfileLogo({ + id: 1, + profileType: ProfileTypes.TOURNAMENTS, + sportType: SportTypes.HOCKEY, + })).toBe('https://hockey.instatscout.com/images/tournaments/180/1.png') + }) +}) diff --git a/src/helpers/getProfileLogo/index.tsx b/src/helpers/getProfileLogo/index.tsx new file mode 100644 index 00000000..d8d82eea --- /dev/null +++ b/src/helpers/getProfileLogo/index.tsx @@ -0,0 +1,27 @@ +import { + SportTypes, + ProfileTypes, + PROFILE_NAMES, +} from 'config' + +const IMAGES_URLS = { + [SportTypes.BASKETBALL]: 'https://basketball.instatscout.com/images', + [SportTypes.FOOTBALL]: 'https://instatscout.com/images', + [SportTypes.HOCKEY]: 'https://hockey.instatscout.com/images', +} + +type GetLogoArgs = { + id: number, + profileType: ProfileTypes, + size?: number, + sportType: SportTypes, +} + +export const getProfileLogo = ({ + id, + profileType, + size = 180, + sportType, +}: GetLogoArgs) => ( + `${IMAGES_URLS[sportType]}/${PROFILE_NAMES[profileType]}/${size}/${id}.png` +) diff --git a/src/helpers/getProfileUrl/index.tsx b/src/helpers/getProfileUrl/index.tsx new file mode 100644 index 00000000..3f8e282b --- /dev/null +++ b/src/helpers/getProfileUrl/index.tsx @@ -0,0 +1,20 @@ +import { + SportTypes, + ProfileTypes, + SPORT_NAMES, + PROFILE_NAMES, +} from 'config' + +type Args = { + id: number, + profileType: ProfileTypes, + sportType: SportTypes, +} + +export const getProfileUrl = ({ + id, + profileType, + sportType, +}: Args) => ( + `${SPORT_NAMES[sportType]}/${PROFILE_NAMES[profileType]}/${id}` +) diff --git a/src/helpers/getSportColor/index.tsx b/src/helpers/getSportColor/index.tsx new file mode 100644 index 00000000..859fe0d2 --- /dev/null +++ b/src/helpers/getSportColor/index.tsx @@ -0,0 +1,9 @@ +import { SportTypes } from 'config' + +const colors = { + [SportTypes.BASKETBALL]: '#f1903b', + [SportTypes.FOOTBALL]: '#00a435', + [SportTypes.HOCKEY]: '#5eb1ff', +} + +export const getSportColor = (sport: SportTypes) => colors[sport] diff --git a/src/helpers/getSportLexic/index.tsx b/src/helpers/getSportLexic/index.tsx new file mode 100644 index 00000000..03d4e7a4 --- /dev/null +++ b/src/helpers/getSportLexic/index.tsx @@ -0,0 +1,9 @@ +import { SportTypes } from 'config' + +const lexics = { + [SportTypes.FOOTBALL]: 'football', + [SportTypes.HOCKEY]: 'hockey', + [SportTypes.BASKETBALL]: 'basketball', +} + +export const getSportLexic = (sport: SportTypes) => lexics[sport] diff --git a/src/helpers/handleImg/index.tsx b/src/helpers/handleImg/index.tsx index aa655bb2..7d76cc48 100644 --- a/src/helpers/handleImg/index.tsx +++ b/src/helpers/handleImg/index.tsx @@ -1,29 +1,23 @@ import { BaseSyntheticEvent } from 'react' -import { LOGOS_FALLBACKS } from 'config' +import { + SportTypes, + ProfileTypes, +} from 'config' +import { getProfileFallbackLogo } from 'helpers/getProfileFallbackLogo' -export type imageErrorArgs = { +type Args = { e: BaseSyntheticEvent, - sport: number, - type: number, + sport: SportTypes, + type: ProfileTypes, } -export const SPORT_TYPES = { - 1: 'football', - 2: 'hockey', - 3: 'basketball', -} as const - -export const DATA_TYPES = { - 1: 'tournaments', - 2: 'teams', - 3: 'players', -} as const - -export const handleImageError = (arg: imageErrorArgs): void => { +export const handleImageError = (arg: Args): void => { // eslint-disable-next-line no-param-reassign arg.e.target.onError = '' - // @ts-expect-error // eslint-disable-next-line no-param-reassign - arg.e.target.src = LOGOS_FALLBACKS[SPORT_TYPES[arg.sport]][DATA_TYPES[arg.type]] + arg.e.target.src = getProfileFallbackLogo({ + profileType: arg.type, + sportType: arg.sport, + }) } diff --git a/src/helpers/index.tsx b/src/helpers/index.tsx index 561ffbcb..e37b5313 100644 --- a/src/helpers/index.tsx +++ b/src/helpers/index.tsx @@ -1,5 +1,9 @@ export * from './callApi' export * from './callApi/getResponseData' export * from './token' -export * from './getLogo' +export * from './getProfileLogo' +export * from './getProfileFallbackLogo' +export * from './getProfileUrl' +export * from './getSportColor' +export * from './getSportLexic' export * from './handleImg' diff --git a/src/requests/getMatches.tsx b/src/requests/getMatches.tsx index efc0bd44..bbe5143c 100644 --- a/src/requests/getMatches.tsx +++ b/src/requests/getMatches.tsx @@ -1,4 +1,8 @@ -import { DATA_URL, PROCEDURES } from 'config' +import { + DATA_URL, + PROCEDURES, + SportTypes, +} from 'config' import { callApi, getResponseData } from 'helpers' import { MatchStatuses } from 'features/HeaderFilters' @@ -48,7 +52,7 @@ export type Team = { type Args = { date: string, matchStatus: MatchStatuses, - sportType: number, + sportType: SportTypes, tournamentId: number, } diff --git a/src/requests/getSearchItems.tsx b/src/requests/getSearchItems.tsx index 89f19091..1ce42126 100644 --- a/src/requests/getSearchItems.tsx +++ b/src/requests/getSearchItems.tsx @@ -1,12 +1,14 @@ -import { DATA_URL, PROCEDURES } from 'config' +import { + DATA_URL, + PROCEDURES, + SportTypes, +} from 'config' import { callApi, getResponseData } from 'helpers' const proc = PROCEDURES.get_players_teams_tournaments type Gender = 1 | 2 -type Sport = 1 | 2 | 3 - type Player = { firstname_eng: string, firstname_rus: string, @@ -14,7 +16,7 @@ type Player = { id: number, lastname_eng: string, lastname_rus: string, - sport: Sport, + sport: SportTypes, team?: { id: number, name_eng: string, @@ -32,7 +34,7 @@ type Team = { id: number, name_eng: string, name_rus: string, - sport: Sport, + sport: SportTypes, } type Tournament = { @@ -45,7 +47,7 @@ type Tournament = { id: number, name_eng: string, name_rus: string, - sport: Sport, + sport: SportTypes, } export type SearchItems = { diff --git a/src/requests/getSportTournaments.tsx b/src/requests/getSportTournaments.tsx index 8856307f..63bfcce0 100644 --- a/src/requests/getSportTournaments.tsx +++ b/src/requests/getSportTournaments.tsx @@ -1,6 +1,9 @@ -import { DATA_URL, PROCEDURES } from 'config' +import { + DATA_URL, + PROCEDURES, + SportTypes, +} from 'config' import { callApi, getResponseData } from 'helpers' -import { SportTypes } from 'features/HeaderFilters' const proc = PROCEDURES.get_tournament_list diff --git a/src/requests/getUserSportFavs.tsx b/src/requests/getUserSportFavs.tsx index 0c57a55f..ea75d088 100644 --- a/src/requests/getUserSportFavs.tsx +++ b/src/requests/getUserSportFavs.tsx @@ -1,44 +1,46 @@ -import { DATA_URL, PROCEDURES } from 'config' +import { + DATA_URL, + PROCEDURES, + SportTypes, + ProfileTypes, +} from 'config' import { callApi, getResponseData } from 'helpers' const proc = PROCEDURES.get_user_favorites -export type UserSportFavItem = { +type ObjectWithName = { + name_eng: string, + name_rus: string, +} + +type Info = { + country?: ObjectWithName, + date?: string, + firstname_eng?: string, + firstname_rus?: string, + lastname_eng?: string, + lastname_rus?: string, + name_eng?: string, + name_rus?: string, + nickname_eng?: string, + nickname_rus?: string, + short_name_eng?: string, + short_name_rus?: string, + team?: ObjectWithName, + team1?: ObjectWithName, + team2?: ObjectWithName, +} + +type UserFavorite = { id: number, - info: { - country?: { - name_eng: string, - name_rus: string, - }, - date?: string, - firstname_eng?: string, - firstname_rus?: string, - lastname_eng?: string, - lastname_rus?: string, - name_eng?: string, - name_rus?: string, - nickname_eng?: string, - nickname_rus?: string, - short_name_eng?: string, - short_name_rus?: string, - team?: { - name_eng: string, - name_rus: string, - }, - team1?: { - name_eng: string, - name_rus: string, - }, - team2?: { - name_eng: string, - name_rus: string, - }, - }, - sport: number, - type: number, + info: Info, + sport: SportTypes, + type: ProfileTypes, } -export const getUserSportFavs = (): Promise> => { +export type UserFavorites = Array + +export const getUserFavorites = (): Promise => { const config = { body: { params: {}, diff --git a/src/requests/modifyUserSportFavs.tsx b/src/requests/modifyUserSportFavs.tsx index c2eb3470..2203e97f 100644 --- a/src/requests/modifyUserSportFavs.tsx +++ b/src/requests/modifyUserSportFavs.tsx @@ -1,23 +1,31 @@ -import { DATA_URL, PROCEDURES } from 'config' +import isArray from 'lodash/isArray' + +import { + DATA_URL, + PROCEDURES, + SportTypes, + ProfileTypes, +} from 'config' import { callApi, getResponseData } from 'helpers' -import { UserSportFavItem } from './getUserSportFavs' + +import { UserFavorites } from './getUserSportFavs' const proc = PROCEDURES.save_user_favorite -export type ModifyUserSportFavsArgs = { +type Args = { action: number, id: number, - sport: number, - type: number, + sport: SportTypes, + type: ProfileTypes, } -// при добавлении дубликата userSportFavItem back возвращает {} -export const modifyUserSportFavs = ({ +// при добавлении дубликата back возвращает {} +export const modifyUserFavorites = async ({ action, id, sport, type, -}: ModifyUserSportFavsArgs): Promise | {}> => { +}: Args): Promise => { const config = { body: { params: { @@ -30,8 +38,10 @@ export const modifyUserSportFavs = ({ }, } - return callApi({ + const data = await callApi({ config, url: DATA_URL, }).then(getResponseData(proc)) + + return isArray(data) ? data : [] }