diff --git a/src/components/sheet/drawer.tsx b/src/components/sheet/drawer.tsx index 9fa4d22..dabbbc8 100644 --- a/src/components/sheet/drawer.tsx +++ b/src/components/sheet/drawer.tsx @@ -1,5 +1,10 @@ -import { Box, Container, Flex, Loader, Title, useComputedColorScheme } from "@mantine/core"; -import { PropsWithChildren, Suspense, useEffect, useRef } from "react"; +import { + Box, + Container, + Title, + useComputedColorScheme, +} from "@mantine/core"; +import { PropsWithChildren, useEffect, useRef } from "react"; import { Drawer as VaulDrawer } from "vaul"; import styles from "./styles.module.css"; @@ -17,6 +22,11 @@ const Drawer: React.FC = ({ }) => { const colorScheme = useComputedColorScheme("light"); const contentRef = useRef(null); + const openedRef = useRef(opened); + + useEffect(() => { + openedRef.current = opened; + }, [opened]); useEffect(() => { const appElement = document.querySelector(".app") as HTMLElement; @@ -57,7 +67,7 @@ const Drawer: React.FC = ({ appElement.classList.remove("drawer-scaling"); themeColorMeta.content = currentColors.normal; }; - }, [opened, colorScheme]); + }, [opened]); useEffect(() => { if (!opened || !contentRef.current) return; @@ -69,46 +79,44 @@ const Drawer: React.FC = ({ if (visualViewport) { const availableHeight = visualViewport.height; - const maxDrawerHeight = Math.min(availableHeight * 0.75, window.innerHeight * 0.75); + const maxDrawerHeight = Math.min( + availableHeight * 0.75, + window.innerHeight * 0.75 + ); drawerContent.style.maxHeight = `${maxDrawerHeight}px`; } else { - drawerContent.style.maxHeight = '75vh'; + drawerContent.style.maxHeight = "75vh"; } } }; - const resizeObserver = new ResizeObserver(() => { - if (contentRef.current) { - const drawerContent = contentRef.current.closest('[data-vaul-drawer-wrapper]'); - if (drawerContent) { - (drawerContent as HTMLElement).style.height = 'auto'; - (drawerContent as HTMLElement).offsetHeight; - } - } - }); - updateDrawerHeight(); if (window.visualViewport) { - window.visualViewport.addEventListener('resize', updateDrawerHeight); + window.visualViewport.addEventListener("resize", updateDrawerHeight); } - resizeObserver.observe(contentRef.current); - return () => { - resizeObserver.disconnect(); if (window.visualViewport) { - window.visualViewport.removeEventListener('resize', updateDrawerHeight); + window.visualViewport.removeEventListener("resize", updateDrawerHeight); } }; - }, [opened, children]); + }, [opened]); return ( - + - + = ({ style={{ borderRadius: "9999px" }} /> - {title} - - - - }> - {children} - + + {title} + + {children} diff --git a/src/components/sheet/sheet.tsx b/src/components/sheet/sheet.tsx index 9d2e178..522900c 100644 --- a/src/components/sheet/sheet.tsx +++ b/src/components/sheet/sheet.tsx @@ -1,8 +1,8 @@ -import { PropsWithChildren, useCallback } from "react"; +import { PropsWithChildren, Suspense, useCallback } from "react"; import { useIsMobile } from "@/hooks/use-is-mobile"; import Drawer from "./drawer"; import Modal from "./modal"; -import { ScrollArea } from "@mantine/core"; +import { ScrollArea, Flex, Loader } from "@mantine/core"; interface SheetProps extends PropsWithChildren { title?: string; @@ -16,6 +16,8 @@ const Sheet: React.FC = ({ title, children, opened, onChange }) => { const SheetComponent = isMobile ? Drawer : Modal; + if (!opened) return null; + return ( = ({ title, children, opened, onChange }) => { onChange={onChange} onClose={handleClose} > - - {children} - + + + + }> + + {children} + + ); }; diff --git a/src/features/matches/components/match-card.tsx b/src/features/matches/components/match-card.tsx index e270149..eb41d1a 100644 --- a/src/features/matches/components/match-card.tsx +++ b/src/features/matches/components/match-card.tsx @@ -252,7 +252,7 @@ const MatchCard = ({ match, hideH2H = false }: MatchCardProps) => { - {match.home && match.away && ( + {match.home && match.away && !hideH2H && h2hSheet.isOpen && ( { +const TeamHeadToHeadContent = ({ team1, team2, isOpen = true }: TeamHeadToHeadSheetProps) => { const [shouldFetch, setShouldFetch] = useState(false); useEffect(() => { @@ -205,4 +206,12 @@ const TeamHeadToHeadSheet = ({ team1, team2, isOpen = true }: TeamHeadToHeadShee ); }; +const TeamHeadToHeadSheet = (props: TeamHeadToHeadSheetProps) => { + return ( + }> + + + ); +}; + export default TeamHeadToHeadSheet; diff --git a/src/features/matches/components/team-head-to-head-skeleton.tsx b/src/features/matches/components/team-head-to-head-skeleton.tsx new file mode 100644 index 0000000..52b5223 --- /dev/null +++ b/src/features/matches/components/team-head-to-head-skeleton.tsx @@ -0,0 +1,72 @@ +import { Stack, Skeleton, Group, Paper, Divider } from "@mantine/core"; + +const TeamHeadToHeadSkeleton = () => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; + +export default TeamHeadToHeadSkeleton; diff --git a/src/features/matches/queries.ts b/src/features/matches/queries.ts index 531524d..81f5e0c 100644 --- a/src/features/matches/queries.ts +++ b/src/features/matches/queries.ts @@ -1,4 +1,4 @@ -import { useServerQuery } from "@/lib/tanstack-query/hooks"; +import { useServerSuspenseQuery } from "@/lib/tanstack-query/hooks"; import { getMatchesBetweenTeams, getMatchesBetweenPlayers } from "./server"; export const matchKeys = { @@ -18,13 +18,13 @@ export const matchQueries = { }; export const useTeamHeadToHead = (team1Id: string, team2Id: string, enabled = true) => - useServerQuery({ + useServerSuspenseQuery({ ...matchQueries.headToHeadTeams(team1Id, team2Id), enabled, }); export const usePlayerHeadToHead = (player1Id: string, player2Id: string, enabled = true) => - useServerQuery({ + useServerSuspenseQuery({ ...matchQueries.headToHeadPlayers(player1Id, player2Id), enabled, }); diff --git a/src/features/players/components/player-head-to-head-sheet.tsx b/src/features/players/components/player-head-to-head-sheet.tsx index 5ddbe1f..f5e0fea 100644 --- a/src/features/players/components/player-head-to-head-sheet.tsx +++ b/src/features/players/components/player-head-to-head-sheet.tsx @@ -1,8 +1,9 @@ import { Stack, Text, Group, Box, Divider, Paper } from "@mantine/core"; import { usePlayerHeadToHead } from "@/features/matches/queries"; -import { useMemo, useEffect, useState } from "react"; +import { useMemo, useEffect, useState, Suspense } from "react"; import { CrownIcon } from "@phosphor-icons/react"; import MatchList from "@/features/matches/components/match-list"; +import PlayerHeadToHeadSkeleton from "./player-head-to-head-skeleton"; interface PlayerHeadToHeadSheetProps { player1Id: string; @@ -12,7 +13,7 @@ interface PlayerHeadToHeadSheetProps { isOpen?: boolean; } -const PlayerHeadToHeadSheet = ({ +const PlayerHeadToHeadContent = ({ player1Id, player1Name, player2Id, @@ -267,4 +268,12 @@ const PlayerHeadToHeadSheet = ({ ); }; +const PlayerHeadToHeadSheet = (props: PlayerHeadToHeadSheetProps) => { + return ( + }> + + + ); +}; + export default PlayerHeadToHeadSheet; diff --git a/src/features/players/components/player-head-to-head-skeleton.tsx b/src/features/players/components/player-head-to-head-skeleton.tsx new file mode 100644 index 0000000..cc5cd16 --- /dev/null +++ b/src/features/players/components/player-head-to-head-skeleton.tsx @@ -0,0 +1,72 @@ +import { Stack, Skeleton, Group, Paper, Divider } from "@mantine/core"; + +const PlayerHeadToHeadSkeleton = () => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; + +export default PlayerHeadToHeadSkeleton; diff --git a/src/lib/tanstack-query/hooks/user-server-suspense-query.ts b/src/lib/tanstack-query/hooks/user-server-suspense-query.ts index 828ce91..df77117 100644 --- a/src/lib/tanstack-query/hooks/user-server-suspense-query.ts +++ b/src/lib/tanstack-query/hooks/user-server-suspense-query.ts @@ -8,6 +8,7 @@ export function useServerSuspenseQuery( queryFn: () => Promise>; options?: Omit, 'queryFn' | 'queryKey'> showErrorToast?: boolean; + enabled?: boolean; } ) { const { queryKey, queryFn, showErrorToast = true, options: queryOptions } = options;