-
-
- {viewModes.map((mode) => (
-
-
-
- {getViewModeLabel(mode)}
-
-
- ))}
-
-
+
+
+
+ {viewModes.map((mode) => (
+
+
+
+ {getViewModeLabel(mode)}
+
+
+ ))}
-
-
+
{showCurationGroupSelect && onCurationGroupChange && (
= ({
onChange={onCurationGroupChange}
/>
)}
- {connectedProfile && participation.isEligible && (
-
- )}
+ {connectedProfile && participation.isEligible && (
+
+ )}
);
diff --git a/components/waves/leaderboard/header/WaveleaderboardSort.tsx b/components/waves/leaderboard/header/WaveleaderboardSort.tsx
index 8eba4a5777..c287b83485 100644
--- a/components/waves/leaderboard/header/WaveleaderboardSort.tsx
+++ b/components/waves/leaderboard/header/WaveleaderboardSort.tsx
@@ -1,50 +1,19 @@
"use client";
-import { QueryKey } from "@/components/react-query-wrapper/ReactQueryWrapper";
-import {
- WAVE_DROPS_PARAMS,
- getDefaultQueryRetry,
-} from "@/components/react-query-wrapper/utils/query-utils";
import type { CommonSelectItem } from "@/components/utils/select/CommonSelect";
import CommonDropdown from "@/components/utils/select/dropdown/CommonDropdown";
-import type { ApiDropsLeaderboardPage } from "@/generated/models/ApiDropsLeaderboardPage";
import { WaveDropsLeaderboardSort } from "@/hooks/useWaveDropsLeaderboard";
-import { commonApiFetch } from "@/services/api/common-api";
-import { useQueryClient } from "@tanstack/react-query";
-import { debounce } from "lodash";
-import React, { useCallback, useEffect, useMemo } from "react";
-import { createBreakpoint } from "react-use";
+import React, { useMemo } from "react";
interface WaveleaderboardSortProps {
readonly sort: WaveDropsLeaderboardSort;
readonly onSortChange: (sort: WaveDropsLeaderboardSort) => void;
- readonly waveId?: string | undefined;
- readonly curatedByGroupId?: string | undefined;
}
-const SORT_DIRECTION_MAP: Record<
- WaveDropsLeaderboardSort,
- "ASC" | "DESC" | undefined
-> = {
- [WaveDropsLeaderboardSort.RANK]: undefined,
- [WaveDropsLeaderboardSort.RATING_PREDICTION]: "DESC",
- [WaveDropsLeaderboardSort.TREND]: "DESC",
- [WaveDropsLeaderboardSort.MY_REALTIME_VOTE]: undefined,
- [WaveDropsLeaderboardSort.CREATED_AT]: "DESC",
-};
-
-const useBreakpoint = createBreakpoint({ MD: 768, S: 0 });
-
export const WaveleaderboardSort: React.FC
= ({
sort,
onSortChange,
- waveId,
- curatedByGroupId,
}) => {
- const breakpoint = useBreakpoint();
- const isSmallViewport = breakpoint === "S";
- const queryClient = useQueryClient();
- const normalizedCuratedByGroupId = curatedByGroupId?.trim() ?? undefined;
const sortItems = useMemo<
readonly CommonSelectItem[]
>(
@@ -73,150 +42,16 @@ export const WaveleaderboardSort: React.FC = ({
[]
);
- const prefetchSortImmediate = useCallback(
- (targetSort: WaveDropsLeaderboardSort) => {
- if (!waveId || targetSort === sort) return;
-
- const sortDirection = SORT_DIRECTION_MAP[targetSort];
- const queryKey = [
- QueryKey.DROPS_LEADERBOARD,
- {
- waveId,
- page_size: WAVE_DROPS_PARAMS.limit,
- sort: targetSort,
- sort_direction: sortDirection,
- curated_by_group: normalizedCuratedByGroupId ?? null,
- },
- ];
-
- queryClient
- .prefetchInfiniteQuery({
- queryKey,
- queryFn: async ({ pageParam }: { pageParam: number | null }) => {
- const params: Record = {
- page_size: WAVE_DROPS_PARAMS.limit.toString(),
- sort: targetSort,
- };
-
- if (sortDirection) {
- params["sort_direction"] = sortDirection;
- }
-
- if (typeof pageParam === "number") {
- params["page"] = `${pageParam}`;
- }
-
- if (normalizedCuratedByGroupId) {
- params["curated_by_group"] = normalizedCuratedByGroupId;
- }
-
- return await commonApiFetch({
- endpoint: `waves/${waveId}/leaderboard`,
- params,
- });
- },
- pages: 1,
- initialPageParam: null,
- getNextPageParam: (lastPage: ApiDropsLeaderboardPage) => {
- if (targetSort === WaveDropsLeaderboardSort.MY_REALTIME_VOTE) {
- const haveZeroVotes = lastPage.drops.some(
- (drop) => drop.context_profile_context?.rating === 0
- );
- if (haveZeroVotes) {
- return null;
- }
- }
- return lastPage.next ? lastPage.page + 1 : null;
- },
- staleTime: 60000,
- ...getDefaultQueryRetry(),
- })
- .catch((error: unknown) => {
- // Log prefetch errors for debugging while not blocking the UI
- console.warn("Failed to prefetch leaderboard data:", {
- waveId,
- targetSort,
- error: error instanceof Error ? error.message : error,
- });
- });
- },
- [queryClient, waveId, sort, normalizedCuratedByGroupId]
- );
-
- // Debounce prefetch to prevent excessive network requests on rapid hover events
- const prefetchSort = useMemo(
- () => debounce(prefetchSortImmediate, 300),
- [prefetchSortImmediate]
- );
-
- // Cancel pending debounced calls on unmount to avoid late network requests
- useEffect(() => {
- return () => prefetchSort.cancel();
- }, [prefetchSort]);
-
- const getButtonClassName = (buttonSort: WaveDropsLeaderboardSort) => {
- const baseClass =
- "tw-px-4 tw-py-1.5 tw-text-xs tw-font-medium tw-border-0 tw-rounded-md tw-transition-colors";
-
- if (sort === buttonSort) {
- return `${baseClass} tw-bg-white/10 tw-text-white tw-shadow-sm`;
- }
-
- return `${baseClass} tw-bg-transparent tw-text-iron-500 desktop-hover:hover:tw-text-iron-300`;
- };
-
- if (isSmallViewport) {
- return (
-
-
- items={sortItems}
- activeItem={sort}
- filterLabel="Sort"
- setSelected={onSortChange}
- size="sm"
- showFilterLabel={true}
- />
-
- );
- }
-
return (
-
-
-
-
-
+
+
+ items={sortItems}
+ activeItem={sort}
+ filterLabel="Sort"
+ setSelected={onSortChange}
+ size="sm"
+ showFilterLabel={true}
+ />
);
};