diff --git a/src/app/components/ui/skeleton.tsx b/src/app/components/ui/skeleton.tsx new file mode 100644 index 0000000..8837f9d --- /dev/null +++ b/src/app/components/ui/skeleton.tsx @@ -0,0 +1,7 @@ +import { cn } from "@/common/utils"; + +function Skeleton({ className, ...props }: React.HTMLAttributes) { + return
; +} + +export { Skeleton }; diff --git a/src/components/leaderboard/leaderboard-scores.tsx b/src/components/leaderboard/leaderboard-scores.tsx index d0b23f3..0f5bf57 100644 --- a/src/components/leaderboard/leaderboard-scores.tsx +++ b/src/components/leaderboard/leaderboard-scores.tsx @@ -12,11 +12,11 @@ import Pagination from "../input/pagination"; import LeaderboardScore from "./leaderboard-score"; import { scoreAnimation } from "@/components/score/score-animation"; -type Props = { +type LeaderboardScoresProps = { leaderboard: ScoreSaberLeaderboardToken; }; -export default function LeaderboardScores({ leaderboard }: Props) { +export default function LeaderboardScores({ leaderboard }: LeaderboardScoresProps) { const { width } = useWindowDimensions(); const controls = useAnimation(); diff --git a/src/components/navbar/navbar.tsx b/src/components/navbar/navbar.tsx index f562938..ce204f7 100644 --- a/src/components/navbar/navbar.tsx +++ b/src/components/navbar/navbar.tsx @@ -26,9 +26,9 @@ const items: NavbarItem[] = [ // Helper function to render each navbar item const renderNavbarItem = (item: NavbarItem) => ( -
- {item.icon &&
{item.icon}
} -
{item.name}
+
+ {item.icon &&
{item.icon}
} +

{item.name}

); @@ -37,7 +37,7 @@ export default function Navbar() { return (
-
+
{/* Left-aligned items */}
diff --git a/src/components/navbar/profile-button.tsx b/src/components/navbar/profile-button.tsx index f4353b9..74b0bbe 100644 --- a/src/components/navbar/profile-button.tsx +++ b/src/components/navbar/profile-button.tsx @@ -27,7 +27,7 @@ export default function ProfileButton() { src={`https://img.fascinated.cc/upload/w_24,h_24/https://cdn.scoresaber.com/avatars/${settings.playerId}.jpg`} /> -

You

+

You

); diff --git a/src/components/ranking/mini.tsx b/src/components/ranking/mini.tsx index 469c951..afcbe77 100644 --- a/src/components/ranking/mini.tsx +++ b/src/components/ranking/mini.tsx @@ -10,6 +10,7 @@ import CountryFlag from "../country-flag"; import { Avatar, AvatarImage } from "../ui/avatar"; import ScoreSaberPlayer from "@/common/model/player/impl/scoresaber-player"; import { scoresaberService } from "@/common/service/impl/scoresaber"; +import { PlayerRankingSkeleton } from "@/components/ranking/player-ranking-skeleton"; const PLAYER_NAME_MAX_LENGTH = 18; @@ -96,6 +97,10 @@ export default function Mini({ type, player }: MiniProps) { players = players.slice(playerPosition - 3, playerPosition + 2); } + if (isLoading) { + return ; + } + return (
@@ -103,7 +108,6 @@ export default function Mini({ type, player }: MiniProps) {

{type} Ranking

- {isLoading &&

Loading...

} {isError &&

Error

} {players?.map((playerRanking, index) => { const rank = type == "Global" ? playerRanking.rank : playerRanking.countryRank; @@ -120,13 +124,13 @@ export default function Mini({ type, player }: MiniProps) { className="grid gap-2 grid-cols-[auto_1fr_auto] items-center bg-accent px-2 py-1.5 cursor-pointer transform-gpu transition-all hover:brightness-75 first:rounded-t last:rounded-b" >

#{formatNumberWithCommas(rank)}

-
+

{playerName}

-
+

{formatPp(playerRanking.pp)}pp

{playerRanking.id !== player.id && (

0 ? "text-green-400" : "text-red-400"}`}> diff --git a/src/components/ranking/player-ranking-skeleton.tsx b/src/components/ranking/player-ranking-skeleton.tsx new file mode 100644 index 0000000..8a27c9c --- /dev/null +++ b/src/components/ranking/player-ranking-skeleton.tsx @@ -0,0 +1,34 @@ +import Card from "@/components/card"; +import { Skeleton } from "@/app/components/ui/skeleton"; + +export function PlayerRankingSkeleton() { + const skeletonArray = new Array(5).fill(0); + + return ( + +

+ {/* Icon Skeleton */} + {/* Text Skeleton for Ranking */} +
+ +
+ {skeletonArray.map((_, index) => ( +
+ {/* Rank Skeleton */} +
+ {/* Avatar Skeleton */} + {/* Player Name Skeleton */} +
+
+ {/* PP Value Skeleton */} + {/* PP Difference Skeleton */} +
+
+ ))} +
+ + ); +}