@orderly.network/trading-leaderboard 2.6.1 → 2.6.2-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +7 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +5 -5
- package/dist/index.mjs.map +1 -1
- package/package.json +9 -9
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/deprecated/components/provider/index.tsx","../src/deprecated/pages/leaderboard/leaderboard.mobile.ui.tsx","../src/deprecated/components/campaigns/campaigns.widget.tsx","../src/deprecated/components/campaigns/campaigns.mobile.ui.tsx","../src/deprecated/components/campaigns/campaigns.script.ts","../src/utils.ts","../src/deprecated/components/campaigns/campaigns.ui.tsx","../src/deprecated/components/tradingList/tradingList.mobile.ui.tsx","../src/deprecated/components/tradingList/column.tsx","../src/deprecated/components/tradingList/tradingList.script.ts","../src/hooks/useEndReached.ts","../src/deprecated/components/tradingList/tradingList.ui.tsx","../src/deprecated/components/tradingList/tradingList.widget.tsx","../src/deprecated/pages/leaderboard/leaderboard.script.ts","../src/deprecated/pages/leaderboard/leaderboard.ui.tsx","../src/deprecated/pages/leaderboard/leaderboard.widget.tsx","../src/components/provider/index.tsx","../src/components/ranking/shared/ranking.ui.tsx","../src/components/ranking/shared/column.tsx","../src/components/ranking/shared/util.ts","../src/components/ranking/generalRanking/generalRanking.script.ts","../src/components/ranking/generalRanking/generalRanking.widget.tsx","../src/components/ranking/campaignRanking/campaignRanking.script.ts","../src/components/rewards/utils.ts","../src/components/ranking/campaignRanking/campaignRanking.widget.tsx","../src/components/leaderboard/generalLeaderboard/generalLeaderboard.script.ts","../src/components/leaderboard/generalLeaderboard/generalLeaderboard.ui.tsx","../src/components/leaderboard/shared/LeaderboardFilter.tsx","../src/components/leaderboard/shared/LeaderboardTabs.tsx","../src/components/leaderboard/generalLeaderboard/generalLeaderboard.widget.tsx","../src/components/leaderboard/campaignLeaderboard/campaignLeaderboard.script.ts","../src/components/leaderboard/campaignLeaderboard/campaignLeaderboard.ui.tsx","../src/components/leaderboard/campaignLeaderboard/campaignLeaderboard.widget.tsx","../src/pages/leaderboard/page.tsx","../src/components/background/index.tsx","../src/components/campaigns/campaigns.widget.tsx","../src/components/campaigns/campaigns.content.desktop.ui.tsx","../src/components/campaigns/utils.ts","../src/components/campaigns/type.ts","../src/components/campaigns/campaigns.script.ts","../src/components/campaigns/components/time.desktop.ui.tsx","../src/components/campaigns/components/axis.tsx","../src/components/campaigns/components/countdown.tsx","../src/components/campaigns/header/campaigns.header.desktop.ui.tsx","../src/components/campaigns/DefaultCampaign.tsx","../src/components/campaigns/campaign.item.ui.tsx","../src/components/campaigns/header/campaigns.header.mobile.ui.tsx","../src/components/campaigns/header/campaigns.header.widget.tsx","../src/components/rewards/rewards.widget.tsx","../src/components/rewards/rewards.desktop.ui.tsx","../src/components/rule/rule.widget.tsx","../src/components/rule/rule.tsx","../src/components/rule/description.tsx","../src/components/rule/terms.tsx"],"names":["createContext","useContext","useMemo","jsx","TradingLeaderboardContext","TradingLeaderboardProvider","props","href","campaigns","backgroundSrc","children","memoizedValue","useTradingLeaderboardContext","cn","Flex","useScreen","useTranslation","Box","Text","Button","Select","jsxs","scrollIndicatorWidth","scrollIndicatorHeight","MobileCampaigns","Header","campaign","CampaignItem","ScrollIndicator","title","description","image","displayTime","learnMoreUrl","tradingUrl","t","style","scrollIndex","list","item","index","useEffect","useState","useEmblaCarousel","useTrack","TrackerEventName","format","subDays","getDateRange","offsetDay","formatDateRange","date","getUTCDateInfo","year","month","day","hours","minutes","formatCampaignDate","monthNames","formatUpdateDate","timestamp","time","useCampaignsScript","category","setCategory","track","tracking","filterCampaigns","now","acc","startTime","endTime","options","currentCampaigns","firstAvailableCategory","onCategoryChange","value","setScrollIndex","emblaRef","emblaApi","onLearnMore","onTradeNow","Campaigns","CampaignsWidget","state","isMobile","DataFilter","DataTable","Spinner","useCallback","useRef","differenceInDays","useAccount","useConfig","useInfiniteQuery","useQuery","usePrivateQuery","usePagination","useEndReached","sentinelRef","onEndReached","observer","cb","handleObserver","entries","entry","FilterDays","useTradingListScript","searchValue","setSearchValue","initialSort","sort","setSort","brokerId","dateRange","filterDay","updateFilterDay","filterItems","onFilter","useFilter","page","pageSize","setPage","parsePagination","getUrl","args","searchParams","prefix","data","isLoading","res","infiniteData","size","setSize","isValidating","pageIndex","previousPageData","top100Data","userDataRes","getAddressRank","address","isSameAddress","userDataList","getRowKey","addRankForList","total","rank","dataSource","rankList","dataList","flatList","pagination","onSearchValueChange","clearSearchValue","onSort","setFilterDay","setDateRange","filter","newDateRange","address1","address2","Fragment","useTradingListColumns","record","isYou","MobileTradingList","column","isFirst","isLast","CloseCircleFillIcon","Input","TradingList","SearchIcon","TradingListWidget","MobileLeaderboardWidget","isVideoSrc","src","extension","useLeaderboardScript","showCampaigns","isVideo","Leaderboard","renderBackground","linearGradient","LeaderboardWidget","parseISO","sortWith","descend","useMemoizedFn","campaignId","dataAdapter","onCampaignChange","userData","setUserData","updatedTime","setUpdatedTime","generateCode","generateCodeMutate","currentCampaign","filteredCampaigns","memoCampaignChange","id","getCurrentAddressRowKey","useRankingColumns","fields","enableSort","rankIcon","badgeImg","FirstRankIcon","first_badge_default","SecondRankIcon","second_badge_default","ThirdRankIcon","third_badge_default","linearGradientText","Ranking","onRow","isSecond","isThird","onCell","isFirstColumn","isLastColumn","isRank","useGeneralRankingScript","sortKey","formatData","GeneralRankingWidget","rest","getUserMetricValue","userdata","metric","estimateUserRank","userMetricValue","totalParticipants","findRewardInPool","pool","estimatedRank","tier","isInTier","start","end","calculateEstimatedRewards","totalEstimatedReward","mainCurrency","calculateEstimatedTickets","ticketRules","calculateTieredTickets","calculateLinearTickets","metricValue","tiers","sortedTiers","a","b","linearRule","formatRewardAmount","amount","currency","formatTicketCount","tickets","calculateUserPoolReward","calculateTicketProgress","every","nextTier","progress","nextTierValue","currentTier","i","useCampaignRankingScript","isCustomData","customData","getUserUrl","_data","rewards","CampaignRankingWidget","useGeneralLeaderboardScript","activeTab","setActiveTab","filterState","searchState","useSearch","Divider","LeaderboardFilter","input","dateRangeView","filterDayView","TabPanel","Tabs","LeaderboardTabs","updateTime","showVolume","showPnl","metrics","isMobileGeneral","renderTabs","GeneralLeaderboard","GeneralLeaderboardWidget","useCampaignLeaderboardScript","excludeColumns","difference","CampaignLeaderboard","CampaignLeaderboardWidget","Background","InfoCircleIcon","Tooltip","ChevronRightIcon","AuthGuard","i18n","CampaignTagEnum","DEFAULT_TIMEZONE_DISPLAY","getUserTimezoneDisplay","getCampaignTag","userReferralCode","currentTime","formatCampaignDateRange","showTimezone","startDate","endDate","startFormatted","endFormatted","timezoneDisplay","getTradingVolume","statistics","getTotalPrizePool","currencyTotals","currencies","getTicketPrizePool","formatPrizeAmount","generateCampaignTimeline","rewardTime","timeline","getTimelineType","isNow","formatTimeDisplay","formatted","CampaignsContentDesktopUI","classNames","shouldShowJoinButton","joinCampaign","isJoining","canTrade","bgSrc","tooltipOpen","setTooltipOpen","tooltipProps","tradingVolume","totalPrizePool","ticketPrizePool","showTradeButton","isCampaignStarted","highlightPool","tooltipContent","useMutation","AccountStatusEnum","toast","currentCampaignId","symbols","isCampaignEnded","stats","userCampaigns","refreshUserCampaigns","isParticipated","doJoinCampaign","joinError","result","error","CampaignsAxis","points","activeIndex","point","AxisPoint","getLineBackgroundClass","segmentIndex","widthPercentage","CampaignsAxisMobile","type","Circle","TimeUnit","label","CampaignsCountdown","timeLeft","setTimeLeft","isStarted","setIsStarted","calculateTimeLeft","hasStarted","days","seconds","timer","titleText","timeUnits","unit","CampaignsTimeDesktopUI","timelineData","ChevronLeftIcon","DefaultCampaign","className","CampaignItemUI","active","tag","CampaignTag","tagText","CampaignsHeaderUI","isLargeScreen","setIsLargeScreen","canScrollPrev","setCanScrollPrev","canScrollNext","setCanScrollNext","checkScreenSize","updateScrollAvailability","slidesInView","lastSlideIndex","isLastSlideInView","scrollPrev","scrollNext","slideStyle","shouldHideScrollButtons","memo","CampaignsHeaderMobileUI","hasInitialScrolled","isInitializing","allCampaignItems","selectedIndex","selectedCampaign","scrollToCurrentCampaign","targetIndex","CampaignsHeaderWidget","contentClassNames","Trans","commify","RewardsDesktopUI","hideConfig","currentUserData","estimatedRewards","estimatedTickets","rewardText","ticketText","userPoolReward","ticketTooltipContent","extraProps","RewardItem","RewardsWidget","LeaderboardTitle","getListStyleClass","parseRichText","text","parts","currentIndex","key","boldRegex","linkRegex","imageRegex","allMatches","match","beforeText","remainingText","DescriptionContent","config","renderContent","contents","level","defaultListStyle","content","renderContentItem","itemListStyle","CampaignRuleUI","rules","ruleConfig","CampaignTermsUI","termsConfig","RuleWidget","rulesAndTerms","LeaderboardPage","LeaderboardSection"],"mappings":"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","sourcesContent":["import React, { createContext, useContext, useMemo } from \"react\";\n\nexport type Campaign = {\n title: string;\n description: string;\n image: string;\n startTime: Date | string;\n endTime: Date | string;\n href:\n | string\n | {\n /** learn more url */\n learnMore: string;\n /** trading url, if provided, will override default trading now button url */\n trading: string;\n };\n};\n\n/**\n * Trading leaderboard provider state\n */\nexport type TradingLeaderboardState = {\n /** campaigns config, if not provided, will not show campaigns section */\n campaigns?: Campaign[];\n /** background src, it can be a image resource or video resource */\n backgroundSrc?: string;\n href?: {\n /** default trading now button url */\n trading: string;\n };\n};\n\n/**\n * Trading leaderboard context\n */\nexport const TradingLeaderboardContext = createContext<TradingLeaderboardState>(\n {},\n);\n\nexport type TradingLeaderboardProviderProps =\n React.PropsWithChildren<TradingLeaderboardState>;\n\nexport const TradingLeaderboardProvider: React.FC<\n Readonly<TradingLeaderboardProviderProps>\n> = (props) => {\n const { href, campaigns, backgroundSrc, children } = props;\n const memoizedValue = useMemo<TradingLeaderboardState>(() => {\n return {\n href: href,\n campaigns: campaigns,\n backgroundSrc: backgroundSrc,\n };\n }, [href, campaigns, backgroundSrc]);\n return (\n <TradingLeaderboardContext.Provider value={memoizedValue}>\n {children}\n </TradingLeaderboardContext.Provider>\n );\n};\n\nexport const useTradingLeaderboardContext = () => {\n return useContext(TradingLeaderboardContext);\n};\n","import { FC } from \"react\";\nimport { cn, Flex } from \"@orderly.network/ui\";\nimport { CampaignsWidget } from \"../../components/campaigns\";\nimport { TradingListWidget } from \"../../components/tradingList\";\nimport { LeaderboardScriptReturn } from \"./leaderboard.script\";\n\nexport type LeaderboardProps = {\n style?: React.CSSProperties;\n className?: string;\n} & LeaderboardScriptReturn;\n\nexport const MobileLeaderboardWidget: FC<LeaderboardProps> = (props) => {\n // const renderBackground = () => {\n // const linearGradient =\n // \"linear-gradient(180deg, rgba(var(--oui-color-base-10) / 0.3) 0%, rgba(var(--oui-color-base-10) / 0) 70%, rgba(var(--oui-color-base-10) / 1) 100%)\";\n\n // if (props.isVideo) {\n // return (\n // <div\n // className={cn(\"oui-absolute oui-left-0 oui-top-0\", \"oui-size-full\")}\n // >\n // <div\n // style={{\n // backgroundImage: linearGradient,\n // backgroundSize: \"cover\",\n // backgroundRepeat: \"no-repeat\",\n // }}\n // className={cn(\"oui-absolute oui-left-0 oui-top-0\", \"oui-size-full\")}\n // />\n // <video\n // playsInline\n // // eslint-disable-next-line react/no-unknown-property\n // webkit-playsinline // need to use this prop to ban full screen in iphone\n // autoPlay\n // loop\n // muted\n // className={cn(\n // // rest style\n // \"oui-pointer-events-none oui-border-none oui-bg-transparent oui-outline-none\",\n // \"oui-size-full\",\n // // \"oui-absolute oui-top-0 oui-left-0\",\n // \"oui-object-cover\",\n // \"oui-opacity-50\",\n // )}\n // // ref={(video) => {\n // // if (video) {\n // // video.setAttribute(\"playsinline\", \"true\");\n // // video.setAttribute(\"webkit-playsinline\", \"true\");\n // // }\n // // }}\n // >\n // <source src={props.backgroundSrc} type=\"video/mp4\" />\n // <source src={props.backgroundSrc} type=\"video/webm\" />\n // <source src={props.backgroundSrc} type=\"video/ogg\" />\n // <source src={props.backgroundSrc} type=\"video/avi\" />\n // Your browser does not support the video tag.\n // </video>\n // </div>\n // );\n // }\n\n // if (props.backgroundSrc) {\n // return (\n // <div\n // style={{\n // backgroundImage: `${linearGradient}, url(${props.backgroundSrc}) `,\n // backgroundSize: \"cover\",\n // backgroundRepeat: \"no-repeat\",\n // }}\n // className={cn(\n // \"oui-absolute oui-left-0 oui-top-0\",\n // \"oui-size-full\",\n // \"oui-opacity-50\",\n // )}\n // />\n // );\n // }\n // };\n return (\n <div\n style={{\n paddingBottom: \"calc(64px + env(safe-area-inset-bottom))\",\n }}\n className={cn(\n \"oui-relative oui-grid oui-h-[calc(100vh-44px)] oui-gap-1 oui-bg-base-10\",\n \"oui-mix-blend-screen\",\n props.className,\n )}\n >\n {/* {renderBackground()} */}\n <Flex\n direction=\"column\"\n gapY={3}\n height=\"100%\"\n px={3}\n pt={3}\n pb={3}\n className={cn(\n \"oui-trading-leaderboard-mobile oui-custom-scrollbar oui-overflow-y-auto\",\n \"oui-relative oui-h-[calc(100vh_-_64px)]\",\n )}\n >\n {props.showCampaigns && <CampaignsWidget />}\n <TradingListWidget />\n </Flex>\n </div>\n );\n};\n","import { FC } from \"react\";\nimport { useScreen } from \"@orderly.network/ui\";\nimport { MobileCampaigns } from \"./campaigns.mobile.ui\";\nimport { useCampaignsScript } from \"./campaigns.script\";\nimport { Campaigns } from \"./campaigns.ui\";\n\nexport type CampaignsWidgetProps = {\n className?: string;\n style?: React.CSSProperties;\n};\n\nexport const CampaignsWidget: FC<CampaignsWidgetProps> = (props) => {\n const state = useCampaignsScript();\n const { isMobile } = useScreen();\n\n if (isMobile) {\n return (\n <MobileCampaigns\n {...state}\n className={props.className}\n style={props.style}\n />\n );\n }\n return (\n <Campaigns {...state} className={props.className} style={props.style} />\n );\n};\n","import { FC } from \"react\";\nimport { useTranslation } from \"@orderly.network/i18n\";\nimport { cn, Box, Text, Flex, Button, Select } from \"@orderly.network/ui\";\nimport { CampaignsScriptReturn, CurrentCampaigns } from \"./campaigns.script\";\n\nexport type CampaignsProps = {\n className?: string;\n style?: React.CSSProperties;\n} & CampaignsScriptReturn;\n\nconst scrollIndicatorWidth = 25;\nconst scrollIndicatorHeight = 6;\n\nexport const MobileCampaigns: FC<CampaignsProps> = (props) => {\n if (props.currentCampaigns.length === 0) {\n return null;\n }\n\n return (\n <Box\n width=\"100%\"\n intensity={900}\n p={3}\n className={cn(\n \"oui-mobile-trading-leaderboard-campaigns oui-rounded-[20px]\",\n props.className,\n )}\n style={props.style}\n >\n <Header {...props} />\n <Box\n r=\"xl\"\n mt={3}\n ref={props.enableScroll ? props.emblaRef : undefined}\n className={cn(\n \"oui-w-full oui-min-w-0 oui-overflow-hidden\",\n \"oui-select-none oui-cursor-pointer\",\n )}\n >\n <Flex>\n {props.currentCampaigns.map((campaign) => {\n return <CampaignItem key={campaign.title} campaign={campaign} />;\n })}\n </Flex>\n </Box>\n {props.enableScroll && (\n <ScrollIndicator\n style={{\n width: scrollIndicatorWidth * props.currentCampaigns.length,\n }}\n list={props.currentCampaigns}\n scrollIndex={props.scrollIndex}\n scrollTo={props.emblaApi?.scrollTo}\n />\n )}\n </Box>\n );\n};\n\nconst Header: FC<CampaignsScriptReturn> = (props) => {\n const { t } = useTranslation();\n\n return (\n <Flex justify=\"between\" itemAlign=\"center\">\n <Text size=\"base\" intensity={80}>\n {t(\"tradingLeaderboard.campaigns\")}\n </Text>\n <Select.options\n size={\"xs\"}\n value={props.category}\n onValueChange={props.onCategoryChange}\n options={props.options}\n classNames={{\n // set the width of the trigger to the width of the content\n trigger: \"oui-w-[--radix-select-content-available-width]\",\n }}\n />\n </Flex>\n );\n};\n\nconst CampaignItem: FC<{ campaign: CurrentCampaigns }> = ({ campaign }) => {\n const { title, description, image, displayTime, learnMoreUrl, tradingUrl } =\n campaign;\n const { t } = useTranslation();\n\n return (\n <Box intensity={800} r=\"xl\" className=\"oui-flex-[0_0_100%]\">\n <img\n className=\"oui-w-full oui-h-[calc((100vw-48px)/2)] oui-rounded-t-xl oui-object-fill\"\n src={image}\n alt={title}\n />\n\n <Flex\n itemAlign=\"start\"\n justify=\"between\"\n direction=\"column\"\n height=\"100%\"\n p={4}\n gapY={3}\n className=\"oui-font-semibold\"\n >\n <Flex direction=\"column\" itemAlign=\"start\" gapY={1}>\n <Text size=\"sm\">{title}</Text>\n <Text size=\"2xs\" intensity={54}>\n {displayTime}\n </Text>\n <Text size=\"2xs\" intensity={36}>\n {description}\n </Text>\n </Flex>\n <Flex justify=\"between\" width=\"100%\" gapX={3}>\n <Button\n variant=\"outlined\"\n color=\"secondary\"\n fullWidth\n size=\"md\"\n onClick={() => {\n window.open(learnMoreUrl, \"_blank\");\n }}\n >\n {t(\"tradingLeaderboard.learnMore\")}\n </Button>\n <Button\n size=\"md\"\n fullWidth\n onClick={() => {\n window.open(tradingUrl, \"_self\");\n }}\n >\n {t(\"tradingLeaderboard.tradeNow\")}\n </Button>\n </Flex>\n </Flex>\n </Box>\n );\n};\n\ninterface ScrollIndicatorProps {\n style?: React.CSSProperties;\n list: CurrentCampaigns[];\n scrollIndex: number;\n scrollTo?: (index: number) => void;\n}\n\nconst ScrollIndicator: React.FC<ScrollIndicatorProps> = (props) => {\n const { style, scrollIndex, list } = props;\n\n return (\n <Flex\n mt={3}\n r=\"full\"\n height={scrollIndicatorHeight}\n className={cn(\"oui-bg-line oui-mx-auto oui-relative\")}\n style={props.style}\n >\n {list.map((item, index) => {\n return (\n <Box\n key={index}\n width={scrollIndicatorWidth}\n height={scrollIndicatorHeight}\n onClick={() => {\n props.scrollTo?.(index);\n }}\n r=\"full\"\n className=\"oui-cursor-pointer\"\n />\n );\n })}\n <Box\n width={scrollIndicatorWidth}\n height={scrollIndicatorHeight}\n r=\"full\"\n className={cn(\n \"oui-absolute oui-left-0 oui-top-0\",\n \"oui-transition-all oui-duration-300\",\n \"oui-bg-primary\",\n )}\n style={{\n transform: `translateX(${scrollIndex * scrollIndicatorWidth}px)`,\n }}\n />\n </Flex>\n );\n};\n","import { useEffect, useMemo, useState } from \"react\";\nimport useEmblaCarousel from \"embla-carousel-react\";\nimport { useTrack } from \"@orderly.network/hooks\";\nimport { useTranslation } from \"@orderly.network/i18n\";\nimport { TrackerEventName } from \"@orderly.network/types\";\nimport { formatCampaignDate } from \"../../../utils\";\nimport { useTradingLeaderboardContext, Campaign } from \"../provider\";\n\nexport type CampaignsScriptReturn = ReturnType<typeof useCampaignsScript>;\n\n// Define the type for our categorized campaigns\ntype CategorizedCampaigns = {\n ongoing: Campaign[];\n past: Campaign[];\n future: Campaign[];\n};\n\nexport type CurrentCampaigns = Campaign & {\n displayTime: string;\n learnMoreUrl: string;\n tradingUrl: string;\n};\n\nexport type TEmblaApi = {\n scrollTo?: (index: number) => void;\n};\n\ntype CategoryKey = keyof CategorizedCampaigns;\n\nexport function useCampaignsScript() {\n const { t } = useTranslation();\n const { campaigns = [], href } = useTradingLeaderboardContext();\n const [category, setCategory] = useState<CategoryKey>(\"ongoing\");\n\n const { track, tracking } = useTrack();\n\n const filterCampaigns = useMemo(() => {\n const now = new Date();\n\n return campaigns.reduce<CategorizedCampaigns>(\n (acc, campaign) => {\n const startTime = new Date(campaign.startTime);\n const endTime = new Date(campaign.endTime);\n\n if (now >= startTime && now <= endTime) {\n acc.ongoing.push(campaign);\n } else if (now > endTime) {\n acc.past.push(campaign);\n } else {\n acc.future.push(campaign);\n }\n\n return acc;\n },\n { ongoing: [], past: [], future: [] },\n );\n }, [campaigns]);\n\n const options = useMemo(() => {\n const opts: { label: string; value: CategoryKey }[] = [\n { label: t(\"tradingLeaderboard.ongoing\"), value: \"ongoing\" },\n { label: t(\"tradingLeaderboard.future\"), value: \"future\" },\n { label: t(\"tradingLeaderboard.past\"), value: \"past\" },\n ];\n\n // Filter out categories with no campaigns and map to the required format\n return opts.filter((item) => filterCampaigns[item.value].length > 0);\n }, [filterCampaigns, t]);\n\n const currentCampaigns = useMemo(() => {\n const list = filterCampaigns[category];\n return list.map((campaign) => {\n const { startTime, endTime } = campaign;\n\n let learnMoreUrl: string;\n let tradingUrl = href?.trading!;\n\n if (typeof campaign.href === \"object\") {\n learnMoreUrl = campaign.href.learnMore;\n tradingUrl = campaign.href.trading;\n } else {\n learnMoreUrl = campaign.href;\n }\n\n return {\n ...campaign,\n displayTime: `${formatCampaignDate(startTime)} - ${formatCampaignDate(\n endTime,\n )} UTC`,\n learnMoreUrl,\n tradingUrl,\n };\n });\n }, [filterCampaigns, category, href]);\n\n useEffect(() => {\n // Find the first non-empty category\n const categoryKeys: CategoryKey[] = [\"ongoing\", \"future\", \"past\"];\n\n const firstAvailableCategory = categoryKeys.find(\n (item) => filterCampaigns[item].length > 0,\n );\n\n if (firstAvailableCategory) {\n setCategory(firstAvailableCategory);\n }\n }, [filterCampaigns]);\n\n const onCategoryChange = (value: string) => {\n setCategory(value as CategoryKey);\n };\n const [scrollIndex, setScrollIndex] = useState(0);\n\n const [emblaRef, emblaApi] = useEmblaCarousel({\n loop: false,\n slidesToScroll: \"auto\",\n });\n\n useEffect(() => {\n emblaApi?.on(\"select\", () => {\n setScrollIndex(emblaApi?.selectedScrollSnap());\n });\n }, [emblaApi]);\n\n const onLearnMore = (campaign: CurrentCampaigns) => {\n track(TrackerEventName.leaderboardCampaignClickLearnMore, {\n campaign_title: campaign.title,\n });\n window.open(campaign.learnMoreUrl, \"_blank\");\n };\n\n const onTradeNow = (campaign: CurrentCampaigns) => {\n tracking(TrackerEventName.leaderboardCampaignClickTradeNow, {\n campaign_title: campaign.title,\n });\n window.open(campaign.tradingUrl, \"_self\");\n };\n\n return {\n options,\n currentCampaigns,\n category,\n onCategoryChange,\n tradingUrl: href?.trading,\n emblaRef,\n emblaApi: emblaApi as TEmblaApi,\n scrollIndex,\n enableScroll: currentCampaigns?.length > 1,\n onLearnMore,\n onTradeNow,\n };\n}\n","import { format, subDays } from \"date-fns\";\n\nexport const getDateRange = (offsetDay: number) => {\n return {\n from: subDays(new Date(), offsetDay - 1)!,\n to: new Date()!,\n };\n};\n\n/**\n * Format a date to \"yyyy-MM-dd\" format (e.g., \"2025-03-10\")\n * @param date The date to format\n * @returns Formatted date string\n */\nexport const formatDateRange = (date: Date): string => {\n return format(date, \"yyyy-MM-dd\");\n};\n\nfunction getUTCDateInfo(date: Date) {\n const year = date.getUTCFullYear();\n const month = date.getUTCMonth();\n const day = date.getUTCDate();\n const hours = String(date.getUTCHours()).padStart(2, \"0\");\n const minutes = String(date.getUTCMinutes()).padStart(2, \"0\");\n\n return { year, month, day, hours, minutes };\n}\n\nexport function formatCampaignDate(date: Date | string): string {\n const monthNames = [\n \"Jan\",\n \"Feb\",\n \"Mar\",\n \"Apr\",\n \"May\",\n \"Jun\",\n \"Jul\",\n \"Aug\",\n \"Sep\",\n \"Oct\",\n \"Nov\",\n \"Dec\",\n ];\n if (typeof date === \"string\") {\n date = new Date(date);\n }\n const { year, month, day, hours, minutes } = getUTCDateInfo(date);\n return `${monthNames[month]} ${day}, ${year} ${hours}:${minutes}`;\n}\n\nexport function formatUpdateDate(timestamp: number) {\n const time = new Date(timestamp);\n try {\n return format(time, \"yyyy-MM-dd HH:mm\");\n } catch (error) {\n console.error(\"Error formatting time:\", error);\n return \"\";\n }\n}\n","import { FC } from \"react\";\nimport { useTranslation } from \"@orderly.network/i18n\";\nimport { cn, Box, Text, Flex, Button, Select } from \"@orderly.network/ui\";\nimport { CampaignsScriptReturn, CurrentCampaigns } from \"./campaigns.script\";\n\nexport type CampaignsProps = {\n className?: string;\n style?: React.CSSProperties;\n} & CampaignsScriptReturn;\n\nexport const Campaigns: FC<CampaignsProps> = (props) => {\n if (props.currentCampaigns.length === 0) {\n return null;\n }\n\n return (\n <Box\n width=\"100%\"\n intensity={900}\n p={5}\n pr={2}\n height={288}\n className={cn(\n \"oui-trading-leaderboard-campaigns oui-rounded-[20px]\",\n props.className,\n )}\n style={props.style}\n >\n <Header {...props} />\n <Box\n mt={5}\n r=\"xl\"\n className={cn(\"oui-overflow-y-auto\", \"oui-custom-scrollbar\")}\n >\n <Flex\n gapY={5}\n height={200}\n direction=\"column\"\n r=\"xl\"\n className=\"oui-pr-1.5\"\n >\n {props.currentCampaigns.map((campaign) => {\n return (\n <CampaignItem\n key={campaign.title}\n campaign={campaign}\n onLearnMore={props.onLearnMore}\n onTradeNow={props.onTradeNow}\n />\n );\n })}\n </Flex>\n </Box>\n </Box>\n );\n};\n\nconst Header: FC<CampaignsScriptReturn> = (props) => {\n const { t } = useTranslation();\n return (\n <Flex justify=\"between\" itemAlign=\"center\" pr={3}>\n <Text size=\"xl\">{t(\"tradingLeaderboard.campaigns\")}</Text>\n <Select.options\n size={\"xs\"}\n value={props.category}\n onValueChange={props.onCategoryChange}\n options={props.options}\n classNames={{\n // set the width of the trigger to the width of the content\n trigger: \"oui-w-[--radix-select-content-available-width]\",\n }}\n />\n </Flex>\n );\n};\n\ntype CampaignItemProps = {\n campaign: CurrentCampaigns;\n onLearnMore: (campaign: CurrentCampaigns) => void;\n onTradeNow: (campaign: CurrentCampaigns) => void;\n};\n\nconst CampaignItem: FC<CampaignItemProps> = ({\n campaign,\n onLearnMore,\n onTradeNow,\n}) => {\n const { title, description, image, displayTime } = campaign;\n const { t } = useTranslation();\n\n return (\n <Flex intensity={800} r=\"xl\" width=\"100%\">\n <img\n className=\"oui-h-[200px] oui-w-[400px] oui-rounded-l-xl oui-object-fill\"\n src={image}\n alt={title}\n />\n\n <Flex\n itemAlign=\"start\"\n justify=\"between\"\n direction=\"column\"\n height=\"100%\"\n p={5}\n className=\"oui-flex-1 oui-font-semibold\"\n >\n <Flex gap={1} direction=\"column\" itemAlign=\"start\">\n <Text size=\"xl\">{title}</Text>\n <Text size=\"sm\" intensity={36}>\n {description}\n </Text>\n </Flex>\n <Flex justify=\"between\" width=\"100%\">\n <Text size=\"xs\" intensity={54}>\n {displayTime}\n </Text>\n <Flex gap={3}>\n <Button\n variant=\"outlined\"\n color=\"secondary\"\n size=\"md\"\n onClick={() => {\n onLearnMore(campaign);\n }}\n >\n {t(\"tradingLeaderboard.learnMore\")}\n </Button>\n <Button\n size=\"md\"\n onClick={() => {\n onTradeNow(campaign);\n }}\n >\n {t(\"tradingLeaderboard.tradeNow\")}\n </Button>\n </Flex>\n </Flex>\n </Flex>\n </Flex>\n );\n};\n","import { FC, SVGProps } from \"react\";\nimport { cn, DataFilter, DataTable, Flex, Spinner } from \"@orderly.network/ui\";\nimport { useTradingListColumns } from \"./column\";\nimport {\n getRowKey,\n TradingData,\n TradingListScriptReturn,\n} from \"./tradingList.script\";\n\nexport type TradingListProps = {\n style?: React.CSSProperties;\n className?: string;\n} & TradingListScriptReturn;\n\nexport const MobileTradingList: FC<TradingListProps> = (props) => {\n const column = useTradingListColumns(props.address);\n\n return (\n <Flex\n direction=\"column\"\n width=\"100%\"\n itemAlign=\"start\"\n intensity={900}\n r=\"2xl\"\n px={4}\n style={props.style}\n className={cn(\n \"oui-mobile-trading-leaderboard-trading-list\",\n props.className,\n )}\n >\n <Flex\n width=\"100%\"\n justify=\"between\"\n itemAlign=\"center\"\n className={cn(\"oui-mobile-trading-leaderboard-trading-filter\")}\n >\n {props.filterItems.length > 0 && (\n <DataFilter\n items={props.filterItems}\n onFilter={(value: any) => {\n props.onFilter(value);\n }}\n className=\"oui-h-[40px] oui-border-none\"\n />\n )}\n </Flex>\n\n <DataTable\n classNames={{\n root: \"oui-pb-4\",\n body: \"oui-text-2xs\",\n scroll: \"oui-overflow-y-hidden oui-h-full\",\n }}\n loading={props.isLoading}\n id=\"oui-trading-leaderboard-trading-table\"\n columns={column}\n initialSort={props.initialSort}\n onSort={props.onSort}\n dataSource={props.dataList}\n generatedRowKey={(record: TradingData) => record.key || record.address}\n manualPagination\n manualSorting\n onRow={(record, index) => {\n return {\n className: cn(\"oui-h-[30px]\"),\n };\n }}\n onCell={(column, record, index) => {\n if (record.key === getRowKey(props.address!)) {\n const isFirst = column.getIsFirstColumn();\n const isLast = column.getIsLastColumn();\n\n return {\n className: cn(\n \"after:oui-absolute after:oui-h-[30px] after:oui-w-full\",\n \"after:oui-border-[rgb(var(--oui-gradient-brand-start))]\",\n \" after:oui-left-0 after:oui-top-0 after:oui-z-[-1]\",\n \"after:oui-border-y\",\n isFirst && \"after:oui-rounded-l-lg after:oui-border-l\",\n isLast && \"after:oui-rounded-r-lg after:oui-border-r\",\n ),\n };\n }\n return {};\n }}\n />\n <div\n ref={props.sentinelRef}\n className=\"oui-invisible oui-relative oui-top-[-300px] oui-h-px\"\n />\n {props.isLoading && props.dataList.length > 0 && (\n <Flex itemAlign=\"center\" justify=\"center\" width=\"100%\" height={40}>\n <Spinner size=\"sm\" />\n </Flex>\n )}\n </Flex>\n );\n};\n\nexport const SearchIcon: FC<SVGProps<SVGSVGElement>> = (props) => (\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 14 14\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path d=\"M5.841 1.14a4.667 4.667 0 0 0 0 9.333 4.74 4.74 0 0 0 2.875-.975l2.54 2.56a.6.6 0 0 0 .838 0 .6.6 0 0 0 0-.838L9.537 8.677a4.72 4.72 0 0 0 .971-2.871 4.667 4.667 0 0 0-4.667-4.667m0 1.166a3.5 3.5 0 1 1 0 7 3.5 3.5 0 0 1 0-7\" />\n </svg>\n);\n","import { useMemo } from \"react\";\nimport { useTranslation } from \"@orderly.network/i18n\";\nimport { Text, Column, Box, useScreen } from \"@orderly.network/ui\";\nimport { getRowKey } from \"./tradingList.script\";\n\nexport const useTradingListColumns = (address?: string) => {\n const { t } = useTranslation();\n const { isMobile } = useScreen();\n\n return useMemo(() => {\n return [\n {\n title: t(\"tradingLeaderboard.rank\"),\n dataIndex: \"rank\",\n width: 40,\n render: (value: number) => {\n return (\n <Box width={20} className=\"oui-text-center\">\n {value}\n </Box>\n );\n },\n },\n {\n title: t(\"common.address\"),\n dataIndex: \"address\",\n render: (value: string, record: any) => {\n const isYou = record.key === getRowKey(address!);\n if (isMobile && isYou) {\n return <Text>You</Text>;\n }\n\n return (\n <>\n <Text.formatted rule=\"address\">{value}</Text.formatted>\n {isYou && <Text> (You)</Text>}\n </>\n );\n },\n width: 90,\n },\n {\n title: t(\"tradingLeaderboard.tradingVolume\"),\n dataIndex: \"perp_volume\",\n onSort: true,\n render: (value: string) => {\n if (!value) {\n return \"-\";\n }\n return (\n <Text.numeral prefix=\"$\" rule=\"price\" dp={2}>\n {value}\n </Text.numeral>\n );\n },\n width: 105,\n },\n {\n title: t(\"common.realizedPnl\"),\n dataIndex: \"realized_pnl\",\n onSort: true,\n align: isMobile ? \"right\" : \"left\",\n render: (value: string) => {\n if (!value) {\n return \"-\";\n }\n return (\n <Text.numeral prefix=\"$\" rule=\"price\" dp={2} coloring>\n {value}\n </Text.numeral>\n );\n },\n width: 90,\n },\n ] as Column[];\n }, [t, isMobile, address]);\n};\n","import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { differenceInDays } from \"date-fns\";\nimport {\n useAccount,\n useConfig,\n useInfiniteQuery,\n useQuery,\n usePrivateQuery,\n} from \"@orderly.network/hooks\";\nimport { API } from \"@orderly.network/types\";\nimport { TableSort, usePagination, useScreen } from \"@orderly.network/ui\";\nimport { useEndReached } from \"../../../hooks/useEndReached\";\nimport { getDateRange, formatDateRange } from \"../../../utils\";\n\nexport type TradingListScriptOptions = {};\n\nexport type TradingData = {\n account_id: string;\n address: string;\n broker_fee: number;\n date: string;\n perp_maker_volume: number;\n perp_taker_volume: number;\n perp_volume: number;\n total_fee: number;\n // custom field\n key?: string;\n};\n\nexport type TradingResponse = {\n meta: API.RecordsMeta;\n rows: TradingData[];\n};\nexport type TradingListScriptReturn = ReturnType<typeof useTradingListScript>;\n\nexport const FilterDays = [7, 14, 30, 90] as const;\nexport type TFilterDays = (typeof FilterDays)[number];\nexport type DateRange = {\n from?: Date;\n to?: Date;\n};\n\nexport function useTradingListScript() {\n const [searchValue, setSearchValue] = useState(\"\");\n const [initialSort] = useState<TableSort>({\n sortKey: \"perp_volume\",\n sort: \"desc\",\n });\n const [sort, setSort] = useState<TableSort | undefined>(initialSort);\n\n const { state } = useAccount();\n const brokerId = useConfig(\"brokerId\");\n\n const { isMobile } = useScreen();\n\n const { dateRange, filterDay, updateFilterDay, filterItems, onFilter } =\n useFilter();\n\n const { page, pageSize, setPage, parsePagination } = usePagination({\n pageSize: 100,\n });\n\n const getUrl = (args: {\n page: number;\n pageSize: number;\n address?: string;\n sort?: string | null;\n }) => {\n const searchParams = new URLSearchParams();\n\n searchParams.set(\"page\", args.page.toString());\n searchParams.set(\"size\", args.pageSize.toString());\n\n searchParams.set(\"aggregateBy\", \"address_per_builder\");\n\n if (brokerId) {\n searchParams.set(\"broker_id\", brokerId);\n }\n\n if (args.sort) {\n searchParams.set(\"sort\", args.sort);\n } else if (args.sort !== null && sort) {\n const prefix = sort.sort === \"asc\" ? \"ascending\" : \"descending\";\n searchParams.set(\"sort\", `${prefix}_${sort.sortKey}`);\n }\n\n if (dateRange.from) {\n searchParams.set(\"start_date\", formatDateRange(dateRange.from!));\n }\n\n if (dateRange.to) {\n searchParams.set(\"end_date\", formatDateRange(dateRange.to!));\n }\n\n if (args.address) {\n searchParams.set(\"address\", args.address);\n }\n\n return `/v1/broker/leaderboard/daily?${searchParams.toString()}`;\n };\n\n const { data, isLoading } = useQuery<TradingResponse>(\n getUrl({ page, pageSize, address: searchValue }),\n {\n formatter: (res) => res,\n revalidateOnFocus: false,\n },\n );\n\n const {\n data: infiniteData,\n size,\n setSize,\n isValidating,\n } = useInfiniteQuery<TradingResponse>(\n (pageIndex: number, previousPageData: any): string | null => {\n // reached the end\n if (previousPageData && !previousPageData.rows?.length) return null;\n\n if (!isMobile) {\n return null;\n }\n\n return getUrl({\n page: pageIndex + 1,\n pageSize,\n address: searchValue,\n });\n },\n {\n initialSize: 1,\n formatter: (res) => res,\n revalidateOnFocus: false,\n },\n );\n\n // it will use first page data cache\n const { data: top100Data } = useQuery<TradingResponse>(\n state.address\n ? getUrl({\n page: 1,\n pageSize: 100,\n sort: `descending_${sort?.sortKey || \"perp_volume\"}`,\n })\n : null,\n {\n formatter: (res) => res,\n revalidateOnFocus: false,\n },\n );\n\n const { data: userDataRes = [] } = usePrivateQuery<TradingData[]>(\n state.address\n ? getUrl({ page: 1, pageSize: 1, address: state.address, sort: null })\n : null,\n {\n revalidateOnFocus: false,\n },\n );\n\n const getAddressRank = useCallback(\n (address: string) => {\n const index = top100Data?.rows.findIndex((item) =>\n isSameAddress(item.address, address!),\n );\n return index !== -1 ? index! + 1 : \"100+\";\n },\n [top100Data],\n );\n\n const userDataList = useMemo(() => {\n if (!state.address || isLoading) {\n return [];\n }\n\n if (!userDataRes.length) {\n return [\n {\n key: getRowKey(state.address!),\n address: state.address,\n rank: \"-\",\n } as unknown as TradingData,\n ];\n }\n\n return userDataRes?.map((item) => ({\n ...item,\n rank: getAddressRank(item.address!),\n key: getRowKey(item.address!),\n }));\n }, [state.address, userDataRes, isLoading, getAddressRank]);\n\n const addRankForList = useCallback(\n (list: TradingData[], total: number) => {\n return list?.map((item, index) => {\n let rank: string | number = index + 1;\n\n if (searchValue) {\n rank = getAddressRank(item.address);\n } else {\n if (sort?.sort === \"asc\") {\n rank = total - (page - 1) * pageSize - index;\n } else if (sort?.sort === \"desc\") {\n rank = (page - 1) * pageSize + index + 1;\n }\n }\n\n return {\n ...item,\n rank,\n };\n });\n },\n [page, pageSize, sort, searchValue, getAddressRank],\n );\n\n const dataSource = useMemo(() => {\n const list = data?.rows || [];\n const total = data?.meta.total || 0;\n const rankList = addRankForList(list, total);\n if (page === 1 && !searchValue) {\n return [...userDataList, ...rankList];\n }\n return rankList;\n }, [data, page, userDataList, searchValue, addRankForList]);\n\n const dataList = useMemo(() => {\n if (!infiniteData?.length) {\n return [];\n }\n\n const total = infiniteData[0]?.meta.total || 0;\n const flatList = infiniteData?.map((item) => item.rows)?.flat();\n const rankList = addRankForList(flatList, total);\n\n if (!searchValue) {\n return [...userDataList, ...rankList];\n }\n\n return rankList;\n }, [infiniteData, userDataList, searchValue, addRankForList]);\n\n const sentinelRef = useRef<HTMLDivElement | null>(null);\n\n const pagination = useMemo(\n () => parsePagination(data?.meta),\n [parsePagination, data],\n );\n\n useEndReached(sentinelRef, () => {\n if (!isValidating && isMobile) {\n setSize(size + 1);\n }\n });\n\n const onSearchValueChange = (value: string) => {\n setSearchValue(value);\n };\n\n const clearSearchValue = useCallback(() => {\n setSearchValue(\"\");\n }, []);\n\n const onSort = useCallback(\n (sort?: TableSort) => {\n setSort(sort || initialSort);\n },\n [initialSort],\n );\n\n useEffect(() => {\n if (searchValue) {\n setPage(1);\n }\n }, [searchValue]);\n\n useEffect(() => {\n setPage(1);\n }, [state.address]);\n\n useEffect(() => {\n if (dateRange.to && dateRange.from) {\n setPage(1);\n }\n }, [dateRange]);\n\n return {\n pagination,\n dateRange,\n filterDay,\n updateFilterDay,\n filterItems,\n onFilter,\n initialSort,\n onSort,\n dataSource,\n isLoading: isLoading || isValidating,\n searchValue,\n onSearchValueChange,\n clearSearchValue,\n isMobile,\n sentinelRef,\n dataList,\n address: state.address,\n };\n}\n\nconst useFilter = () => {\n // default is 90d\n const [filterDay, setFilterDay] = useState<TFilterDays | null>(90);\n\n const [dateRange, setDateRange] = useState<DateRange>(getDateRange(90));\n\n const updateFilterDay = (day: TFilterDays) => {\n setFilterDay(day);\n setDateRange(getDateRange(day));\n };\n\n const onFilter = (filter: { name: string; value: any }) => {\n if (filter.name === \"dateRange\") {\n const newDateRange = filter.value;\n setDateRange(newDateRange);\n\n if (newDateRange.from && newDateRange.to) {\n const offsetDay =\n Math.abs(differenceInDays(newDateRange.from, newDateRange.to)) + 1;\n\n const dateRange = getDateRange(offsetDay);\n if (\n formatDateRange(dateRange.from) ===\n formatDateRange(newDateRange.from) &&\n formatDateRange(dateRange.to) === formatDateRange(newDateRange.to)\n ) {\n setFilterDay(offsetDay as any);\n } else {\n setFilterDay(null);\n }\n }\n }\n };\n\n const filterItems = useMemo(() => {\n const dateRangeFilter = {\n type: \"range\",\n name: \"dateRange\",\n value: dateRange,\n max: 90,\n };\n\n return [dateRangeFilter] as any;\n }, [dateRange]);\n\n return {\n filterItems,\n onFilter,\n dateRange,\n filterDay,\n updateFilterDay,\n };\n};\n\nexport function isSameAddress(address1: string, address2: string) {\n return address1.toLowerCase() === address2.toLowerCase();\n}\n\nexport function getRowKey(address: string) {\n return `current-address-${address?.toLowerCase()}`;\n}\n","import { useEffect, useRef, MutableRefObject } from \"react\";\n\n/**\n * Listen for the specified element to scroll to the bottom\n */\nexport function useEndReached(\n sentinelRef: MutableRefObject<HTMLDivElement | null>,\n onEndReached?: () => void\n) {\n const observer = useRef<IntersectionObserver>();\n const cb = useRef(onEndReached);\n\n cb.current = onEndReached;\n\n useEffect(() => {\n const options: IntersectionObserverInit = {\n root: null,\n rootMargin: \"0px\",\n threshold: 0,\n };\n\n const handleObserver = (entries: IntersectionObserverEntry[]) => {\n entries.forEach((entry) => {\n if (entry.isIntersecting) {\n cb.current?.();\n }\n });\n };\n\n observer.current = new IntersectionObserver(handleObserver, options);\n\n return () => {\n observer.current?.disconnect();\n };\n }, []);\n\n useEffect(() => {\n if (sentinelRef.current) {\n observer.current?.observe(sentinelRef.current);\n }\n }, [sentinelRef.current]);\n}\n","import { FC, SVGProps } from \"react\";\nimport { useTranslation } from \"@orderly.network/i18n\";\nimport {\n Box,\n CloseCircleFillIcon,\n cn,\n DataFilter,\n DataTable,\n Flex,\n Input,\n Text,\n} from \"@orderly.network/ui\";\nimport { useTradingListColumns } from \"./column\";\nimport {\n FilterDays,\n getRowKey,\n TradingData,\n TradingListScriptReturn,\n} from \"./tradingList.script\";\n\nexport type TradingListProps = {\n style?: React.CSSProperties;\n className?: string;\n} & TradingListScriptReturn;\n\nexport const TradingList: FC<TradingListProps> = (props) => {\n const column = useTradingListColumns(props.address);\n const { t } = useTranslation();\n\n return (\n <Flex\n direction=\"column\"\n width=\"100%\"\n itemAlign=\"start\"\n intensity={900}\n r=\"2xl\"\n px={4}\n style={props.style}\n className={cn(\"oui-trading-leaderboard-trading-list\", props.className)}\n >\n <Flex\n width=\"100%\"\n justify=\"between\"\n itemAlign=\"center\"\n mt={2}\n className={cn(\n \"oui-trading-leaderboard-trading-filter\",\n \"oui-border-b oui-border-line\",\n )}\n >\n <Flex gap={3}>\n {props.filterItems.length > 0 && (\n <DataFilter\n items={props.filterItems}\n onFilter={(value: any) => {\n props.onFilter(value);\n }}\n className=\"oui-h-[53px] oui-border-none\"\n />\n )}\n {FilterDays.map((value) => {\n return (\n <button\n className=\"oui-relative oui-px-2 oui-py-[2px] oui-text-sm\"\n key={value}\n >\n <div className=\"oui-z-10\">\n <Text.gradient\n color={props.filterDay === value ? \"brand\" : undefined}\n className={\n props.filterDay !== value\n ? \"oui-text-base-contrast-54\"\n : \"\"\n }\n >\n {`${value}D`}\n </Text.gradient>\n </div>\n <div\n className=\"oui-absolute oui-inset-0 oui-rounded oui-opacity-[.12] oui-gradient-primary\"\n onClick={() => {\n props.updateFilterDay(value as any);\n }}\n ></div>\n </button>\n );\n })}\n </Flex>\n <Input\n value={props.searchValue}\n onValueChange={props.onSearchValueChange}\n placeholder={t(\"common.address.search.placeholder\")}\n className={cn(\n \"oui-trading-leaderboard-trading-search-input\",\n \"oui-w-[240px]\",\n )}\n size=\"sm\"\n prefix={\n <Box pl={3} pr={1}>\n <SearchIcon className=\"oui-text-base-contrast-36\" />\n </Box>\n }\n suffix={\n props.searchValue && (\n <Box mr={2}>\n <CloseCircleFillIcon\n size={14}\n className=\"oui-cursor-pointer oui-text-base-contrast-36\"\n onClick={props.clearSearchValue}\n />\n </Box>\n )\n }\n autoComplete=\"off\"\n />\n </Flex>\n\n <DataTable\n loading={props.isLoading}\n id=\"oui-trading-leaderboard-trading-table\"\n columns={column}\n initialSort={props.initialSort}\n onSort={props.onSort}\n bordered\n dataSource={props.dataSource}\n generatedRowKey={(record: TradingData) => record.key || record.address}\n manualPagination\n manualSorting\n pagination={props.pagination}\n classNames={{\n root: \"!oui-h-[calc(100%_-_53px_-_8px)]\",\n }}\n onRow={(record, index) => {\n return {\n className: cn(\"oui-h-[48px]\"),\n };\n }}\n onCell={(column, record, index) => {\n if (record.key === getRowKey(props.address!)) {\n const isFirst = column.getIsFirstColumn();\n const isLast = column.getIsLastColumn();\n\n return {\n className: cn(\n \"after:oui-absolute after:oui-h-[48px] after:oui-w-full\",\n \"after:oui-border-[rgb(var(--oui-gradient-brand-start))]\",\n \"after:oui-left-0 after:oui-top-0 after:oui-z-[-1]\",\n \"after:oui-border-y\",\n isFirst && \"after:oui-rounded-l-lg after:oui-border-l\",\n isLast && \"after:oui-rounded-r-lg after:oui-border-r\",\n ),\n };\n }\n return {};\n }}\n />\n </Flex>\n );\n};\n\nexport const SearchIcon: FC<SVGProps<SVGSVGElement>> = (props) => (\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 14 14\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path d=\"M5.841 1.14a4.667 4.667 0 0 0 0 9.333 4.74 4.74 0 0 0 2.875-.975l2.54 2.56a.6.6 0 0 0 .838 0 .6.6 0 0 0 0-.838L9.537 8.677a4.72 4.72 0 0 0 .971-2.871 4.667 4.667 0 0 0-4.667-4.667m0 1.166a3.5 3.5 0 1 1 0 7 3.5 3.5 0 0 1 0-7\" />\n </svg>\n);\n","import { FC } from \"react\";\nimport { MobileTradingList } from \"./tradingList.mobile.ui\";\nimport { useTradingListScript } from \"./tradingList.script\";\nimport { TradingList, TradingListProps } from \"./tradingList.ui\";\n\nexport type TradingListWidgetProps = Pick<\n TradingListProps,\n \"style\" | \"className\"\n>;\n\n/**\n * @deprecated use TradingListPage instead\n * it will be removed in next version\n */\nexport const TradingListWidget: FC<TradingListWidgetProps> = (props) => {\n const state = useTradingListScript();\n if (state.isMobile) {\n return <MobileTradingList {...state} {...props} />;\n }\n return <TradingList {...state} {...props} />;\n};\n","import { useMemo } from \"react\";\nimport { useScreen } from \"@orderly.network/ui\";\nimport { Campaign } from \"../../components/provider\";\n\nexport type LeaderboardScriptReturn = ReturnType<typeof useLeaderboardScript>;\n\nexport type LeaderboardScriptOptions = {\n backgroundSrc?: string;\n campaigns?: Campaign[];\n};\n\nfunction isVideoSrc(src?: string) {\n const extension = src?.split(\".\").pop();\n return [\"mp4\", \"webm\", \"avi\", \"ogg\"].includes(extension ?? \"\");\n}\n\nexport function useLeaderboardScript(options: LeaderboardScriptOptions) {\n const { backgroundSrc, campaigns = [] } = options;\n const { isMobile } = useScreen();\n\n const showCampaigns = useMemo(() => campaigns?.length > 0, [campaigns]);\n\n const isVideo = useMemo(() => {\n return isVideoSrc(backgroundSrc);\n }, [backgroundSrc]);\n\n return {\n backgroundSrc,\n isVideo,\n showCampaigns,\n isMobile,\n };\n}\n","import { FC } from \"react\";\nimport { cn, Flex } from \"@orderly.network/ui\";\nimport { CampaignsWidget } from \"../../components/campaigns\";\nimport { TradingListWidget } from \"../../components/tradingList\";\nimport { LeaderboardScriptReturn } from \"./leaderboard.script\";\n\nexport type LeaderboardProps = {\n style?: React.CSSProperties;\n className?: string;\n} & LeaderboardScriptReturn;\n\nexport const Leaderboard: FC<LeaderboardProps> = (props) => {\n const renderBackground = () => {\n const linearGradient =\n \"linear-gradient(180deg, rgba(var(--oui-color-base-10) / 0.3) 0%, rgba(var(--oui-color-base-10) / 0) 70%, rgba(var(--oui-color-base-10) / 1) 100%)\";\n\n if (props.isVideo) {\n return (\n <div\n className={cn(\n \"oui-absolute oui-top-0 oui-left-0\",\n \"oui-w-full oui-h-full\",\n )}\n >\n <div\n style={{\n backgroundImage: linearGradient,\n backgroundSize: \"cover\",\n backgroundRepeat: \"no-repeat\",\n }}\n className={cn(\n \"oui-absolute oui-top-0 oui-left-0\",\n \"oui-w-full oui-h-full\",\n )}\n />\n <video\n autoPlay\n loop\n muted\n className={cn(\n // rest style\n \"oui-border-none oui-outline-none oui-bg-transparent\",\n \"oui-w-full oui-h-full\",\n // \"oui-absolute oui-top-0 oui-left-0\",\n \"oui-object-cover\",\n \"oui-opacity-50\",\n )}\n >\n <source src={props.backgroundSrc} type=\"video/mp4\" />\n <source src={props.backgroundSrc} type=\"video/webm\" />\n <source src={props.backgroundSrc} type=\"video/ogg\" />\n <source src={props.backgroundSrc} type=\"video/avi\" />\n Your browser does not support the video tag.\n </video>\n </div>\n );\n }\n\n if (props.backgroundSrc) {\n return (\n <div\n style={{\n backgroundImage: `${linearGradient}, url(${props.backgroundSrc}) `,\n backgroundSize: \"cover\",\n backgroundRepeat: \"no-repeat\",\n }}\n className={cn(\n \"oui-absolute oui-top-0 oui-left-0\",\n \"oui-w-full oui-h-full\",\n \"oui-opacity-50\",\n )}\n />\n );\n }\n };\n\n return (\n <div\n style={props.style}\n className={cn(\"oui-h-full oui-mix-blend-screen\", props.className)}\n >\n {renderBackground()}\n <Flex\n direction=\"column\"\n gapY={5}\n height=\"100%\"\n className={cn(\n \"oui-trading-leaderboard oui-relative\",\n \"oui-max-w-[1040px] oui-px-3 oui-mx-auto \",\n )}\n >\n {props.showCampaigns && <CampaignsWidget />}\n <TradingListWidget\n className={cn(\n props.showCampaigns\n ? \"oui-h-[calc(100%_-_288px_-_20px)]\"\n : \"oui-h-full\",\n )}\n />\n </Flex>\n </div>\n );\n};\n","import { FC } from \"react\";\nimport {\n TradingLeaderboardProvider,\n TradingLeaderboardProviderProps,\n} from \"../../components/provider\";\nimport { MobileLeaderboardWidget } from \"./leaderboard.mobile.ui\";\nimport { useLeaderboardScript } from \"./leaderboard.script\";\nimport { Leaderboard, LeaderboardProps } from \"./leaderboard.ui\";\n\nexport type LeaderboardWidgetProps = TradingLeaderboardProviderProps &\n Pick<LeaderboardProps, \"style\" | \"className\">;\n\n/**\n * @deprecated use LeaderboardPage instead\n * it will be removed in next version\n */\nexport const LeaderboardWidget: FC<LeaderboardWidgetProps> = (props) => {\n const state = useLeaderboardScript({\n backgroundSrc: props.backgroundSrc,\n campaigns: props.campaigns,\n });\n\n return (\n <TradingLeaderboardProvider campaigns={props.campaigns} href={props.href}>\n {state.isMobile ? (\n <MobileLeaderboardWidget {...state} />\n ) : (\n <Leaderboard\n {...state}\n className={props.className}\n style={props.style}\n />\n )}\n </TradingLeaderboardProvider>\n );\n};\n","import React, {\n createContext,\n useContext,\n useMemo,\n useState,\n useEffect,\n} from \"react\";\nimport { parseISO } from \"date-fns\";\nimport { sortWith, descend } from \"ramda\";\nimport {\n usePrivateQuery,\n RefferalAPI as API,\n useMemoizedFn,\n} from \"@orderly.network/hooks\";\nimport { CampaignConfig, UserData } from \"../campaigns/type\";\n\n/**\n * Trading leaderboard provider state\n */\nexport type TradingLeaderboardState = {\n /** campaigns config, if not provided, will not show campaigns section */\n campaigns?: CampaignConfig[];\n /** background src, it can be a image resource or video resource */\n backgroundSrc?: string;\n href?: {\n /** default trading now button url */\n trading: string;\n };\n currentCampaignId: string | number;\n currentCampaign?: CampaignConfig;\n onCampaignChange: (campaignId: string | number) => void;\n /** leaderboard user data, it will be used to calculate the rewards */\n userData?: UserData;\n /** set leaderboard user data */\n setUserData?: (userdata: UserData) => void;\n /** campaign ranking list updated time */\n updatedTime?: number;\n /** set snapshot time */\n setUpdatedTime?: (updatedTime?: number) => void;\n /** custom data, if use this, you can full control the data */\n dataAdapter?: (info: { page: number; pageSize: number }) => {\n loading: boolean;\n dataSource?: any[];\n dataList?: any[];\n userData?: any;\n updatedTime?: number;\n meta?: {\n total: number;\n current_page: number;\n records_per_page: number;\n };\n };\n};\n\n/**\n * Trading leaderboard context\n */\nexport const TradingLeaderboardContext = createContext<TradingLeaderboardState>(\n {} as TradingLeaderboardState,\n);\n\nexport type TradingLeaderboardProviderProps = Pick<\n TradingLeaderboardState,\n \"campaigns\" | \"href\" | \"backgroundSrc\" | \"dataAdapter\"\n> & {\n campaignId?: string | number;\n onCampaignChange?: (campaignId: string | number) => void;\n};\n\nexport const TradingLeaderboardProvider: React.FC<\n React.PropsWithChildren<TradingLeaderboardProviderProps>\n> = (props) => {\n const {\n campaignId,\n campaigns,\n backgroundSrc,\n href,\n children,\n dataAdapter,\n onCampaignChange,\n } = props;\n\n const [userData, setUserData] = useState<UserData>();\n const [updatedTime, setUpdatedTime] = useState<number>();\n\n const { data: generateCode, mutate: generateCodeMutate } = usePrivateQuery(\n \"/v1/referral/info\",\n {\n revalidateOnFocus: false,\n errorRetryCount: 2,\n formatter: (data) => {\n return {\n code: data?.referee_info?.referer_code || \"\",\n };\n },\n },\n );\n\n useEffect(() => {\n if (generateCode?.code && userData?.referral_code != generateCode.code) {\n setUserData({ ...userData!, referral_code: generateCode.code });\n generateCodeMutate();\n }\n }, [userData, generateCode, generateCodeMutate]);\n\n const currentCampaign = useMemo(() => {\n return campaigns?.find((campaign) => campaign.campaign_id == campaignId);\n }, [campaigns, campaignId]);\n\n const filteredCampaigns = useMemo(() => {\n // const filtered = campaigns?.filter((campaign) => {\n // // return true;\n // // Campaign without referral_codes is visible to all users\n // if (!campaign.referral_codes) {\n // return true;\n // }\n // return campaign.referral_codes?.includes(userData?.referral_code || \"\");\n // });\n\n // Using date-fns to parse date strings and sort by end_time in descending order\n return campaigns\n ? sortWith(\n [descend((campaign: CampaignConfig) => parseISO(campaign.end_time))],\n campaigns,\n )\n : campaigns;\n }, [campaigns]);\n\n const memoCampaignChange = useMemoizedFn((id: string | number) => {\n onCampaignChange?.(id);\n });\n\n const memoizedValue = useMemo<TradingLeaderboardState>(() => {\n return {\n campaigns: filteredCampaigns,\n href: href,\n backgroundSrc: backgroundSrc,\n currentCampaignId: campaignId || \"general\",\n currentCampaign,\n updatedTime,\n userData,\n setUserData,\n onCampaignChange: memoCampaignChange,\n setUpdatedTime: setUpdatedTime,\n dataAdapter: dataAdapter,\n };\n }, [\n backgroundSrc,\n currentCampaign,\n campaignId,\n filteredCampaigns,\n href,\n updatedTime,\n userData,\n dataAdapter,\n memoCampaignChange,\n ]);\n\n return (\n <TradingLeaderboardContext.Provider value={memoizedValue}>\n {children}\n </TradingLeaderboardContext.Provider>\n );\n};\n\nexport const useTradingLeaderboardContext = () => {\n const ctx = useContext<TradingLeaderboardState>(TradingLeaderboardContext);\n return ctx;\n};\n","import { FC, useCallback } from \"react\";\nimport {\n cn,\n DataTable,\n Flex,\n Spinner,\n TanstackColumn,\n useScreen,\n} from \"@orderly.network/ui\";\nimport { type CampaignRankingData } from \"../campaignRanking/campaignRanking.script\";\nimport {\n type GeneralRankingData,\n GeneralRankingScriptReturn,\n} from \"../generalRanking/generalRanking.script\";\nimport { type RankingColumnFields, useRankingColumns } from \"./column\";\nimport { getCurrentAddressRowKey } from \"./util\";\n\ntype RankingData = GeneralRankingData | CampaignRankingData;\n\nexport type RankingProps = {\n style?: React.CSSProperties;\n className?: string;\n fields: RankingColumnFields[];\n} & Omit<GeneralRankingScriptReturn, \"dataList\" | \"dataSource\"> & {\n dataList: RankingData[];\n dataSource: RankingData[];\n };\n\nexport const Ranking: FC<RankingProps> = (props) => {\n const column = useRankingColumns(\n props.fields,\n props.address,\n typeof props.onSort === \"function\",\n );\n const { isMobile } = useScreen();\n\n const onRow = useCallback(\n (record: RankingData, index: number) => {\n const isYou = record.key === getCurrentAddressRowKey(props.address!);\n const isFirst = record.rank === 1;\n const isSecond = record.rank === 2;\n const isThird = record.rank === 3;\n\n const showBg = isFirst || isSecond || isThird;\n\n return {\n className: cn(\n \"oui-h-[40px] md:oui-h-[48px]\",\n // use oui-relative to let the background image position based on row\n \"oui-relative\",\n isYou\n ? // add 4px extra height to make row has 2px space\n \"oui-h-[44px] md:oui-h-[52px]\"\n : cn(\n showBg && \"oui-border-b-2 oui-border-b-transparent\",\n isFirst &&\n \"oui-bg-[linear-gradient(270deg,rgba(241,215,121,0.0225)_-2.05%,rgba(255,203,70,0.45)_100%)]\",\n isSecond &&\n \"oui-bg-[linear-gradient(270deg,rgba(255,255,255,0.0225)_-2.05%,rgba(199,199,199,0.45)_100%)]\",\n isThird &&\n \"oui-bg-[linear-gradient(270deg,rgba(255,233,157,0.0225)_-1.3%,rgba(160,101,46,0.45)_100%)]\",\n ),\n ),\n };\n },\n [props.address],\n );\n\n const onCell = useCallback(\n (\n column: TanstackColumn<RankingData>,\n record: RankingData,\n index: number,\n ) => {\n const isFirstColumn = column.getIsFirstColumn();\n const isLastColumn = column.getIsLastColumn();\n const isRank = [1, 2, 3].includes(record.rank as number);\n if (record.key === getCurrentAddressRowKey(props.address!)) {\n return {\n className: cn(\n \"after:oui-absolute after:oui-h-[40px] after:oui-w-full md:after:oui-h-[48px]\",\n \"after:oui-border-[rgb(var(--oui-gradient-brand-start))]\",\n \"after:oui-left-0 after:oui-top-[2px] after:oui-z-[-1]\",\n \"after:oui-border-y\",\n isFirstColumn && \"after:oui-rounded-l-lg after:oui-border-l\",\n isLastColumn && \"after:oui-rounded-r-lg after:oui-border-r\",\n ),\n };\n }\n return {\n className: cn(\n isFirstColumn &&\n isRank &&\n \"oui-rounded-l-lg oui-mix-blend-luminosity\",\n isLastColumn && isRank && \"oui-rounded-r-lg oui-mix-blend-luminosity\",\n ),\n // style: isRank\n // ? {\n // position: \"unset\",\n // }\n // : undefined,\n };\n },\n [props.address],\n );\n\n if (isMobile) {\n return (\n <>\n <DataTable\n classNames={{\n root: \"oui-trading-leaderboard-ranking-table\",\n body: \"oui-text-2xs\",\n scroll: \"oui-overflow-y-hidden oui-h-full\",\n }}\n loading={props.isLoading}\n columns={column}\n bordered\n initialSort={props.initialSort}\n onSort={props.onSort}\n dataSource={props.dataList}\n generatedRowKey={(record: RankingData) =>\n record.key || record.address\n }\n manualPagination\n manualSorting\n onRow={onRow}\n onCell={onCell}\n />\n <div\n ref={props.sentinelRef}\n className=\"oui-invisible oui-relative oui-top-[-300px] oui-h-px\"\n />\n {props.isLoading && props.dataList.length > 0 && (\n <Flex itemAlign=\"center\" justify=\"center\" width=\"100%\" height={40}>\n <Spinner size=\"sm\" />\n </Flex>\n )}\n </>\n );\n }\n\n return (\n <DataTable\n loading={props.isLoading}\n columns={column}\n initialSort={props.initialSort}\n onSort={props.onSort}\n bordered\n dataSource={props.dataSource}\n generatedRowKey={(record: RankingData) => record.key || record.address}\n manualPagination\n manualSorting\n pagination={props.pagination}\n classNames={{\n root: cn(\n \"oui-trading-leaderboard-ranking-table\",\n \"!oui-h-[calc(100%_-_53px_-_8px)]\",\n ),\n scroll: \"oui-min-h-[600px]\",\n }}\n onRow={onRow}\n onCell={onCell}\n />\n );\n};\n","import { ReactNode, useMemo } from \"react\";\nimport { useTranslation } from \"@orderly.network/i18n\";\nimport { Text, Column, Box, useScreen, cn } from \"@orderly.network/ui\";\nimport firstBadge from \"../../../img/first_badge.png\";\nimport secondBadge from \"../../../img/second_badge.png\";\nimport thirdBadge from \"../../../img/third_badge.png\";\nimport { getCurrentAddressRowKey } from \"./util\";\n\nexport type RankingColumnFields =\n | \"rank\"\n | \"address\"\n | \"volume\"\n | \"pnl\"\n | \"rewards\";\n\nexport const useRankingColumns = (\n fields?: RankingColumnFields[],\n address?: string,\n enableSort?: boolean,\n) => {\n const { t } = useTranslation();\n const { isMobile } = useScreen();\n\n return useMemo(() => {\n const columns = [\n {\n title: t(\"tradingLeaderboard.rank\"),\n dataIndex: \"rank\",\n width: 50,\n render: (value: number, record: any) => {\n const isYou = record.key === getCurrentAddressRowKey(address!);\n\n let rankIcon: ReactNode;\n let badgeImg: ReactNode = null;\n\n if (!isYou) {\n if (value === 1) {\n rankIcon = <FirstRankIcon />;\n badgeImg = firstBadge;\n } else if (value === 2) {\n rankIcon = <SecondRankIcon />;\n badgeImg = secondBadge;\n } else if (value === 3) {\n rankIcon = <ThirdRankIcon />;\n badgeImg = thirdBadge;\n }\n }\n\n return (\n <>\n {badgeImg && (\n <img\n src={badgeImg as string}\n alt={`${value}th badge`}\n className={cn(\n \"oui-z-0 oui-h-[38px] oui-opacity-30 md:oui-h-[46px]\",\n \"oui-absolute oui-left-0 oui-top-0\",\n \"oui-mix-blend-luminosity\",\n // force create a separate layer in order to fix mix-blend-luminosity not working on ios\n \"oui-transform-gpu\",\n )}\n />\n )}\n <div className=\"oui-relative\">\n {rankIcon || (\n <Box width={20} pl={2} className=\"oui-text-center\">\n {value}\n </Box>\n )}\n </div>\n </>\n );\n },\n },\n {\n title: t(\"common.address\"),\n dataIndex: \"address\",\n render: (value: string, record: any) => {\n const isYou = record.key === getCurrentAddressRowKey(address!);\n if (isMobile && isYou) {\n return <Text>You</Text>;\n }\n\n let linearGradientText;\n\n if (!isYou) {\n if (record.rank === 1) {\n linearGradientText =\n \"linear-gradient(169deg, #FBE67B 2.09%, #FCFBE7 15.8%, #F7D14E 40.73%, #D4A041 58.8%)\";\n } else if (record.rank === 2) {\n linearGradientText =\n \"linear-gradient(201.05deg, #D9D9D9 38.79%, #F7F6F4 53.85%, #D9D9D9 71.71%, #7F7F7F 91.87%), rgba(255, 255, 255, 0.8)\";\n } else if (record.rank === 3) {\n linearGradientText =\n \"linear-gradient(149.05deg, #B6947E 15.63%, #F8DAC8 31.37%, #B6947E 44.29%, #F8DCCB 56.6%), rgba(255, 255, 255, 0.8)\";\n }\n }\n\n return (\n <>\n <Text.formatted\n rule=\"address\"\n key={record.rank}\n style={\n linearGradientText\n ? {\n background: linearGradientText,\n WebkitBackgroundClip: \"text\",\n WebkitTextFillColor: \"transparent\",\n backgroundClip: \"text\",\n }\n : {}\n }\n >\n {value}\n </Text.formatted>\n {isYou && <Text> (You)</Text>}\n </>\n );\n },\n width: 90,\n },\n {\n title: t(\"tradingLeaderboard.tradingVolume\"),\n dataIndex: \"volume\",\n onSort: enableSort,\n align: isMobile ? \"right\" : \"left\",\n render: (value: string) => {\n if (!value) {\n return \"-\";\n }\n return (\n <Text.numeral prefix=\"$\" rule=\"price\" dp={2}>\n {value}\n </Text.numeral>\n );\n },\n width: 105,\n },\n {\n title: t(\"common.realizedPnl\"),\n dataIndex: \"pnl\",\n onSort: enableSort,\n align: isMobile ? \"right\" : \"left\",\n render: (value: string) => {\n if (!value) {\n return \"-\";\n }\n return (\n <Text.numeral prefix=\"$\" rule=\"price\" dp={2} coloring>\n {value}\n </Text.numeral>\n );\n },\n width: 90,\n },\n {\n title: t(\"tradingLeaderboard.estimatedRewards\"),\n dataIndex: \"rewards\",\n align: isMobile ? \"right\" : \"left\",\n render: (value: { amount: number; currency: string }) => {\n if (!value) {\n return \"-\";\n }\n return (\n <Text.numeral\n suffix={` ${value?.currency || \"\"}`}\n rule=\"price\"\n dp={0}\n >\n {value?.amount}\n </Text.numeral>\n );\n },\n width: 90,\n },\n ] as Column[];\n\n return columns.filter((column) =>\n fields?.includes(column.dataIndex as RankingColumnFields),\n );\n }, [t, isMobile, address, fields, enableSort]);\n};\n\nconst FirstRankIcon = () => {\n return (\n <svg\n width=\"25\"\n height=\"25\"\n viewBox=\"0 0 25 25\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M3.88281 2.5L7.78711 10.3105C6.38111 11.5855 5.5 13.427 5.5 15.5C5.5 19.4 8.6 22.5 12.5 22.5C16.4 22.5 19.5 19.4 19.5 15.5C19.5 13.427 18.6189 11.5855 17.2129 10.3105L21.1172 2.5H15.5L12.5 8.5L9.5 2.5H3.88281ZM12.5 10.5C15.3 10.5 17.5 12.7 17.5 15.5C17.5 18.3 15.3 20.5 12.5 20.5C9.7 20.5 7.5 18.3 7.5 15.5C7.5 12.7 9.7 10.5 12.5 10.5ZM12.5 12.5C12.4 12.8 11.9 13.6992 11 13.6992V14.6992H12.0996V18.5H13.4004H13.5V12.5H12.5Z\"\n fill=\"url(#paint0_linear_21940_39199)\"\n />\n <defs>\n <linearGradient\n id=\"paint0_linear_21940_39199\"\n x1=\"6.18073\"\n y1=\"6\"\n x2=\"20.1338\"\n y2=\"18.1659\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#8C421D\" />\n <stop offset=\"0.325272\" stopColor=\"#FBE67B\" />\n <stop offset=\"0.535488\" stopColor=\"#FCFBE7\" />\n <stop offset=\"0.769917\" stopColor=\"#F7D14E\" />\n <stop offset=\"1\" stopColor=\"#D4A041\" />\n </linearGradient>\n </defs>\n </svg>\n );\n};\n\nconst SecondRankIcon = () => {\n return (\n <svg\n width=\"25\"\n height=\"25\"\n viewBox=\"0 0 25 25\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M3.88281 2.5L7.78711 10.3105C6.38111 11.5855 5.5 13.427 5.5 15.5C5.5 19.4 8.6 22.5 12.5 22.5C16.4 22.5 19.5 19.4 19.5 15.5C19.5 13.427 18.6189 11.5855 17.2129 10.3105L21.1172 2.5H15.5L12.5 8.5L9.5 2.5H3.88281ZM12.5 10.5C15.3 10.5 17.5 12.7 17.5 15.5C17.5 18.3 15.3 20.5 12.5 20.5C9.7 20.5 7.5 18.3 7.5 15.5C7.5 12.7 9.7 10.5 12.5 10.5ZM12.5469 12.5C10.7729 12.5 10.481 13.901 10.5 14.5H11.6738C11.6738 14.357 11.809 13.5 12.5 13.5C13.163 13.5 13.291 14.0232 13.291 14.2852C13.291 15.0512 12.245 15.7623 10.5 17.6973V18.5L14.4883 18.4766L14.4863 17.5332H12.2285C13.8425 15.8792 14.5 15.1309 14.5 14.1719C14.5 13.4869 14.1149 12.5 12.5469 12.5Z\"\n fill=\"url(#paint0_linear_21940_39214)\"\n />\n <defs>\n <linearGradient\n id=\"paint0_linear_21940_39214\"\n x1=\"6.18073\"\n y1=\"6\"\n x2=\"20.1338\"\n y2=\"18.1659\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#7F7F7F\" />\n <stop offset=\"0.325272\" stopColor=\"#D9D9D9\" />\n <stop offset=\"0.535488\" stopColor=\"#F7F6F4\" />\n <stop offset=\"0.769917\" stopColor=\"#D9D9D9\" />\n <stop offset=\"1\" stopColor=\"#7F7F7F\" />\n </linearGradient>\n </defs>\n </svg>\n );\n};\n\nconst ThirdRankIcon = () => {\n return (\n <svg\n width=\"29\"\n height=\"25\"\n viewBox=\"0 0 29 25\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M5.88281 2.5L9.78711 10.3105C8.38111 11.5855 7.5 13.427 7.5 15.5C7.5 19.4 10.6 22.5 14.5 22.5C18.4 22.5 21.5 19.4 21.5 15.5C21.5 13.427 20.6189 11.5855 19.2129 10.3105L23.1172 2.5H17.5L14.5 8.5L11.5 2.5H5.88281ZM14.5 10.5C17.3 10.5 19.5 12.7 19.5 15.5C19.5 18.3 17.3 20.5 14.5 20.5C11.7 20.5 9.5 18.3 9.5 15.5C9.5 12.7 11.7 10.5 14.5 10.5ZM14.4688 12.5C13.6927 12.5 12.5898 12.9348 12.5898 14.0918H13.7266C13.7266 13.9118 13.8461 13.4336 14.4941 13.4336C14.6251 13.4336 15.2715 13.4767 15.2715 14.1797C15.2715 14.8967 14.7109 14.9844 14.4219 14.9844H13.8145V15.8906H14.4219C14.5659 15.8906 15.3613 15.8537 15.3613 16.7637C15.3613 16.8837 15.3111 17.5625 14.4961 17.5625C13.8081 17.5625 13.6233 17.0284 13.6562 16.8164H12.5195C12.4615 17.4334 12.9757 18.4961 14.4688 18.4961C15.3018 18.4961 16.5 18.0942 16.5 16.7812C16.5 15.8643 15.8621 15.536 15.5391 15.418C15.6781 15.354 16.4082 14.9771 16.4082 14.1641C16.4082 13.7131 16.2127 12.5 14.4688 12.5Z\"\n fill=\"url(#paint0_linear_21940_39224)\"\n />\n <defs>\n <linearGradient\n id=\"paint0_linear_21940_39224\"\n x1=\"8.61159\"\n y1=\"5.33333\"\n x2=\"22.7368\"\n y2=\"20.4383\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#B6947E\" />\n <stop offset=\"0.2\" stopColor=\"#8F6959\" />\n <stop offset=\"0.475\" stopColor=\"#F8DAC8\" />\n <stop offset=\"0.67\" stopColor=\"#AC836E\" />\n <stop offset=\"0.83\" stopColor=\"#B6947E\" />\n <stop offset=\"1\" stopColor=\"#F8DCCB\" />\n </linearGradient>\n </defs>\n </svg>\n );\n};\n","export function isSameAddress(address1: string, address2: string) {\n return address1.toLowerCase() === address2.toLowerCase();\n}\n\nexport function getCurrentAddressRowKey(address: string) {\n return `current-address-${address?.toLowerCase()}`;\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n useAccount,\n useConfig,\n useInfiniteQuery,\n useQuery,\n} from \"@orderly.network/hooks\";\nimport { API } from \"@orderly.network/types\";\nimport { TableSort, usePagination, useScreen } from \"@orderly.network/ui\";\nimport { useEndReached } from \"../../../hooks/useEndReached\";\nimport { DateRange } from \"../../../type\";\nimport { formatDateRange, getDateRange } from \"../../../utils\";\nimport { getCurrentAddressRowKey, isSameAddress } from \"../shared/util\";\n\nexport type GeneralRankingData = {\n account_id: string;\n address: string;\n broker_fee: number;\n date: string;\n perp_maker_volume: number;\n perp_taker_volume: number;\n perp_volume: number;\n realized_pnl: number;\n total_fee: number;\n\n // custom field\n key?: string;\n rank?: number | string;\n volume?: number;\n pnl?: number;\n};\n\nexport type GeneralRankingResponse = {\n meta: API.RecordsMeta;\n rows: GeneralRankingData[];\n};\nexport type GeneralRankingScriptReturn = ReturnType<\n typeof useGeneralRankingScript\n>;\n\nexport type GeneralRankingScriptOptions = {\n dateRange?: DateRange;\n address?: string;\n sortKey?: \"perp_volume\" | \"realized_pnl\";\n};\n\nexport function useGeneralRankingScript(options?: GeneralRankingScriptOptions) {\n const {\n dateRange = getDateRange(90),\n address: searchValue,\n sortKey = \"perp_volume\",\n } = options || {};\n\n const [initialSort] = useState<TableSort>({\n sortKey,\n sort: \"desc\",\n });\n\n const [sort, setSort] = useState<TableSort | undefined>(initialSort);\n\n const { state } = useAccount();\n const brokerId = useConfig(\"brokerId\");\n\n const { isMobile } = useScreen();\n\n const { page, pageSize, setPage, parsePagination } = usePagination({\n pageSize: isMobile ? 100 : 20,\n });\n\n const getUrl = (args: {\n page: number;\n pageSize: number;\n address?: string;\n sort?: string | null;\n }) => {\n const searchParams = new URLSearchParams();\n\n searchParams.set(\"page\", args.page.toString());\n searchParams.set(\n \"size\",\n // if page is 1, we need to set page size to 100 to get the top 100 data to judge user rank\n args.page === 1 ? \"100\" : args.pageSize.toString(),\n );\n searchParams.set(\"aggregateBy\", \"address_per_builder\");\n\n if (brokerId) {\n searchParams.set(\"broker_id\", brokerId);\n }\n\n if (args.sort) {\n searchParams.set(\"sort\", args.sort);\n } else if (args.sort !== null && sort) {\n const prefix = sort.sort === \"asc\" ? \"ascending\" : \"descending\";\n searchParams.set(\"sort\", `${prefix}_${sort.sortKey}`);\n }\n\n if (dateRange?.from) {\n searchParams.set(\"start_date\", formatDateRange(dateRange.from!));\n }\n\n if (dateRange?.to) {\n searchParams.set(\"end_date\", formatDateRange(dateRange.to!));\n }\n\n if (args.address) {\n searchParams.set(\"address\", args.address);\n }\n\n // https://orderly.network/docs/build-on-omnichain/evm-api/restful-api/private/get-builders-leaderboard\n return `/v1/broker/leaderboard/daily?${searchParams.toString()}`;\n };\n\n const { data, isLoading } = useQuery<GeneralRankingResponse>(\n getUrl({ page, pageSize, address: searchValue }),\n {\n formatter: (res) => res,\n revalidateOnFocus: false,\n },\n );\n\n const {\n data: infiniteData,\n size,\n setSize,\n isValidating,\n } = useInfiniteQuery<GeneralRankingResponse>(\n (pageIndex: number, previousPageData: any): string | null => {\n // reached the end\n if (previousPageData && !previousPageData.rows?.length) return null;\n\n if (!isMobile) {\n return null;\n }\n\n return getUrl({\n page: pageIndex + 1,\n pageSize,\n address: searchValue,\n });\n },\n {\n initialSize: 1,\n formatter: (res) => res,\n revalidateOnFocus: false,\n },\n );\n\n // it will use first page data cache\n const { data: top100Data } = useQuery<GeneralRankingResponse>(\n state.address\n ? getUrl({\n page: 1,\n pageSize: 100,\n sort: `descending_${sort?.sortKey || \"perp_volume\"}`,\n })\n : null,\n {\n formatter: (res) => res,\n revalidateOnFocus: false,\n },\n );\n\n const { data: userDataRes = [] } = useQuery<GeneralRankingData[]>(\n state.address\n ? getUrl({ page: 1, pageSize: 1, address: state.address, sort: null })\n : null,\n {\n revalidateOnFocus: false,\n },\n );\n\n const getAddressRank = useCallback(\n (address: string) => {\n const index = top100Data?.rows.findIndex((item) =>\n isSameAddress(item.address, address!),\n );\n return index !== -1 ? index! + 1 : \"100+\";\n },\n [top100Data],\n );\n\n const userDataList = useMemo(() => {\n if (!state.address || isLoading) {\n return [];\n }\n\n if (!userDataRes.length) {\n return [\n {\n key: getCurrentAddressRowKey(state.address!),\n address: state.address,\n rank: \"-\",\n } as unknown as GeneralRankingData,\n ];\n }\n\n return userDataRes?.map((item) => ({\n ...item,\n rank: getAddressRank(item.address!),\n key: getCurrentAddressRowKey(item.address!),\n }));\n }, [state.address, userDataRes, isLoading, getAddressRank]);\n\n const addRankForList = useCallback(\n (list: GeneralRankingData[], total: number) => {\n return list?.map((item, index) => {\n let rank: string | number = index + 1;\n\n if (searchValue) {\n rank = getAddressRank(item.address);\n } else {\n if (sort?.sort === \"asc\") {\n rank = total - (page - 1) * pageSize - index;\n } else if (sort?.sort === \"desc\") {\n rank = (page - 1) * pageSize + index + 1;\n }\n }\n\n return {\n ...item,\n rank,\n };\n });\n },\n [page, pageSize, sort, searchValue, getAddressRank],\n );\n\n const dataSource = useMemo(() => {\n let list = data?.rows || [];\n if (page === 1) {\n list = list.slice(0, pageSize);\n }\n const total = data?.meta.total || 0;\n const rankList = addRankForList(list, total);\n\n if (page === 1 && !searchValue) {\n return formatData([...userDataList, ...rankList]);\n }\n return formatData(rankList);\n }, [data, page, pageSize, userDataList, searchValue, addRankForList]);\n\n const dataList = useMemo(() => {\n if (!infiniteData?.length) {\n return [];\n }\n\n const total = infiniteData[0]?.meta.total || 0;\n const flatList = infiniteData?.map((item) => item.rows)?.flat();\n const rankList = addRankForList(flatList, total);\n\n if (!searchValue) {\n return formatData([...userDataList, ...rankList]);\n }\n return formatData(rankList);\n }, [infiniteData, userDataList, searchValue, addRankForList]);\n\n const sentinelRef = useRef<HTMLDivElement | null>(null);\n\n const pagination = useMemo(\n () =>\n parsePagination({\n total: data?.meta?.total || 0,\n current_page: data?.meta?.current_page || 1,\n records_per_page: pageSize,\n }),\n [data?.meta?.total, data?.meta?.current_page, pageSize],\n );\n\n useEndReached(sentinelRef, () => {\n if (!isValidating && isMobile) {\n setSize(size + 1);\n }\n });\n\n const onSort = useCallback(\n (sort?: TableSort) => {\n // befause table column dataIndex is not the same as the api sort, so we need to map the sortKey\n if (sort?.sortKey === \"volume\") {\n sort.sortKey = \"perp_volume\";\n } else if (sort?.sortKey === \"pnl\") {\n sort.sortKey = \"realized_pnl\";\n }\n setSort(sort || initialSort);\n },\n [initialSort],\n );\n\n useEffect(() => {\n if (searchValue) {\n setPage(1);\n }\n }, [searchValue]);\n\n useEffect(() => {\n setPage(1);\n }, [state.address]);\n\n useEffect(() => {\n if (dateRange?.to && dateRange?.from) {\n setPage(1);\n }\n }, [dateRange]);\n\n useEffect(() => {\n setSort({ sortKey, sort: \"desc\" });\n }, [sortKey]);\n\n return {\n pagination,\n initialSort,\n onSort,\n dataSource,\n isLoading: isLoading || isValidating,\n isMobile,\n sentinelRef,\n dataList,\n address: state.address,\n };\n}\n\nfunction formatData(data: any[]) {\n return data.map((item) => ({\n ...item,\n volume: item.perp_volume,\n pnl: item.realized_pnl,\n }));\n}\n","import { FC } from \"react\";\nimport { Ranking, RankingProps } from \"../shared/ranking.ui\";\nimport {\n GeneralRankingScriptOptions,\n useGeneralRankingScript,\n} from \"./generalRanking.script\";\n\nexport type GeneralRankingWidgetProps = Pick<\n RankingProps,\n \"style\" | \"className\" | \"fields\"\n> &\n GeneralRankingScriptOptions;\n\nexport const GeneralRankingWidget: FC<GeneralRankingWidgetProps> = (props) => {\n const { dateRange, address, fields, sortKey, ...rest } = props;\n const state = useGeneralRankingScript({\n dateRange,\n address,\n sortKey,\n });\n\n return <Ranking {...state} {...rest} fields={fields} />;\n};\n","import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n useAccount,\n useConfig,\n useInfiniteQuery,\n useQuery,\n} from \"@orderly.network/hooks\";\nimport { API } from \"@orderly.network/types\";\nimport { TableSort, usePagination, useScreen } from \"@orderly.network/ui\";\nimport { useEndReached } from \"../../../hooks/useEndReached\";\nimport { CampaignConfig, UserData } from \"../../campaigns/type\";\nimport { useTradingLeaderboardContext } from \"../../provider\";\nimport { calculateUserPoolReward } from \"../../rewards/utils\";\nimport { getCurrentAddressRowKey, isSameAddress } from \"../shared/util\";\n\nexport type CampaignRankingData = {\n broker_id: string;\n account_id: string;\n address: string;\n volume: number;\n pnl: number;\n total_deposit_amount: number;\n total_withdrawal_amount: number;\n start_account_value: number;\n end_account_value: number;\n\n // custom field\n key?: string;\n rank?: number | string;\n rewards?: {\n amount: number;\n currency: string;\n };\n};\n\ntype CampaignRankingResponse = {\n meta: API.RecordsMeta;\n rows: CampaignRankingData[];\n updated_time: number;\n};\nexport type CampaignRankingScriptReturn = ReturnType<\n typeof useCampaignRankingScript\n>;\n\nexport type CampaignRankingScriptOptions = {\n campaignId: number | string;\n sortKey?: \"volume\" | \"pnl\";\n};\n\nexport function useCampaignRankingScript(\n options: CampaignRankingScriptOptions,\n) {\n const { campaignId, sortKey = \"volume\" } = options;\n const [initialSort] = useState<TableSort>({\n sortKey,\n sort: \"desc\",\n });\n const [sort, setSort] = useState<TableSort | undefined>(initialSort);\n\n const { currentCampaign, setUserData, setUpdatedTime, dataAdapter } =\n useTradingLeaderboardContext();\n\n const { state } = useAccount();\n const brokerId = useConfig(\"brokerId\");\n\n const { isMobile } = useScreen();\n\n const { page, pageSize, setPage, parsePagination } = usePagination({\n pageSize: isMobile ? 100 : 20,\n });\n\n const isCustomData = typeof dataAdapter === \"function\";\n\n const customData = useMemo(() => {\n if (typeof dataAdapter === \"function\") {\n return dataAdapter({ page, pageSize });\n }\n }, [dataAdapter, page, pageSize]);\n\n const getUrl = (args: {\n page: number;\n pageSize: number;\n sort?: string | null;\n }) => {\n if (isCustomData) {\n return null;\n }\n const searchParams = new URLSearchParams();\n\n searchParams.set(\"page\", args.page.toString());\n searchParams.set(\n \"size\",\n // if page is 1, we need to set page size to 100 to get the top 100 data to judge user rank\n args.page === 1 ? \"100\" : args.pageSize.toString(),\n );\n\n if (campaignId) {\n searchParams.set(\"campaign_id\", campaignId.toString());\n }\n\n if (brokerId) {\n searchParams.set(\"broker_id\", brokerId);\n }\n\n if (args.sort) {\n searchParams.set(\"sort_by\", args.sort);\n } else if (args.sort !== null && sort) {\n searchParams.set(\"sort_by\", sort.sortKey);\n }\n\n // https://orderly.network/docs/build-on-omnichain/evm-api/restful-api/public/get-campaign-ranking\n // only get prod ranking data\n return `https://api.orderly.org/v1/public/campaign/ranking?${searchParams.toString()}`;\n };\n\n const { data, isLoading } = useQuery<CampaignRankingResponse>(\n getUrl({ page, pageSize }),\n {\n formatter: (res) => res,\n revalidateOnFocus: false,\n },\n );\n\n const {\n data: infiniteData,\n size,\n setSize,\n isValidating,\n } = useInfiniteQuery<CampaignRankingResponse>(\n (pageIndex: number, previousPageData: any): string | null => {\n // reached the end\n if (previousPageData && !previousPageData.rows?.length) return null;\n\n if (!isMobile) {\n return null;\n }\n\n return getUrl({\n page: pageIndex + 1,\n pageSize,\n });\n },\n {\n initialSize: 1,\n formatter: (res) => res,\n revalidateOnFocus: false,\n },\n );\n\n // it will use first page data cache\n const { data: top100Data } = useQuery<CampaignRankingResponse>(\n state.address\n ? getUrl({\n page: 1,\n pageSize: 100,\n // sort: \"desc\",\n })\n : null,\n {\n formatter: (res) => res,\n revalidateOnFocus: false,\n },\n );\n\n const getUserUrl = () => {\n if (!state.address || !campaignId || isCustomData) {\n return null;\n }\n\n const searchParams = new URLSearchParams();\n\n if (brokerId) {\n searchParams.set(\"broker_id\", brokerId);\n }\n\n searchParams.set(\"campaign_id\", campaignId.toString());\n searchParams.set(\"address\", state.address!);\n\n // https://orderly.network/docs/build-on-omnichain/evm-api/restful-api/public/get-campaign-user-info\n // only get prod user data\n return `https://api.orderly.org/v1/public/campaign/user?${searchParams.toString()}`;\n };\n\n const { data: userDataRes } = useQuery<CampaignRankingData[]>(getUserUrl(), {\n revalidateOnFocus: false,\n });\n\n const getAddressRank = useCallback(\n (address: string) => {\n if (top100Data?.rows?.length === 0) {\n return \"-\";\n }\n\n const index = top100Data?.rows.findIndex((item) =>\n isSameAddress(item.address, address!),\n );\n return index !== -1 ? index! + 1 : \"100+\";\n },\n [top100Data],\n );\n\n const userData = useMemo(() => {\n if (customData) {\n return customData?.userData;\n }\n\n if (!state.address || isLoading) {\n return undefined;\n }\n\n if (!userDataRes) {\n return {\n key: getCurrentAddressRowKey(state.address!),\n address: state.address,\n rank: \"-\",\n } as unknown as CampaignRankingData;\n }\n\n return {\n ...userDataRes,\n address: state.address,\n rank: getAddressRank(state.address!),\n key: getCurrentAddressRowKey(state.address!),\n };\n }, [state.address, userDataRes, isLoading, getAddressRank, customData]);\n\n const addRankForList = useCallback(\n (list: CampaignRankingData[], total: number) => {\n return list?.map((item, index) => {\n let rank: string | number = index + 1;\n\n if (sort?.sort === \"asc\") {\n rank = total - (page - 1) * pageSize - index;\n } else if (sort?.sort === \"desc\") {\n rank = (page - 1) * pageSize + index + 1;\n }\n\n return {\n ...item,\n rank,\n };\n });\n },\n [page, pageSize, sort],\n );\n\n const dataSource = useMemo(() => {\n if (customData) {\n return formatData(customData?.dataSource, currentCampaign, sortKey);\n }\n\n let list = data?.rows || [];\n if (page === 1) {\n list = list.slice(0, pageSize);\n }\n const total = data?.meta.total || 0;\n const rankList = addRankForList(list, total);\n\n const _data =\n page === 1 ? (userData ? [userData, ...rankList] : rankList) : rankList;\n\n return formatData(_data, currentCampaign, sortKey);\n }, [\n data,\n page,\n pageSize,\n userData,\n addRankForList,\n currentCampaign,\n sortKey,\n customData,\n ]);\n\n const dataList = useMemo(() => {\n if (customData) {\n return formatData(customData?.dataList, currentCampaign, sortKey);\n }\n\n if (!infiniteData?.length) {\n return [];\n }\n\n const total = infiniteData[0]?.meta.total || 0;\n const flatList = infiniteData?.map((item) => item.rows)?.flat();\n const rankList = addRankForList(flatList, total);\n\n const _data = userData ? [userData, ...rankList] : rankList;\n\n return formatData(_data, currentCampaign, sortKey);\n }, [\n infiniteData,\n userData,\n addRankForList,\n currentCampaign,\n sortKey,\n customData,\n ]);\n\n const sentinelRef = useRef<HTMLDivElement | null>(null);\n\n const pagination = useMemo(\n () =>\n parsePagination({\n total: customData?.meta?.total || data?.meta?.total || 0,\n current_page:\n customData?.meta?.current_page || data?.meta?.current_page || 1,\n records_per_page: pageSize,\n }),\n [\n data?.meta?.total,\n data?.meta?.current_page,\n pageSize,\n parsePagination,\n customData,\n ],\n );\n\n useEndReached(sentinelRef, () => {\n if (!isValidating && isMobile) {\n setSize(size + 1);\n }\n });\n\n useEffect(() => {\n setPage(1);\n }, [state.address]);\n\n useEffect(() => {\n if (userData) {\n setUserData?.(userData as any);\n }\n }, [userData]);\n\n useEffect(() => {\n const time = customData?.updatedTime || data?.updated_time || 0;\n setUpdatedTime?.(time);\n // when currentCampaign changed, we need to reset the campaign ranking list updated time\n }, [data, currentCampaign, customData]);\n\n useEffect(() => {\n setSort({ sortKey, sort: \"desc\" });\n }, [sortKey]);\n\n return {\n pagination,\n initialSort,\n dataSource,\n isLoading: isLoading || isValidating || customData?.loading,\n isMobile,\n sentinelRef,\n dataList,\n address: state.address,\n };\n}\n\nfunction formatData(\n data?: any[],\n currentCampaign?: CampaignConfig,\n metric?: \"volume\" | \"pnl\",\n) {\n const pool = currentCampaign?.prize_pools?.find(\n (item) => item.metric === metric,\n );\n\n return data?.map((item) => {\n const rewards = pool ? calculateUserPoolReward(item as UserData, pool!) : 0;\n\n return {\n ...item,\n rewards: {\n amount: rewards,\n currency: pool?.currency,\n },\n };\n });\n}\n","import {\n TicketTierRule,\n TicketLinearRule,\n TicketRules,\n CampaignConfig,\n UserData,\n PrizePool,\n} from \"../campaigns/type\";\n\n/**\n * Get user metric value based on pool metric type\n */\nfunction getUserMetricValue(\n userdata: UserData,\n metric: \"volume\" | \"pnl\",\n): number {\n return metric === \"volume\" ? userdata.volume : userdata.pnl;\n}\n\n/**\n * Estimate user's rank based on current performance\n */\nfunction estimateUserRank(\n userdata: UserData,\n metric: \"volume\" | \"pnl\",\n): number | null {\n // If we have actual rank data, use it\n if (userdata.rank) {\n return Number(userdata.rank);\n }\n\n // Otherwise, make a simple estimation based on performance\n const userMetricValue = getUserMetricValue(userdata, metric);\n const totalParticipants = userdata.total_participants || 1000;\n\n if (userMetricValue <= 0) return null;\n\n // Simple heuristic: assume better performance means better rank\n // In reality, you would compare against actual leaderboard data\n if (userMetricValue >= 100000) return 1;\n if (userMetricValue >= 50000) return Math.floor(totalParticipants * 0.05); // Top 5%\n if (userMetricValue >= 10000) return Math.floor(totalParticipants * 0.2); // Top 20%\n if (userMetricValue >= 1000) return Math.floor(totalParticipants * 0.5); // Top 50%\n\n return Math.floor(totalParticipants * 0.8); // Bottom 80%\n}\n\n/**\n * Find reward amount for user based on estimated rank in a specific pool\n */\nfunction findRewardInPool(userdata: UserData, pool: PrizePool): number {\n const userMetricValue = getUserMetricValue(userdata, pool.metric);\n\n // Skip if user has no relevant data\n if (userMetricValue <= 0) return 0;\n\n const estimatedRank = estimateUserRank(userdata, pool.metric);\n if (estimatedRank === null) return 0;\n\n // Find matching tier based on estimated rank\n for (const tier of pool.tiers) {\n let isInTier = false;\n\n if (tier.position && estimatedRank === tier.position) {\n isInTier = true;\n } else if (tier.position_range) {\n const [start, end] = tier.position_range;\n if (estimatedRank >= start && estimatedRank <= end) {\n isInTier = true;\n }\n }\n\n if (isInTier) {\n return tier.amount;\n }\n }\n\n return 0;\n}\n\n/**\n * Calculate estimated rewards based on user's current performance and campaign configuration\n * @param userdata User's current trading data\n * @param campaign Campaign configuration\n * @returns Estimated reward amount with currency\n */\nexport function calculateEstimatedRewards(\n userdata: UserData,\n campaign: CampaignConfig,\n): { amount: number; currency: string } | null {\n if (!campaign.prize_pools || campaign.prize_pools.length === 0) {\n return null;\n }\n\n let totalEstimatedReward = 0;\n const mainCurrency = campaign.prize_pools[0].currency;\n\n // Only sum rewards from pools with the same currency to avoid mixing different currencies\n for (const pool of campaign.prize_pools) {\n totalEstimatedReward += findRewardInPool(userdata, pool);\n }\n\n return totalEstimatedReward > 0\n ? { amount: totalEstimatedReward, currency: mainCurrency }\n : null;\n}\n\n/**\n * Calculate estimated tickets earned based on user's trading performance\n * @param userdata User's current trading data\n * @param ticketRules Ticket configuration rules\n * @returns Estimated number of tickets\n */\nexport function calculateEstimatedTickets(\n userdata: UserData,\n ticketRules: TicketRules,\n): number {\n const userMetricValue =\n ticketRules.metric === \"volume\" ? userdata.volume : userdata.pnl;\n\n if (!userMetricValue) return 0;\n\n if (userMetricValue <= 0) return 0;\n\n if (ticketRules.mode === \"tiered\") {\n return calculateTieredTickets(userMetricValue, ticketRules.tiers || []);\n } else if (ticketRules.mode === \"linear\") {\n return calculateLinearTickets(userMetricValue, ticketRules.linear);\n }\n\n return 0;\n}\n\n/**\n * Calculate tickets using tiered mode\n * ≥ 25,000 volume → 10 tickets\n * ≥ 10,000 and < 25,000 → 5 tickets\n * ≥ 5,000 and < 10,000 → 1 ticket\n * < 5,000 → 0 tickets\n */\nfunction calculateTieredTickets(\n metricValue: number,\n tiers: TicketTierRule[],\n): number {\n // Sort tiers by value in descending order\n const sortedTiers = [...tiers].sort((a, b) => b.value - a.value);\n\n for (const tier of sortedTiers) {\n if (metricValue >= tier.value) {\n return tier.tickets;\n }\n }\n\n return 0;\n}\n\n/**\n * Calculate tickets using linear mode\n * Get X ticket for every Y volume/pnl\n */\nfunction calculateLinearTickets(\n metricValue: number,\n linearRule?: TicketLinearRule,\n): number {\n if (!linearRule || linearRule.every <= 0) return 0;\n\n const multiplier = Math.floor(metricValue / linearRule.every);\n return multiplier * linearRule.tickets;\n}\n\n/**\n * Format reward amount with currency for display\n */\nexport function formatRewardAmount(amount: number, currency: string): string {\n return `${amount.toLocaleString()} ${currency}`;\n}\n\n/**\n * Format ticket count for display\n */\nexport function formatTicketCount(tickets: number): string {\n return tickets.toLocaleString();\n}\n\n/**\n * Calculate user's estimated reward for a specific prize pool\n * @param userdata User's current trading data\n * @param pool Specific prize pool\n * @returns Estimated reward amount for this pool, or 0 if not eligible\n */\nexport function calculateUserPoolReward(\n userdata: UserData,\n pool: PrizePool,\n): number {\n return findRewardInPool(userdata, pool);\n}\n\n/**\n * Calculate progress percentage and next tier requirements for tickets\n * @param userdata User's current trading data\n * @param ticketRules Ticket configuration rules\n * @returns Object containing progress percentage and next tier requirements\n */\nexport function calculateTicketProgress(\n userdata: UserData,\n ticketRules: TicketRules,\n): { percent: number; value: number; atMax?: boolean } | null {\n if (!userdata || !ticketRules) return null;\n\n const userMetricValue = getUserMetricValue(userdata, ticketRules.metric);\n\n if (!userMetricValue) {\n if (ticketRules.mode === \"linear\") {\n return {\n percent: 0,\n value: ticketRules.linear?.every || 0,\n };\n } else {\n return {\n percent: 0,\n value: ticketRules.tiers?.[0]?.value || 0,\n };\n }\n }\n\n if (ticketRules.mode === \"linear\") {\n if (!ticketRules.linear) return null;\n\n const { every, tickets } = ticketRules.linear;\n const currentTier = Math.floor(userMetricValue / every);\n const nextTier = currentTier + 1;\n const progress = ((userMetricValue % every) / every) * 100;\n const nextTierValue = nextTier * every;\n\n return {\n percent: progress,\n value: nextTierValue - userMetricValue,\n };\n }\n\n if (ticketRules.mode === \"tiered\" && ticketRules.tiers) {\n const sortedTiers = [...ticketRules.tiers].sort(\n (a, b) => a.value - b.value,\n );\n\n // Check if tiers array is empty\n if (sortedTiers.length === 0) {\n return null;\n }\n\n // Special case: if user metric value is 0 or negative, show progress to first tier\n if (userMetricValue <= 0) {\n return {\n percent: 0,\n value: sortedTiers[0].value,\n };\n }\n\n // Find current tier and next tier\n let currentTier = null;\n let nextTier = sortedTiers[0]; // Default next tier is the first one\n\n for (let i = 0; i < sortedTiers.length; i++) {\n if (userMetricValue >= sortedTiers[i].value) {\n currentTier = sortedTiers[i];\n nextTier = sortedTiers[i + 1] || null; // Next tier or null if at max\n } else {\n // User hasn't reached this tier yet, so this is the next tier\n nextTier = sortedTiers[i];\n break;\n }\n }\n\n if (!nextTier) {\n return {\n percent: 100,\n value: 0,\n atMax: true,\n };\n }\n\n // If user hasn't reached any tier yet, calculate progress to first tier\n if (!currentTier) {\n const progress = (userMetricValue / nextTier.value) * 100;\n return {\n percent: progress,\n value: nextTier.value - userMetricValue,\n };\n }\n\n const progress =\n ((userMetricValue - currentTier.value) /\n (nextTier.value - currentTier.value)) *\n 100;\n\n return {\n percent: progress,\n value: nextTier.value - userMetricValue,\n };\n }\n\n return null;\n}\n","import { FC } from \"react\";\nimport { Ranking, RankingProps } from \"../shared/ranking.ui\";\nimport {\n CampaignRankingScriptOptions,\n useCampaignRankingScript,\n} from \"./campaignRanking.script\";\n\nexport type CampaignRankingWidgetProps = Pick<\n RankingProps,\n \"style\" | \"className\" | \"fields\"\n> &\n CampaignRankingScriptOptions;\n\nexport const CampaignRankingWidget: FC<CampaignRankingWidgetProps> = (\n props,\n) => {\n const { campaignId, fields, sortKey, ...rest } = props;\n const state = useCampaignRankingScript({\n campaignId,\n sortKey,\n });\n\n // @ts-ignore\n return <Ranking {...state} {...rest} fields={fields} />;\n};\n","import { useCallback, useMemo, useState } from \"react\";\nimport { differenceInDays } from \"date-fns\";\nimport { DateRange, LeaderboardTab } from \"../../../type\";\nimport { formatDateRange, getDateRange } from \"../../../utils\";\n\nexport type GeneralLeaderboardScriptReturn = ReturnType<\n typeof useGeneralLeaderboardScript\n>;\n\nexport const FilterDays = [7, 14, 30, 90] as const;\nexport type TFilterDays = (typeof FilterDays)[number];\n\nexport function useGeneralLeaderboardScript() {\n const [activeTab, setActiveTab] = useState<LeaderboardTab>(\n LeaderboardTab.Volume,\n );\n const filterState = useFilter();\n const searchState = useSearch();\n\n return {\n ...filterState,\n ...searchState,\n activeTab,\n onTabChange: setActiveTab,\n };\n}\n\nfunction useFilter() {\n // default is 90d\n const [filterDay, setFilterDay] = useState<TFilterDays | null>(90);\n\n const [dateRange, setDateRange] = useState<DateRange>(getDateRange(90));\n\n const updateFilterDay = (day: TFilterDays) => {\n setFilterDay(day);\n setDateRange(getDateRange(day));\n };\n\n const onFilter = (filter: { name: string; value: any }) => {\n if (filter.name === \"dateRange\") {\n const newDateRange = filter.value;\n setDateRange(newDateRange);\n\n if (newDateRange.from && newDateRange.to) {\n const offsetDay =\n Math.abs(differenceInDays(newDateRange.from, newDateRange.to)) + 1;\n\n const dateRange = getDateRange(offsetDay);\n if (\n formatDateRange(dateRange.from) ===\n formatDateRange(newDateRange.from) &&\n formatDateRange(dateRange.to) === formatDateRange(newDateRange.to)\n ) {\n setFilterDay(offsetDay as any);\n } else {\n setFilterDay(null);\n }\n }\n }\n };\n\n const filterItems = useMemo(() => {\n const dateRangeFilter = {\n type: \"range\",\n name: \"dateRange\",\n value: dateRange,\n max: 90,\n };\n\n return [dateRangeFilter] as any;\n }, [dateRange]);\n\n return {\n filterItems,\n onFilter,\n dateRange,\n filterDay,\n updateFilterDay,\n };\n}\n\nfunction useSearch() {\n const [searchValue, setSearchValue] = useState(\"\");\n const onSearchValueChange = useCallback((value: string) => {\n setSearchValue(value);\n }, []);\n\n const clearSearchValue = useCallback(() => {\n setSearchValue(\"\");\n }, []);\n\n return {\n searchValue,\n onSearchValueChange,\n clearSearchValue,\n };\n}\n","import { FC, useMemo } from \"react\";\nimport { cn, Box, useScreen, Divider } from \"@orderly.network/ui\";\nimport { LeaderboardTab } from \"../../../type\";\nimport { GeneralRankingWidget } from \"../../ranking/generalRanking\";\nimport { RankingColumnFields } from \"../../ranking/shared/column\";\nimport { LeaderboardFilter } from \"../shared/LeaderboardFilter\";\nimport { LeaderboardTabs } from \"../shared/LeaderboardTabs\";\nimport { GeneralLeaderboardScriptReturn } from \"./generalLeaderboard.script\";\n\nexport type GeneralLeaderboardProps = {\n style?: React.CSSProperties;\n className?: string;\n} & GeneralLeaderboardScriptReturn;\n\nexport const GeneralLeaderboard: FC<GeneralLeaderboardProps> = (props) => {\n const { isMobile } = useScreen();\n\n const fields = useMemo<RankingColumnFields[]>(() => {\n if (isMobile) {\n return [\n \"rank\",\n \"address\",\n props.activeTab === LeaderboardTab.Volume ? \"volume\" : \"pnl\",\n ];\n }\n return [\"rank\", \"address\", \"volume\", \"pnl\"];\n }, [isMobile, props.activeTab]);\n\n if (isMobile) {\n return (\n <Box\n pt={2}\n px={3}\n r=\"2xl\"\n intensity={900}\n width=\"100%\"\n className={cn(\n \"oui-trading-leaderboard-general-leaderboard oui-relative\",\n props.className,\n )}\n style={props.style}\n >\n <LeaderboardFilter {...props} />\n <LeaderboardTabs\n isMobile={isMobile}\n className=\"oui-pt-0\"\n activeTab={props.activeTab}\n onTabChange={props.onTabChange}\n />\n\n <GeneralRankingWidget\n dateRange={props.dateRange}\n address={props.searchValue}\n sortKey={\n props.activeTab === LeaderboardTab.Volume\n ? \"perp_volume\"\n : \"realized_pnl\"\n }\n fields={fields}\n />\n </Box>\n );\n }\n\n return (\n <Box\n pt={2}\n px={6}\n r=\"2xl\"\n intensity={900}\n className={cn(\n \"oui-trading-leaderboard-general-leaderboard oui-relative\",\n \"oui-mx-auto oui-max-w-[992px]\",\n props.className,\n )}\n style={props.style}\n >\n <LeaderboardFilter {...props} />\n <Divider intensity={8} />\n\n <GeneralRankingWidget\n dateRange={props.dateRange}\n address={props.searchValue}\n fields={fields}\n />\n </Box>\n );\n};\n","import { FC, SVGProps } from \"react\";\nimport { useTranslation } from \"@orderly.network/i18n\";\nimport {\n Box,\n CloseCircleFillIcon,\n cn,\n DataFilter,\n Flex,\n Input,\n Text,\n useScreen,\n} from \"@orderly.network/ui\";\nimport { ScrollIndicator } from \"@orderly.network/ui\";\nimport {\n FilterDays,\n GeneralLeaderboardScriptReturn,\n} from \"../generalLeaderboard/generalLeaderboard.script\";\n\nexport type LeaderboardFilterProps = GeneralLeaderboardScriptReturn;\n\nexport const LeaderboardFilter: FC<LeaderboardFilterProps> = (props) => {\n const { t } = useTranslation();\n const { isMobile } = useScreen();\n\n const input = (\n <Input\n value={props.searchValue}\n onValueChange={props.onSearchValueChange}\n placeholder={t(\"common.address.search.placeholder\")}\n className={cn(\n \"oui-trading-leaderboard-trading-search-input\",\n \"oui-w-full\",\n )}\n size=\"sm\"\n prefix={\n <Box pl={3} pr={1}>\n <SearchIcon className=\"oui-text-base-contrast-36\" />\n </Box>\n }\n suffix={\n props.searchValue && (\n <Box mr={2}>\n <CloseCircleFillIcon\n size={14}\n className=\"oui-cursor-pointer oui-text-base-contrast-36\"\n onClick={props.clearSearchValue}\n />\n </Box>\n )\n }\n autoComplete=\"off\"\n />\n );\n\n const dateRangeView = props.filterItems.length > 0 && (\n <DataFilter\n items={props.filterItems}\n onFilter={(value) => {\n props.onFilter(value);\n }}\n className=\"oui-h-[53px] oui-border-none\"\n />\n );\n\n const filterDayView = FilterDays.map((value) => {\n return (\n <button\n className=\"oui-relative oui-px-2 oui-py-[2px] oui-text-sm\"\n key={value}\n >\n <div className=\"oui-z-10\">\n <Text.gradient\n color={props.filterDay === value ? \"brand\" : undefined}\n className={\n props.filterDay !== value ? \"oui-text-base-contrast-54\" : \"\"\n }\n >\n {`${value}D`}\n </Text.gradient>\n </div>\n <div\n className=\"oui-absolute oui-inset-0 oui-rounded oui-opacity-[.12] oui-gradient-primary\"\n onClick={() => {\n props.updateFilterDay(value as any);\n }}\n ></div>\n </button>\n );\n });\n\n if (isMobile) {\n return (\n <Flex\n width=\"100%\"\n justify=\"between\"\n itemAlign=\"center\"\n direction=\"column\"\n mt={3}\n className={cn(\"oui-mobile-trading-leaderboard-ranking-filter\")}\n >\n {input}\n <Flex gap={3} className=\"oui-w-full\">\n {dateRangeView}\n <ScrollIndicator className=\"oui-w-full\">\n <Flex gap={3}>{filterDayView}</Flex>\n </ScrollIndicator>\n </Flex>\n </Flex>\n );\n }\n\n return (\n <Flex\n width=\"100%\"\n justify=\"between\"\n itemAlign=\"center\"\n className={cn(\"oui-trading-leaderboard-ranking-filter\")}\n >\n <Flex gap={3}>\n {dateRangeView}\n {filterDayView}\n </Flex>\n <Box width={240}>{input}</Box>\n </Flex>\n );\n};\n\nexport const SearchIcon: FC<SVGProps<SVGSVGElement>> = (props) => (\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 14 14\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path d=\"M5.841 1.14a4.667 4.667 0 0 0 0 9.333 4.74 4.74 0 0 0 2.875-.975l2.54 2.56a.6.6 0 0 0 .838 0 .6.6 0 0 0 0-.838L9.537 8.677a4.72 4.72 0 0 0 .971-2.871 4.667 4.667 0 0 0-4.667-4.667m0 1.166a3.5 3.5 0 1 1 0 7 3.5 3.5 0 0 1 0-7\" />\n </svg>\n);\n","import { FC, useEffect, useMemo } from \"react\";\nimport { useTranslation } from \"@orderly.network/i18n\";\nimport { cn, Flex, TabPanel, Tabs } from \"@orderly.network/ui\";\nimport { LeaderboardTab } from \"../../../type\";\nimport { formatUpdateDate } from \"../../../utils\";\nimport { useTradingLeaderboardContext } from \"../../provider\";\n\ntype LeaderboardTabsProps = {\n isMobile?: boolean;\n className?: string;\n activeTab: LeaderboardTab;\n onTabChange: (tab: LeaderboardTab) => void;\n};\n\nexport const LeaderboardTabs: FC<LeaderboardTabsProps> = (props) => {\n const { t } = useTranslation();\n const { updatedTime, currentCampaign } = useTradingLeaderboardContext();\n\n const updateTime = useMemo(() => {\n if (updatedTime && currentCampaign) {\n return formatUpdateDate(updatedTime);\n }\n return \"\";\n }, [props.isMobile, updatedTime, currentCampaign]);\n\n const { showVolume, showPnl } = useMemo(() => {\n const metrics = currentCampaign?.prize_pools?.map((item) => item.metric);\n const isMobileGeneral = props.isMobile && !currentCampaign;\n const showVolume = isMobileGeneral\n ? true\n : metrics?.includes(LeaderboardTab.Volume);\n const showPnl = isMobileGeneral\n ? true\n : metrics?.includes(LeaderboardTab.Pnl);\n\n return {\n showVolume,\n showPnl,\n };\n }, [currentCampaign, props.activeTab, props.isMobile]);\n\n useEffect(() => {\n // set default tab\n if (showVolume && showPnl) {\n props.onTabChange(LeaderboardTab.Volume);\n } else if (showVolume) {\n props.onTabChange(LeaderboardTab.Volume);\n } else if (showPnl) {\n props.onTabChange(LeaderboardTab.Pnl);\n }\n }, [currentCampaign, showVolume, showPnl]);\n\n const renderTabs = () => {\n if (showVolume && showPnl) {\n return (\n <Tabs\n value={props.activeTab}\n onValueChange={props.onTabChange as (tab: string) => void}\n variant=\"contained\"\n size=\"lg\"\n key={currentCampaign?.campaign_id}\n >\n <TabPanel\n title={t(\"tradingLeaderboard.tradingVolume\")}\n value={LeaderboardTab.Volume}\n ></TabPanel>\n <TabPanel\n title={t(\"tradingLeaderboard.realizedPnl\")}\n value={LeaderboardTab.Pnl}\n ></TabPanel>\n </Tabs>\n );\n }\n\n if (showVolume) {\n return (\n <Tabs\n value={props.activeTab}\n onValueChange={props.onTabChange as (tab: string) => void}\n variant=\"contained\"\n size=\"lg\"\n key={currentCampaign?.campaign_id}\n >\n <TabPanel\n title={t(\"tradingLeaderboard.tradingVolume\")}\n value={LeaderboardTab.Volume}\n ></TabPanel>\n </Tabs>\n );\n }\n\n if (showPnl) {\n return (\n <Tabs\n value={props.activeTab}\n onValueChange={props.onTabChange as (tab: string) => void}\n variant=\"contained\"\n size=\"lg\"\n key={currentCampaign?.campaign_id}\n >\n <TabPanel\n title={t(\"tradingLeaderboard.realizedPnl\")}\n value={LeaderboardTab.Pnl}\n ></TabPanel>\n </Tabs>\n );\n }\n return <div></div>;\n };\n\n return (\n <Flex\n width=\"100%\"\n py={3}\n justify=\"between\"\n className={cn(\n \"oui-trading-leaderboard-ranking-tabs\",\n \"oui-border-b oui-border-line\",\n props.className,\n )}\n >\n {renderTabs()}\n {/* <Tabs\n value={props.activeTab}\n onValueChange={props.onTabChange as (tab: string) => void}\n variant=\"contained\"\n size=\"lg\"\n >\n <TabPanel\n title=\"Trading volume\"\n value={LeaderboardTab.Volume}\n ></TabPanel>\n <TabPanel title=\"Realized PnL\" value={LeaderboardTab.Pnl}></TabPanel>\n </Tabs> */}\n {updateTime && (\n <Flex\n itemAlign=\"start\"\n direction={props.isMobile ? \"column\" : \"row\"}\n gap={1}\n className={cn(\n props.isMobile ? \"oui-text-3xs\" : \"oui-text-sm\",\n \"oui-text-base-contrast-36\",\n )}\n >\n <span>{t(\"tradingLeaderboard.lastUpdate\")}:</span>\n <span>{updateTime}</span>\n </Flex>\n )}\n </Flex>\n );\n};\n","import { FC } from \"react\";\nimport { useGeneralLeaderboardScript } from \"./generalLeaderboard.script\";\nimport {\n GeneralLeaderboard,\n GeneralLeaderboardProps,\n} from \"./generalLeaderboard.ui\";\n\nexport type GeneralLeaderboardWidgetProps = Pick<\n GeneralLeaderboardProps,\n \"style\" | \"className\"\n>;\n\nexport const GeneralLeaderboardWidget: FC<GeneralLeaderboardWidgetProps> = (\n props,\n) => {\n const state = useGeneralLeaderboardScript();\n\n return (\n <GeneralLeaderboard\n {...state}\n className={props.className}\n style={props.style}\n />\n );\n};\n","import { useMemo, useState } from \"react\";\nimport { LeaderboardTab } from \"../../../type\";\nimport { useTradingLeaderboardContext } from \"../../provider\";\n\nexport type CampaignLeaderboardScriptReturn = ReturnType<\n typeof useCampaignLeaderboardScript\n>;\n\nexport function useCampaignLeaderboardScript() {\n const [activeTab, setActiveTab] = useState<LeaderboardTab>(\n LeaderboardTab.Volume,\n );\n const { currentCampaign } = useTradingLeaderboardContext();\n\n const excludeColumns = useMemo(() => {\n return currentCampaign?.exclude_leaderboard_columns || [];\n }, [currentCampaign]);\n\n return {\n activeTab,\n onTabChange: setActiveTab,\n excludeColumns,\n };\n}\n","import { FC, useMemo } from \"react\";\nimport { difference } from \"ramda\";\nimport { cn, Box, useScreen } from \"@orderly.network/ui\";\nimport { LeaderboardTab } from \"../../../type\";\nimport { CampaignRankingWidget } from \"../../ranking/campaignRanking\";\nimport { RankingColumnFields } from \"../../ranking/shared/column\";\nimport { LeaderboardTabs } from \"../shared/LeaderboardTabs\";\nimport { CampaignLeaderboardScriptReturn } from \"./campaignLeaderboard.script\";\n\nexport type CampaignLeaderboardProps = {\n style?: React.CSSProperties;\n className?: string;\n campaignId: number | string;\n} & CampaignLeaderboardScriptReturn;\n\nexport const CampaignLeaderboard: FC<CampaignLeaderboardProps> = (props) => {\n const { isMobile } = useScreen();\n\n const sortKey = useMemo(() => {\n return props.activeTab === LeaderboardTab.Volume ? \"volume\" : \"pnl\";\n }, [props.activeTab]);\n\n const fields = useMemo<RankingColumnFields[]>(() => {\n const allFields: RankingColumnFields[] = [\n \"rank\",\n \"address\",\n sortKey,\n \"rewards\",\n ];\n return difference(allFields, props.excludeColumns || []);\n }, [isMobile, sortKey, props.excludeColumns]);\n\n if (isMobile) {\n return (\n <Box\n pt={2}\n px={3}\n r=\"2xl\"\n intensity={900}\n width=\"100%\"\n className={cn(\n \"oui-trading-leaderboard-campaign-leaderboard oui-relative\",\n )}\n >\n <LeaderboardTabs\n isMobile={isMobile}\n activeTab={props.activeTab}\n onTabChange={props.onTabChange}\n />\n\n <CampaignRankingWidget\n campaignId={props.campaignId}\n fields={fields}\n sortKey={sortKey}\n />\n </Box>\n );\n }\n\n return (\n <Box\n pt={2}\n px={6}\n r=\"2xl\"\n intensity={900}\n className={cn(\n \"oui-trading-leaderboard-campaign-leaderboard oui-relative\",\n \"oui-mx-auto oui-max-w-[992px]\",\n )}\n >\n <LeaderboardTabs\n isMobile={isMobile}\n activeTab={props.activeTab}\n onTabChange={props.onTabChange}\n />\n <CampaignRankingWidget\n campaignId={props.campaignId}\n fields={fields}\n sortKey={sortKey}\n />\n </Box>\n );\n};\n","import { FC } from \"react\";\nimport { useCampaignLeaderboardScript } from \"./campaignLeaderboard.script\";\nimport {\n CampaignLeaderboard,\n CampaignLeaderboardProps,\n} from \"./campaignLeaderboard.ui\";\n\nexport type CampaignLeaderboardWidgetProps = Pick<\n CampaignLeaderboardProps,\n \"style\" | \"className\" | \"campaignId\"\n>;\n\nexport const CampaignLeaderboardWidget: FC<CampaignLeaderboardWidgetProps> = (\n props,\n) => {\n const state = useCampaignLeaderboardScript();\n\n return (\n <CampaignLeaderboard\n {...state}\n className={props.className}\n style={props.style}\n campaignId={props.campaignId}\n />\n );\n};\n","import { FC, ReactNode } from \"react\";\nimport { useTranslation } from \"@orderly.network/i18n\";\nimport { Box, cn, Flex, Text, useScreen } from \"@orderly.network/ui\";\nimport { Background } from \"../../components/background\";\nimport { CampaignsWidget } from \"../../components/campaigns/campaigns.widget\";\nimport { CampaignLeaderboardWidget } from \"../../components/leaderboard/campaignLeaderboard\";\nimport {\n GeneralLeaderboardWidget,\n GeneralLeaderboardWidgetProps,\n} from \"../../components/leaderboard/generalLeaderboard\";\nimport {\n TradingLeaderboardProvider,\n TradingLeaderboardProviderProps,\n useTradingLeaderboardContext,\n} from \"../../components/provider\";\nimport { RewardsWidget } from \"../../components/rewards/rewards.widget\";\nimport { RuleWidget } from \"../../components/rule\";\n\nexport type LeaderboardPageProps = GeneralLeaderboardWidgetProps &\n TradingLeaderboardProviderProps & {\n style?: React.CSSProperties;\n className?: string;\n };\n\nexport const LeaderboardPage: FC<LeaderboardPageProps> = (props) => {\n return (\n <TradingLeaderboardProvider {...props}>\n <div\n style={{\n paddingBottom: \"calc(64px + env(safe-area-inset-bottom))\",\n }}\n className={cn(\n \"oui-trading-leaderboard-page\",\n \"oui-relative oui-bg-base-10\",\n \"oui-font-semibold\",\n props.className,\n )}\n >\n <CampaignsWidget className=\"oui-relative oui-z-[1] oui-mx-6\" />\n <RewardsWidget />\n <LeaderboardSection {...props} />\n <RuleWidget />\n </div>\n </TradingLeaderboardProvider>\n );\n};\n\ntype LeaderboardSectionProps = {\n style?: React.CSSProperties;\n className?: string;\n};\n\nexport const LeaderboardSection: FC<LeaderboardSectionProps> = (props) => {\n const { t } = useTranslation();\n const { isMobile } = useScreen();\n const { currentCampaignId, currentCampaign, backgroundSrc } =\n useTradingLeaderboardContext();\n\n if (currentCampaignId === \"general\") {\n return (\n <Box px={3} className={cn(\"oui-mix-blend-screen\")}>\n <Background backgroundSrc={backgroundSrc} />\n <GeneralLeaderboardWidget {...props} className=\"oui-mt-10\" />\n </Box>\n );\n }\n\n if (\n currentCampaign &&\n !currentCampaign.hide_arena &&\n currentCampaignId != \"general\"\n ) {\n return (\n <Box px={3}>\n <LeaderboardTitle\n title={t(\"tradingLeaderboard.arena\")}\n isMobile={isMobile}\n />\n <CampaignLeaderboardWidget {...props} campaignId={currentCampaignId} />\n </Box>\n );\n }\n\n return null;\n};\n\nexport const LeaderboardTitle = (props: {\n title: ReactNode;\n isMobile?: boolean;\n}) => {\n return (\n <Flex\n mb={props.isMobile ? 3 : 6}\n gapY={1}\n justify=\"center\"\n direction=\"column\"\n >\n <Text\n className={cn(\n \"oui-trading-leaderboard-title oui-font-bold\",\n props.isMobile\n ? \"oui-text-[20px] oui-leading-[24px]\"\n : \"oui-text-[32px] oui-leading-[44px]\",\n )}\n >\n {props.title}\n </Text>\n <Box\n width={24}\n height={6}\n r=\"base\"\n className=\"oui-bg-[linear-gradient(270deg,rgb(var(--oui-gradient-brand-start))_0%,rgb(var(--oui-gradient-brand-end))_100%)]\"\n />\n </Flex>\n );\n};\n","import { FC, useMemo } from \"react\";\nimport { cn, useScreen } from \"@orderly.network/ui\";\n\ntype BackgroundProps = {\n backgroundSrc?: string;\n};\n\nexport const Background: FC<BackgroundProps> = (props) => {\n const { isMobile } = useScreen();\n\n const isVideo = useMemo(() => {\n return isVideoSrc(props.backgroundSrc);\n }, [props.backgroundSrc]);\n\n if (isMobile) {\n return null;\n }\n\n const linearGradient =\n \"linear-gradient(180deg, rgba(var(--oui-color-base-10) / 0.3) 0%, rgba(var(--oui-color-base-10) / 0) 70%, rgba(var(--oui-color-base-10) / 1) 100%)\";\n\n if (isVideo) {\n return (\n <div className={cn(\"oui-absolute oui-left-0 oui-top-0\", \"oui-size-full\")}>\n <div\n style={{\n backgroundImage: linearGradient,\n backgroundSize: \"cover\",\n backgroundRepeat: \"no-repeat\",\n }}\n className={cn(\"oui-absolute oui-left-0 oui-top-0\", \"oui-size-full\")}\n />\n <video\n autoPlay\n loop\n muted\n className={cn(\n // rest style\n \"oui-border-none oui-bg-transparent oui-outline-none\",\n \"oui-size-full\",\n // \"oui-absolute oui-top-0 oui-left-0\",\n \"oui-object-cover\",\n \"oui-opacity-50\",\n )}\n >\n <source src={props.backgroundSrc} type=\"video/mp4\" />\n <source src={props.backgroundSrc} type=\"video/webm\" />\n <source src={props.backgroundSrc} type=\"video/ogg\" />\n <source src={props.backgroundSrc} type=\"video/avi\" />\n Your browser does not support the video tag.\n </video>\n </div>\n );\n }\n\n if (props.backgroundSrc) {\n return (\n <div\n style={{\n backgroundImage: `${linearGradient}, url(${props.backgroundSrc}) `,\n backgroundSize: \"cover\",\n backgroundRepeat: \"no-repeat\",\n }}\n className={cn(\n \"oui-general-leaderboard-background\",\n \"oui-absolute oui-left-0 oui-top-0 oui-z-[-1]\",\n \"oui-size-full\",\n \"oui-opacity-50\",\n )}\n />\n );\n }\n};\n\nfunction isVideoSrc(src?: string) {\n const extension = src?.split(\".\").pop();\n return [\"mp4\", \"webm\", \"avi\", \"ogg\"].includes(extension ?? \"\");\n}\n","import { FC, useMemo } from \"react\";\nimport { cn, useScreen } from \"@orderly.network/ui\";\nimport { CampaignsContentDesktopUI } from \"./campaigns.content.desktop.ui\";\nimport { useCampaignsScript } from \"./campaigns.script\";\nimport { CampaignsTimeDesktopUI } from \"./components/time.desktop.ui\";\nimport { CampaignsHeaderWidget } from \"./header\";\n\nexport type CampaignsWidgetProps = {\n className?: string;\n style?: React.CSSProperties;\n};\n\nexport const CampaignsWidget: FC<CampaignsWidgetProps> = (props) => {\n const state = useCampaignsScript();\n const { isMobile } = useScreen();\n\n const contentClassNames = useMemo(() => {\n if (!isMobile) return undefined;\n return {\n container: \"oui-h-[400px] oui-gap-5\",\n time: \"oui-text-sm oui-h-5\",\n title: \"oui-text-[24px] oui-leading-[32px]\",\n description: \"oui-text-2xs oui-leading-[15px]\",\n topContainer: \"oui-gap-1 oui-w-[284px]\",\n };\n }, [isMobile]);\n\n return (\n <div\n className={cn([\"oui-relative oui-z-[1] oui-overflow-hidden\"])}\n style={props.style}\n >\n <CampaignsHeaderWidget\n backgroundSrc={state.backgroundSrc}\n campaigns={state.campaigns}\n currentCampaignId={state.currentCampaignId.toString()}\n onCampaignChange={state.onCampaignChange}\n />\n {state.currentCampaign && (\n <CampaignsContentDesktopUI\n campaign={state.currentCampaign}\n statistics={state.statistics}\n onLearnMore={state.onLearnMore}\n onTradeNow={state.onTradeNow}\n backgroundSrc={state.backgroundSrc}\n classNames={contentClassNames}\n isMobile={isMobile}\n isParticipated={state.isParticipated}\n shouldShowJoinButton={state.shouldShowJoinButton}\n joinCampaign={state.joinCampaign}\n isJoining={state.isJoining}\n joinError={state.joinError}\n canTrade={state.canTrade}\n />\n )}\n {state.currentCampaign && (\n <CampaignsTimeDesktopUI\n campaign={state.currentCampaign}\n isMobile={isMobile}\n />\n )}\n </div>\n );\n};\n","import { FC, useMemo, useState } from \"react\";\nimport { useTranslation } from \"@orderly.network/i18n\";\nimport { AccountStatusEnum } from \"@orderly.network/types\";\nimport {\n cn,\n Text,\n InfoCircleIcon,\n Button,\n Tooltip,\n ChevronRightIcon,\n} from \"@orderly.network/ui\";\nimport { AuthGuard } from \"@orderly.network/ui-connector\";\nimport { CampaignConfig, CampaignStatistics } from \"./type\";\nimport {\n formatCampaignDateRange,\n getTradingVolume,\n getTotalPrizePool,\n getTicketPrizePool,\n formatPrizeAmount,\n} from \"./utils\";\n\nexport const CampaignsContentDesktopUI: FC<{\n campaign: CampaignConfig;\n statistics?: CampaignStatistics;\n onLearnMore: () => void;\n onTradeNow: () => void;\n backgroundSrc?: string;\n classNames?: {\n container?: string;\n title?: string;\n description?: string;\n time?: string;\n topContainer?: string;\n descriptionContainer?: string;\n };\n isMobile?: boolean;\n isParticipated?: boolean;\n shouldShowJoinButton?: boolean;\n joinCampaign?: (data: { campaign_id: string | number }) => Promise<any>;\n isJoining?: boolean;\n joinError?: any;\n canTrade?: boolean;\n}> = ({\n campaign,\n statistics,\n onLearnMore,\n onTradeNow,\n backgroundSrc,\n classNames,\n isMobile,\n shouldShowJoinButton,\n joinCampaign,\n isJoining,\n canTrade,\n}) => {\n const { t } = useTranslation();\n const bgSrc = campaign?.image || backgroundSrc;\n const dateRange = formatCampaignDateRange(\n campaign?.start_time,\n campaign?.end_time,\n );\n // for mobile\n const [tooltipOpen, setTooltipOpen] = useState(false);\n\n const tooltipProps = useMemo(() => {\n if (!isMobile) {\n return {};\n }\n return {\n open: tooltipOpen,\n onOpenChange: setTooltipOpen,\n };\n }, [tooltipOpen, isMobile, setTooltipOpen]);\n\n // Get campaign data using utility functions\n const tradingVolume = getTradingVolume(statistics);\n const totalPrizePool = getTotalPrizePool(campaign);\n const ticketPrizePool = getTicketPrizePool(campaign);\n\n const showTradeButton = useMemo(() => {\n return (\n !shouldShowJoinButton && new Date().toISOString() < campaign.end_time\n );\n }, [shouldShowJoinButton, campaign.end_time]);\n\n const isCampaignStarted = useMemo(() => {\n return campaign.start_time < new Date().toISOString();\n }, [campaign]);\n\n const highlightPool = useMemo(() => {\n if (!campaign?.highlight_pool_id) {\n return null;\n }\n return campaign?.prize_pools?.find(\n (pool) => pool.pool_id === campaign.highlight_pool_id,\n );\n }, [campaign]);\n\n const tooltipContent = useMemo(() => {\n if (!campaign?.prize_pools) {\n return null;\n }\n\n return (\n <div className=\"oui-flex oui-min-w-[240px] oui-flex-col oui-gap-1\">\n {campaign?.prize_pools?.map((pool) => {\n return (\n <div\n key={pool.pool_id}\n className=\"oui-flex oui-h-[18px] oui-items-center oui-justify-between\"\n >\n <Text\n size=\"2xs\"\n weight=\"semibold\"\n className=\"oui-text-base-contrast-54\"\n >\n {pool.label}\n </Text>\n <div className=\"oui-flex oui-items-center oui-gap-1\">\n <Text.numeral\n dp={2}\n size=\"2xs\"\n weight=\"semibold\"\n className=\"oui-text-base-contrast\"\n >\n {pool.total_prize}\n </Text.numeral>\n <Text\n size=\"2xs\"\n weight=\"semibold\"\n className=\"oui-text-base-contrast\"\n >\n {pool.currency}\n </Text>\n </div>\n </div>\n );\n })}\n </div>\n );\n }, [campaign]);\n\n return (\n <div\n className={cn([\n \"oui-flex oui-h-[500px] oui-w-full oui-flex-col oui-items-center oui-justify-center oui-gap-10\",\n `oui-bg-cover oui-bg-center oui-bg-no-repeat`,\n classNames?.container,\n ])}\n style={{\n backgroundImage: `linear-gradient(180deg, rgba(var(--oui-color-base-10) / 1) 0%, rgba(var(--oui-color-base-10) / 0.8) 15%, rgba(var(--oui-color-base-10) / 0.4) 40%, rgba(var(--oui-color-base-10) / 0.4) 60%, rgba(var(--oui-color-base-10) / 0.8) 85%, rgba(var(--oui-color-base-10) / 1) 100%), url(${bgSrc})`,\n }}\n >\n <div\n className={cn([\n \"oui-flex oui-flex-col oui-items-center oui-justify-center oui-gap-[10px]\",\n classNames?.topContainer,\n ])}\n >\n <Text\n size=\"sm\"\n weight=\"semibold\"\n className={cn([\"oui-text-base-contrast-54\", classNames?.time])}\n >\n {dateRange}\n </Text>\n <Text\n className={cn([\n \"oui-trading-leaderboard-title oui-text-center oui-text-[48px] oui-font-bold oui-leading-[56px] oui-text-base-contrast\",\n classNames?.title,\n ])}\n >\n {campaign.title}\n </Text>\n <div\n className={cn([\n \"oui-w-[342px] oui-text-center\",\n classNames?.descriptionContainer,\n ])}\n >\n <Text\n size=\"sm\"\n weight=\"semibold\"\n className={cn([\n \"oui-text-base-contrast-54\",\n classNames?.description,\n ])}\n >\n {campaign.description}\n </Text>\n </div>\n </div>\n <div className=\"oui-overflow-hidden oui-rounded-2xl oui-border oui-border-solid oui-border-base-contrast/[0.08]\">\n <div\n className={cn([\n \"oui-flex oui-items-center oui-gap-4 oui-px-4 oui-py-3 oui-backdrop-blur-[10px]\",\n isCampaignStarted ? \"\" : \"oui-hidden\",\n ])}\n >\n <div className=\"oui-flex oui-items-center oui-gap-1\">\n <Text\n size=\"2xs\"\n weight=\"semibold\"\n className=\"oui-text-base-contrast-54\"\n >\n {campaign?.user_account_label ||\n t(\"tradingLeaderboard.participants\")}\n </Text>\n <Text\n size=\"2xs\"\n weight=\"semibold\"\n className=\"oui-text-base-contrast-80\"\n >\n {statistics?.total_participants}\n </Text>\n </div>\n <div className=\"oui-flex oui-items-center oui-gap-1\">\n <Text\n size=\"2xs\"\n weight=\"semibold\"\n className=\"oui-text-base-contrast-54\"\n >\n {t(\"tradingLeaderboard.tradingVolume\")}\n </Text>\n <Text.numeral\n dp={2}\n currency=\"$\"\n size=\"2xs\"\n weight=\"semibold\"\n className=\"oui-text-base-contrast-80\"\n >\n {tradingVolume}\n </Text.numeral>\n </div>\n </div>\n <div\n className={cn([\n \"oui-rounded-2xl oui-border oui-border-solid oui-border-base-contrast/[0.08] oui-bg-primary/[0.08] oui-p-4 oui-backdrop-blur-[10px]\",\n \"oui-flex oui-flex-col oui-gap-4\",\n isCampaignStarted ? \"\" : \"oui-border-transparent\",\n ])}\n >\n <div className=\"oui-flex oui-items-center oui-gap-6\">\n <div className=\"oui-flex oui-flex-col\">\n <div className=\"oui-flex oui-items-center oui-gap-1\">\n <Text\n size={isMobile ? \"2xs\" : \"xs\"}\n weight=\"semibold\"\n className=\"oui-text-base-contrast-54\"\n >\n {/* {t(\"tradingLeaderboard.prizePool\")} */}\n {\"Total prize pool\"}\n </Text>\n <Tooltip\n // @ts-ignore\n content={tooltipContent}\n {...tooltipProps}\n className=\"oui-max-w-[260px] oui-bg-base-5 oui-px-2 oui-py-1\"\n >\n <div\n className=\"oui-flex oui-size-4 oui-items-center oui-justify-center\"\n onClick={() => setTooltipOpen(true)}\n >\n <InfoCircleIcon className=\"oui-cursor-pointer\" />\n </div>\n </Tooltip>\n </div>\n <div>\n <Text.gradient\n weight=\"bold\"\n color=\"brand\"\n className={cn([\n \"oui-trading-leaderboard-title\",\n isMobile\n ? \"oui-text-[20px] oui-leading-[24px]\"\n : \"oui-text-[24px] oui-leading-[28px]\",\n ])}\n >\n {totalPrizePool\n ? formatPrizeAmount(\n totalPrizePool.amount,\n totalPrizePool.currency,\n )\n : \"0 USDC\"}\n </Text.gradient>\n </div>\n </div>\n {(ticketPrizePool || highlightPool) && (\n <div className=\"oui-flex oui-flex-col\">\n <div className=\"oui-flex oui-items-center oui-gap-1\">\n <Text\n size={isMobile ? \"2xs\" : \"xs\"}\n weight=\"semibold\"\n className=\"oui-text-base-contrast-54\"\n >\n {/* {t(\"tradingLeaderboard.ticketPrizePool\")} */}\n {highlightPool?.label || \"Raffle prize\"}\n </Text>\n </div>\n <div>\n <Text.gradient\n weight=\"bold\"\n color=\"brand\"\n className={cn([\n \"oui-trading-leaderboard-title\",\n isMobile\n ? \"oui-text-[20px] oui-leading-[24px]\"\n : \"oui-text-[24px] oui-leading-[28px]\",\n ])}\n >\n {formatPrizeAmount(\n ticketPrizePool?.amount ||\n highlightPool?.total_prize ||\n 0,\n ticketPrizePool?.currency ||\n highlightPool?.currency ||\n \"USDC\",\n )}\n </Text.gradient>\n </div>\n </div>\n )}\n </div>\n {isMobile && campaign?.rule_url && (\n <div\n className=\"-oui-mb-1 -oui-mt-2 oui-flex oui-items-center oui-gap-0.5 oui-text-2xs oui-leading-[15px] oui-text-base-contrast-36\"\n onClick={onLearnMore}\n >\n {t(\"tradingLeaderboard.viewRules\")}\n <ChevronRightIcon\n size={16}\n className=\"oui-text-base-contrast-36\"\n />\n </div>\n )}\n <div\n className={cn([\n \"oui-flex oui-gap-4\",\n campaign?.rule_url || canTrade ? \"\" : \"oui-hidden\",\n ])}\n >\n {!isMobile && campaign?.rule_url && (\n <Button\n size=\"md\"\n variant=\"outlined\"\n className=\"oui-flex-1 \n oui-border-[rgb(var(--oui-gradient-brand-start))] \n oui-text-[rgb(var(--oui-gradient-brand-start))] \n hover:oui-bg-[rgb(var(--oui-gradient-brand-start))]/[0.08]\n active:oui-bg-[rgb(var(--oui-gradient-brand-start))]/[0.08]\n \"\n onClick={onLearnMore}\n >\n {t(\"tradingLeaderboard.viewRules\")}\n </Button>\n )}\n <AuthGuard\n buttonProps={{\n size: isMobile ? \"sm\" : \"md\",\n className: \"oui-px-5\",\n }}\n >\n {shouldShowJoinButton && (\n <Button\n size={isMobile ? \"sm\" : \"md\"}\n variant=\"gradient\"\n color=\"primary\"\n className=\"oui-flex-1\"\n loading={isJoining}\n disabled={isJoining}\n onClick={async () => {\n try {\n await joinCampaign?.({\n campaign_id: Number(campaign.campaign_id),\n });\n } catch (error) {\n console.error(\"Failed to join campaign:\", error);\n }\n }}\n >\n {t(\"tradingLeaderboard.joinNow\")}\n </Button>\n )}\n {showTradeButton && (\n <Button\n size={isMobile ? \"sm\" : \"md\"}\n variant=\"gradient\"\n color=\"primary\"\n className=\"oui-flex-1\"\n onClick={onTradeNow}\n >\n {campaign?.trading_config?.format ||\n t(\"tradingLeaderboard.tradeNow\")}\n </Button>\n )}\n </AuthGuard>\n </div>\n </div>\n </div>\n </div>\n );\n};\n","import { format } from \"date-fns\";\nimport { i18n } from \"@orderly.network/i18n\";\nimport { TimelinePoint } from \"./components/axis\";\nimport { CampaignConfig, CampaignTagEnum, CampaignStatistics } from \"./type\";\n\n// Default timezone display for campaigns\nconst DEFAULT_TIMEZONE_DISPLAY = \"UTC\";\n\n/**\n * Get user's current timezone display name\n * @returns Display name for the user's timezone (e.g., 'UTC', 'EST', 'PST')\n */\nexport const getUserTimezoneDisplay = (): string => {\n try {\n const date = new Date();\n const timeString = date.toLocaleTimeString(\"en-US\", {\n timeZoneName: \"short\",\n });\n const shortName = timeString.split(\" \").pop();\n return shortName || DEFAULT_TIMEZONE_DISPLAY;\n } catch (error) {\n console.warn(\"Failed to detect user timezone, using default:\", error);\n return DEFAULT_TIMEZONE_DISPLAY;\n }\n};\n\n/**\n * Get the appropriate tag for a campaign based on its configuration and current conditions\n * @param campaign Campaign configuration object\n * @param userReferralCode User's referral code (optional)\n * @returns CampaignTagEnum representing the current status of the campaign\n */\nexport const getCampaignTag = (\n campaign: CampaignConfig,\n userReferralCode?: string,\n): CampaignTagEnum => {\n const currentTime = new Date();\n const startTime = new Date(campaign.start_time);\n const endTime = new Date(campaign.end_time);\n\n // Check if campaign is exclusive to specific referral codes\n if (campaign.referral_codes && campaign.referral_codes.length > 0) {\n // If user doesn't have a referral code or it's not in the allowed list\n if (\n !userReferralCode ||\n !campaign.referral_codes.includes(userReferralCode)\n ) {\n // Don't show the campaign at all, or return a special status\n // For now, we'll treat it as if the campaign doesn't exist for this user\n // You might want to handle this differently based on your UI requirements\n return CampaignTagEnum.EXCLUSIVE;\n }\n\n // If user has valid referral code, check the time-based status\n if (currentTime < startTime) {\n return CampaignTagEnum.COMING;\n } else if (currentTime > endTime) {\n return CampaignTagEnum.ENDED;\n } else {\n return CampaignTagEnum.EXCLUSIVE; // Show as exclusive during the active period\n }\n }\n\n // For non-exclusive campaigns, check time-based status\n if (currentTime < startTime) {\n return CampaignTagEnum.COMING;\n } else if (currentTime > endTime) {\n return CampaignTagEnum.ENDED;\n } else {\n return CampaignTagEnum.ONGOING;\n }\n};\n\n/**\n * Check if a campaign is visible to the current user\n * @param campaign Campaign configuration object\n * @param userReferralCode User's referral code (optional)\n * @returns boolean indicating if the campaign should be displayed\n */\nexport const isCampaignVisible = (\n campaign: CampaignConfig,\n userReferralCode?: string,\n): boolean => {\n // If campaign has referral code restrictions\n if (campaign.referral_codes && campaign.referral_codes.length > 0) {\n // Only show if user has a valid referral code\n return (\n !!userReferralCode && campaign.referral_codes.includes(userReferralCode)\n );\n }\n\n // For non-exclusive campaigns, always visible\n return true;\n};\n\n/**\n * Format campaign date range to display format like \"Feb 28, 2025 - March 2, 2025 PST\"\n * @param startTime Start time string or timestamp (should be UTC)\n * @param endTime End time string or timestamp (should be UTC)\n * @param showTimezone Whether to show timezone suffix (defaults to true)\n * @returns Formatted date range string with user's timezone\n */\nexport const formatCampaignDateRange = (\n startTime: string | number | Date,\n endTime: string | number | Date,\n showTimezone: boolean = true,\n): string => {\n try {\n // Convert to Date objects - JavaScript automatically handles UTC conversion to local time\n const startDate = new Date(startTime);\n const endDate = new Date(endTime);\n\n // Check if dates are valid\n if (isNaN(startDate.getTime()) || isNaN(endDate.getTime())) {\n console.warn(\"Invalid date value provided to formatCampaignDateRange:\", {\n startTime,\n endTime,\n });\n return \"Invalid date range\";\n }\n\n // Format dates using date-fns (will display in user's local timezone)\n // MMM d, yyyy format gives us \"Feb 28, 2025\" style\n const startFormatted = format(startDate, \"MMM d, yyyy\");\n const endFormatted = format(endDate, \"MMM d, yyyy\");\n\n const dateRange = `${startFormatted} - ${endFormatted}`;\n\n if (!showTimezone) {\n return dateRange;\n }\n\n // Add user's timezone suffix\n const timezoneDisplay = getUserTimezoneDisplay();\n return `${dateRange} ${timezoneDisplay}`;\n } catch (error) {\n console.error(\"Error formatting campaign date range:\", error, {\n startTime,\n endTime,\n });\n return \"Date formatting error\";\n }\n};\n\n/**\n * Get total participants count from campaign statistics\n * @param statistics Campaign statistics data from API\n * @returns Formatted participants count\n */\nexport const getParticipantsCount = (\n statistics?: CampaignStatistics,\n): number => {\n return statistics?.total_participants || 0;\n};\n\n/**\n * Get total trading volume from campaign statistics\n * @param statistics Campaign statistics data from API\n * @returns Total trading volume amount\n */\nexport const getTradingVolume = (statistics?: CampaignStatistics): number => {\n return statistics?.total_volume || 0;\n};\n\n/**\n * Calculate total prize pool amount from campaign configuration\n * @param campaign Campaign configuration object\n * @returns Object with total amount and currency, or null if no prize pools\n */\nexport const getTotalPrizePool = (\n campaign?: CampaignConfig,\n): { amount: number; currency: string } | null => {\n if (!campaign?.prize_pools || campaign.prize_pools.length === 0) {\n return null;\n }\n\n // Group by currency and sum up the amounts\n const currencyTotals: Record<string, number> = {};\n\n campaign.prize_pools.forEach((pool) => {\n currencyTotals[pool.currency] =\n (currencyTotals[pool.currency] || 0) + pool.total_prize;\n });\n\n // For now, return the first currency found (typically USDC)\n // In the future, we might want to handle multiple currencies differently\n const currencies = Object.keys(currencyTotals);\n if (currencies.length === 0) return null;\n\n const mainCurrency = currencies[0];\n return {\n amount: currencyTotals[mainCurrency],\n currency: mainCurrency,\n };\n};\n\n/**\n * Get ticket prize pool amount from campaign configuration\n * @param campaign Campaign configuration object\n * @returns Object with amount and currency, or null if no ticket rules\n */\nexport const getTicketPrizePool = (\n campaign?: CampaignConfig,\n): { amount: number; currency: string } | null => {\n if (!campaign?.ticket_rules) {\n return null;\n }\n\n return {\n amount: campaign.ticket_rules.total_prize,\n currency: campaign.ticket_rules.currency,\n };\n};\n\n/**\n * Format prize amount for display\n * @param amount Prize amount\n * @param currency Currency symbol\n * @returns Formatted string like \"15,000 USDC\"\n */\nexport const formatPrizeAmount = (amount: number, currency: string): string => {\n return `${amount.toLocaleString()} ${currency}`;\n};\n\n/**\n * Format trading volume for display with currency symbol\n * @param volume Trading volume amount\n * @returns Formatted string with $ prefix\n */\nexport const formatTradingVolume = (volume: number): string => {\n if (volume >= 1_000_000) {\n return `$${(volume / 1_000_000).toFixed(1)}M`;\n } else if (volume >= 1_000) {\n return `$${(volume / 1_000).toFixed(1)}K`;\n } else {\n return `$${volume.toFixed(0)}`;\n }\n};\n\n/**\n * Format participants count for display\n * @param count Participants count\n * @returns Formatted string with proper formatting\n */\nexport const formatParticipantsCount = (count: number): string => {\n if (count >= 1_000_000) {\n return `${(count / 1_000_000).toFixed(1)}M`;\n } else if (count >= 1_000) {\n return `${(count / 1_000).toFixed(1)}K`;\n } else {\n return count.toLocaleString();\n }\n};\n\n/**\n * Generate timeline data points for campaign visualization\n * @param campaign Campaign configuration object\n * @returns Array of TimelinePoint objects (max 4 points) in user's local timezone\n */\nexport const generateCampaignTimeline = (\n campaign: CampaignConfig,\n): TimelinePoint[] => {\n const currentTime = new Date();\n const startTime = new Date(campaign.start_time);\n const endTime = new Date(campaign.end_time);\n const rewardTime = campaign.reward_distribution_time\n ? new Date(campaign.reward_distribution_time)\n : null;\n\n const timeline: TimelinePoint[] = [];\n\n // Helper function to determine point type based on time\n const getTimelineType = (\n time: Date,\n isNow: boolean = false,\n ): \"past\" | \"active\" | \"future\" => {\n if (isNow) return \"active\";\n return currentTime >= time ? \"past\" : \"future\";\n };\n\n // Helper function to format time for display in user's local timezone\n const formatTimeDisplay = (time: Date): string => {\n try {\n // Format time using date-fns (displays in user's local timezone)\n const formatted = format(time, \"yyyy-MM-dd HH:mm\");\n const timezoneDisplay = getUserTimezoneDisplay();\n return `${formatted} ${timezoneDisplay}`;\n } catch (error) {\n console.error(\"Error formatting time:\", error);\n return time.toISOString();\n }\n };\n\n // Battle starts point\n timeline.push({\n title: i18n.t(\"tradingLeaderboard.battleStarts\"),\n type: getTimelineType(startTime),\n time: formatTimeDisplay(startTime),\n });\n\n // Add \"Now\" point if battle is ongoing\n const isOngoing = currentTime >= startTime && currentTime <= endTime;\n if (isOngoing) {\n timeline.push({\n title: i18n.t(\"chart.now\"),\n type: \"active\",\n time: formatTimeDisplay(currentTime),\n });\n }\n\n // Battle ends point\n timeline.push({\n title: i18n.t(\"tradingLeaderboard.battleEnds\"),\n type: getTimelineType(endTime),\n time: formatTimeDisplay(endTime),\n });\n\n // Reward distribution point (if provided)\n if (rewardTime) {\n timeline.push({\n title: i18n.t(\"tradingLeaderboard.rewardDistribution\"),\n type: getTimelineType(rewardTime),\n time: formatTimeDisplay(rewardTime),\n });\n }\n\n // Ensure we don't exceed 4 points\n return timeline.slice(0, 4);\n};\n","import { RankingColumnFields } from \"../ranking/shared/column\";\nimport { DescriptionConfig, DescriptionItem } from \"../rule/description\";\n\nexport enum CampaignTagEnum {\n ONGOING = \"ongoing\",\n COMING = \"coming\",\n ENDED = \"ended\",\n EXCLUSIVE = \"exclusive\",\n}\n\n// Campaign statistics data structure (from campaign statistics API)\nexport interface CampaignStatistics {\n total_participants?: number;\n total_volume?: number;\n}\n\n// Campaign prize pool configuration types\nexport interface PrizePoolTier {\n position?: number;\n position_range?: [number, number];\n amount: number;\n}\n\nexport interface PrizePool {\n pool_id: string;\n label: string;\n total_prize: number;\n currency: string;\n metric: \"volume\" | \"pnl\";\n tiers: PrizePoolTier[];\n}\n\n// Ticket prize configuration types\nexport interface TicketTierRule {\n value: number;\n tickets: number;\n}\n\nexport interface TicketLinearRule {\n every: number;\n tickets: number;\n}\n\nexport interface TicketRules {\n total_prize: number;\n currency: string;\n metric: \"volume\" | \"pnl\";\n mode: \"tiered\" | \"linear\";\n tiers?: TicketTierRule[];\n linear?: TicketLinearRule;\n}\n\n// Campaign configuration\nexport interface CampaignConfig {\n campaign_id: number | string;\n title: string;\n description: string;\n start_time: string;\n end_time: string;\n reward_distribution_time?: string;\n volume_scope?: string | string[];\n referral_codes?: string[] | string;\n prize_pools?: PrizePool[];\n ticket_rules?: TicketRules;\n image?: string;\n rule_url?: string;\n rule_config?: {\n action?: \"scroll\" | \"click\";\n };\n trading_url?: string;\n trading_config?: {\n format?: string;\n };\n href?: string;\n hide_arena?: boolean;\n hide_rewards?: boolean;\n hide_estimated_rewards?: boolean;\n highlight_pool_id?: string;\n user_account_label?: string;\n rule?: {\n rule: DescriptionItem[];\n terms: DescriptionItem[];\n ruleConfig?: DescriptionConfig;\n };\n exclude_leaderboard_columns?: RankingColumnFields[];\n}\n\n// User data for calculations\nexport interface UserData {\n rank?: number | string;\n pnl: number;\n total_participants?: number;\n volume: number;\n referral_code?: string;\n}\n\nexport type CampaignStatsDetailsResponse = {\n broker_id: string;\n user_count: number;\n volume: number;\n symbol: string;\n}[];\n\nexport type CampaignStatsResponse = {\n sign_up_count: number;\n user_count: number;\n volume: number;\n updated_time: number;\n};\n\nexport type UserCampaignsResponse = {\n id: string;\n register_time: number;\n}[];\n","import { useMemo, useCallback } from \"react\";\nimport {\n useQuery,\n useConfig,\n useMutation,\n useAccount,\n} from \"@orderly.network/hooks\";\nimport { AccountStatusEnum } from \"@orderly.network/types\";\nimport { toast } from \"@orderly.network/ui\";\nimport { useTradingLeaderboardContext } from \"../provider\";\nimport { CampaignStatsResponse, UserCampaignsResponse } from \"./type\";\n\n/**\n * Hook for managing campaigns data and statistics\n * TODO: Replace mock data with real API calls when backend is ready\n */\nexport const useCampaignsScript = () => {\n const {\n campaigns = [],\n currentCampaignId,\n onCampaignChange,\n currentCampaign,\n userData,\n backgroundSrc,\n } = useTradingLeaderboardContext();\n\n const symbols = Array.isArray(currentCampaign?.volume_scope)\n ? currentCampaign?.volume_scope.join(\",\")\n : currentCampaign?.volume_scope;\n\n const brokerId = useConfig(\"brokerId\");\n\n const isCampaignEnded = useMemo(() => {\n return (\n currentCampaign?.end_time &&\n currentCampaign?.end_time < new Date().toISOString()\n );\n }, [currentCampaign]);\n\n const searchParams = useMemo(() => {\n return {\n campaign_id: currentCampaignId.toString(),\n symbols: symbols || \"\",\n broker_id: brokerId,\n group_by: \"BROKER\",\n };\n }, [currentCampaignId, symbols, brokerId]);\n\n const { data: stats } = useQuery<CampaignStatsResponse>(\n currentCampaignId !== \"general\"\n ? `https://api.orderly.org/v1/public/campaign/stats?${new URLSearchParams(searchParams).toString()}`\n : null,\n { revalidateOnFocus: false },\n );\n\n const { state } = useAccount();\n\n const { data: userCampaigns, mutate: refreshUserCampaigns } =\n useQuery<UserCampaignsResponse>(\n currentCampaignId !== \"general\" && state.address\n ? `https://api.orderly.org/v1/public/campaigns?address=${state.address}`\n : null,\n { revalidateOnFocus: false },\n );\n\n const isParticipated = useMemo(() => {\n const target = userCampaigns?.find((item) => item.id == currentCampaignId);\n return !!target;\n }, [userCampaigns, currentCampaignId]);\n\n const shouldShowJoinButton = useMemo(() => {\n // return false;\n return !!state.address && !isCampaignEnded && !isParticipated;\n }, [state.address, isCampaignEnded, isParticipated]);\n\n const [doJoinCampaign, { isMutating: isJoining, error: joinError }] =\n useMutation(`/v1/client/campaign/sign_up`, \"POST\");\n\n const joinCampaign = useCallback(\n async (data: { campaign_id: string | number }) => {\n try {\n if (state.status < AccountStatusEnum.EnableTrading) {\n toast.error(\"Please enable trading to proceed.\");\n return;\n }\n // console.log(\"data\", data);\n const result = await doJoinCampaign(data);\n // console.log(\"result\", result);\n\n if (result?.success !== false) {\n // Refresh user campaigns data to update participation status\n await refreshUserCampaigns();\n toast.success(result?.message || \"Campaign joined successfully\");\n return result;\n } else {\n toast.error(result?.message || \"Failed to join campaign\");\n }\n } catch (error) {\n console.error(\"Failed to join campaign:\", error);\n throw error;\n }\n },\n [doJoinCampaign, refreshUserCampaigns, state.status],\n );\n\n const statistics = {\n total_participants: stats?.user_count,\n total_volume: stats?.volume,\n };\n\n const onLearnMore = () => {\n if (currentCampaign?.rule_url) {\n if (currentCampaign.rule_config?.action === \"scroll\") {\n document\n .getElementById(currentCampaign.rule_url)\n ?.scrollIntoView({ behavior: \"smooth\" });\n } else {\n window.open(currentCampaign.rule_url, \"_blank\");\n }\n }\n };\n\n const onTradeNow = () => {\n if (currentCampaign?.trading_url) {\n window.open(currentCampaign.trading_url, \"_self\");\n }\n };\n\n const canTrade = useMemo(() => {\n if (!currentCampaign) return false;\n return (\n currentCampaign?.start_time < new Date().toISOString() &&\n currentCampaign?.end_time > new Date().toISOString() &&\n state.status >= AccountStatusEnum.EnableTrading\n );\n }, [currentCampaign, state.status]);\n\n return {\n campaigns,\n currentCampaignId,\n currentCampaign,\n onCampaignChange,\n statistics,\n userData,\n onLearnMore,\n onTradeNow,\n backgroundSrc,\n joinCampaign,\n isJoining,\n isParticipated,\n shouldShowJoinButton,\n joinError,\n canTrade,\n };\n};\n","import { FC } from \"react\";\nimport { cn } from \"@orderly.network/ui\";\nimport { CampaignConfig } from \"../type\";\nimport { generateCampaignTimeline } from \"../utils\";\nimport { CampaignsAxis, CampaignsAxisMobile } from \"./axis\";\nimport { CampaignsCountdown } from \"./countdown\";\n\nexport const CampaignsTimeDesktopUI: FC<{\n campaign: CampaignConfig;\n isMobile?: boolean;\n}> = ({ campaign, isMobile }) => {\n const timelineData = generateCampaignTimeline(campaign);\n\n return (\n <div\n className={cn([\n \"oui-max-w-[992px] oui-mx-auto oui-flex oui-flex-col oui-items-center\",\n isMobile ? \"oui-pt-4 oui-gap-10 oui-pb-10\" : \"oui-py-10 oui-gap-4\",\n ])}\n >\n <CampaignsCountdown campaign={campaign} isMobile={isMobile} />\n {isMobile ? (\n <CampaignsAxisMobile points={timelineData} />\n ) : (\n <CampaignsAxis points={timelineData} />\n )}\n </div>\n );\n};\n","import { FC } from \"react\";\nimport { cn } from \"@orderly.network/ui\";\n\nexport interface TimelinePoint {\n title: string;\n type: \"past\" | \"active\" | \"future\";\n time: string;\n}\n\nexport interface CampaignsAxisProps {\n points: TimelinePoint[];\n}\n\nexport const CampaignsAxis: FC<CampaignsAxisProps> = ({ points }) => {\n if (!points || points.length === 0) {\n return null;\n }\n\n // Find the index of the active point\n const activeIndex = points.findIndex((point) => point.type === \"active\");\n\n // For single point, center it without any lines\n if (points.length === 1) {\n return (\n <div className=\"oui-flex oui-w-full oui-justify-center\">\n <div className=\"oui-flex oui-flex-col oui-items-center\">\n <AxisPoint type={points[0].type} />\n <div className=\"oui-mt-4 oui-flex oui-flex-col oui-items-center oui-text-center\">\n <div className=\"oui-trading-leaderboard-title oui-mb-1 oui-whitespace-nowrap oui-text-sm oui-font-medium oui-text-base-contrast-54\">\n {points[0].title}\n </div>\n <div className=\"oui-whitespace-nowrap oui-text-xs oui-text-base-contrast-36\">\n {points[0].time}\n </div>\n </div>\n </div>\n </div>\n );\n }\n\n // Helper function to determine line background class\n const getLineBackgroundClass = (segmentIndex: number): string => {\n // If there's an active point and this segment is to the left of it, use oui-bg-base-3\n if (activeIndex !== -1 && segmentIndex < activeIndex) {\n return \"oui-bg-base-3\";\n }\n // Otherwise use regular color\n return \"oui-bg-base-8\";\n };\n\n const widthPercentage = points?.length > 3 ? \"110%\" : \"120%\";\n\n return (\n <div className=\"oui-flex oui-w-full\" style={{ width: widthPercentage }}>\n {points.map((point, index) => {\n const isFirst = index === 0;\n const isLast = index === points.length - 1;\n\n return (\n <div\n key={index}\n className=\"oui-relative oui-flex oui-flex-1 oui-flex-col oui-items-center\"\n >\n {/* Point container with connecting lines */}\n <div className=\"oui-relative oui-flex oui-w-full oui-items-center\">\n {/* Left line - always occupy space, but invisible for first point */}\n <div\n className={cn([\n \"oui-h-[6px] oui-flex-1\",\n !isFirst && getLineBackgroundClass(index - 1),\n ])}\n />\n\n {/* Point */}\n <div className=\"oui-z-10 oui-shrink-0\">\n <AxisPoint type={point.type} />\n </div>\n\n {/* Right line - always occupy space, but invisible for last point */}\n <div\n className={cn([\n \"oui-h-[6px] oui-flex-1\",\n !isLast && getLineBackgroundClass(index),\n ])}\n />\n </div>\n\n {/* Label below point */}\n <div className=\"oui-mt-4 oui-flex oui-flex-col oui-items-center oui-text-center\">\n <div className=\"oui-trading-leaderboard-title oui-mb-1 oui-whitespace-nowrap oui-text-sm oui-font-medium oui-text-base-contrast-54\">\n {point.title}\n </div>\n <div className=\"oui-whitespace-nowrap oui-text-xs oui-text-base-contrast-36\">\n {point.type !== \"active\" && point.time}\n </div>\n </div>\n </div>\n );\n })}\n </div>\n );\n};\n\nexport const CampaignsAxisMobile: FC<CampaignsAxisProps> = ({ points }) => {\n if (!points || points.length === 0) {\n return null;\n }\n\n // Find the index of the active point\n const activeIndex = points.findIndex((point) => point.type === \"active\");\n\n // Helper function to determine line background class\n const getLineBackgroundClass = (segmentIndex: number): string => {\n // If there's an active point and this segment is above it, use oui-bg-base-3\n if (activeIndex !== -1 && segmentIndex < activeIndex) {\n return \"oui-bg-base-3\";\n }\n // Otherwise use regular color\n return \"oui-bg-base-8\";\n };\n\n return (\n <div className=\"oui-flex oui-w-full oui-flex-col oui-items-center oui-gap-10\">\n {points.map((point, index) => {\n const isFirst = index === 0;\n const isLast = index === points.length - 1;\n\n return (\n <div key={index} className={cn([\"oui-relative\"])}>\n {/* Main content container */}\n <div className=\"oui-flex oui-h-10 oui-items-start oui-gap-4\">\n {/* Point with connecting line */}\n <div\n className={cn([\n \"oui-relative oui-flex oui-flex-col oui-items-center\",\n isFirst && \"oui-translate-y-[10px]\",\n ])}\n >\n <AxisPoint type={point.type} />\n\n {/* Vertical connecting line - only show if not the last point */}\n {!isLast && (\n <div\n className={cn([\n \"oui-h-[64px] oui-w-[6px]\",\n getLineBackgroundClass(index),\n ])}\n />\n )}\n </div>\n\n {/* Text content */}\n <div className=\"oui-flex oui-flex-col oui-justify-start\">\n <div className=\"oui-trading-leaderboard-title oui-mb-1 oui-text-sm oui-font-medium oui-text-base-contrast-54\">\n {point.title}\n </div>\n <div className=\"oui-min-w-[160px] oui-text-xs oui-text-base-contrast-36\">\n {point.type !== \"active\" && point.time}\n </div>\n </div>\n </div>\n </div>\n );\n })}\n </div>\n );\n};\n\nconst AxisPoint: FC<{ type: \"past\" | \"active\" | \"future\" }> = ({ type }) => {\n return (\n <div\n className={cn([\n \"oui-size-5 oui-shrink-0 oui-rounded-full\",\n type === \"past\" && \"oui-bg-base-contrast-80\",\n type === \"active\" &&\n \"oui-bg-gradient-to-r oui-from-[rgba(var(--oui-gradient-brand-start))] oui-to-[rgba(var(--oui-gradient-brand-end))]\",\n type === \"future\" &&\n \"oui-border-[2.5px] oui-border-solid oui-border-base-contrast-80 oui-bg-[#07080A]\",\n ])}\n />\n );\n};\n","import { FC, useState, useEffect } from \"react\";\nimport { useTranslation } from \"@orderly.network/i18n\";\nimport { cn } from \"@orderly.network/ui\";\nimport { CampaignConfig } from \"../type\";\n\nconst Circle = () => (\n <div className=\"oui-w-1 oui-h-1 oui-rounded-full oui-bg-white/[0.16]\" />\n);\n\ninterface TimeLeft {\n days: number;\n hours: number;\n minutes: number;\n seconds: number;\n}\n\ninterface TimeUnitProps {\n value: number;\n label: string;\n isMobile?: boolean;\n}\n\nconst TimeUnit: FC<TimeUnitProps> = ({ value, label, isMobile }) => (\n <div\n className={cn([\n \"oui-flex oui-flex-col oui-items-center oui-gap-1\",\n isMobile ? \"oui-w-[45px]\" : \"oui-w-[63px]\",\n ])}\n >\n <div\n className={cn([\n \"oui-trading-leaderboard-title oui-text-base-contrast oui-font-medium\",\n isMobile\n ? \"oui-text-[20px] oui-leading-[24px] oui-h-[24px]\"\n : \"oui-text-[36px] oui-leading-[44px] oui-h-[44px]\",\n ])}\n >\n {value.toString().padStart(2, \"0\")}\n </div>\n <div\n className={cn([\n \"oui-trading-leaderboard-title oui-text-base-contrast-80 oui-font-medium\",\n isMobile\n ? \"oui-text-[10px] oui-leading-[14px] oui-h-[14px]\"\n : \"oui-text-sm oui-leading-[20px] oui-h-[20px]\",\n ])}\n >\n {label}\n </div>\n </div>\n);\n\nexport const CampaignsCountdown: FC<{\n campaign: CampaignConfig;\n isMobile?: boolean;\n}> = ({ campaign, isMobile }) => {\n const { t } = useTranslation();\n const [timeLeft, setTimeLeft] = useState<TimeLeft>({\n days: 0,\n hours: 0,\n minutes: 0,\n seconds: 0,\n });\n const [isStarted, setIsStarted] = useState(false);\n\n useEffect(() => {\n const calculateTimeLeft = () => {\n const currentTime = new Date().getTime();\n const startTime = new Date(campaign.start_time).getTime();\n const endTime = new Date(campaign.end_time).getTime();\n\n // Determine if campaign has started\n const hasStarted = currentTime >= startTime;\n setIsStarted(hasStarted);\n\n // Calculate time difference based on campaign status\n const targetTime = hasStarted ? endTime : startTime;\n const difference = targetTime - currentTime;\n\n if (difference > 0) {\n const days = Math.floor(difference / (1000 * 60 * 60 * 24));\n const hours = Math.floor(\n (difference % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60),\n );\n const minutes = Math.floor(\n (difference % (1000 * 60 * 60)) / (1000 * 60),\n );\n const seconds = Math.floor((difference % (1000 * 60)) / 1000);\n\n setTimeLeft({ days, hours, minutes, seconds });\n } else {\n setTimeLeft({ days: 0, hours: 0, minutes: 0, seconds: 0 });\n }\n };\n\n // Calculate immediately\n calculateTimeLeft();\n\n // Set up interval to update every second\n const timer = setInterval(calculateTimeLeft, 1000);\n\n // Cleanup interval on component unmount\n return () => clearInterval(timer);\n }, [campaign.start_time, campaign.end_time]);\n\n // Check if campaign has ended\n const currentTime = new Date();\n const endTime = new Date(campaign.end_time);\n\n if (currentTime > endTime) {\n return (\n <div className=\"oui-w-full oui-flex oui-items-center oui-justify-center oui-gap-4\">\n <div\n className=\"oui-max-w-[382px] oui-w-full oui-h-[1px] oui-bg-gradient-to-r oui-from-[rgba(var(--oui-gradient-brand-end)/0)]\n oui-to-[rgba(var(--oui-gradient-brand-start))]\"\n />\n <div\n className={cn([\n \"oui-trading-leaderboard-title oui-flex oui-items-center oui-justify-center oui-font-medium oui-text-base-contrast-54\",\n isMobile\n ? \"oui-text-[14px] oui-leading-[20px] oui-h-[20px] oui-whitespace-nowrap\"\n : \"oui-p-5 oui-text-[18px] oui-leading-[26px] oui-h-[26px]\",\n ])}\n >\n {t(\"tradingLeaderboard.batteleHasEnded\")}\n </div>\n <div\n className=\"oui-max-w-[382px] oui-w-full oui-h-[1px] oui-bg-gradient-to-r oui-from-[rgba(var(--oui-gradient-brand-start))]\n oui-to-[rgba(var(--oui-gradient-brand-end)/0)]\"\n />\n </div>\n );\n }\n\n const titleText = isStarted\n ? t(\"tradingLeaderboard.battleEndsIn\")\n : t(\"tradingLeaderboard.battleStartsIn\");\n\n // Time units configuration\n const timeUnits = [\n { value: timeLeft.days, label: \"Days\" },\n { value: timeLeft.hours, label: \"Hours\" },\n { value: timeLeft.minutes, label: \"Minutes\" },\n { value: timeLeft.seconds, label: \"Seconds\" },\n ];\n\n return (\n <div className=\"oui-w-full oui-flex oui-items-center oui-justify-center oui-gap-4\">\n <div\n className=\"oui-max-w-[298px] oui-w-full oui-h-[1px] oui-bg-gradient-to-r oui-from-[rgba(var(--oui-gradient-brand-end)/0)]\n oui-to-[rgba(var(--oui-gradient-brand-start))]\"\n />\n <div\n className={cn([\n \"oui-flex oui-flex-col oui-items-center\",\n isMobile ? \"oui-p-0 oui-gap-1\" : \"oui-p-5 oui-gap-2\",\n ])}\n >\n <div\n className={cn([\n \"oui-trading-leaderboard-title oui-font-medium oui-text-base-contrast-54\",\n isMobile\n ? \"oui-text-[14px] oui-leading-[20px] oui-h-[20px]\"\n : \"oui-text-[18px] oui-leading-[26px] oui-h-[26px]\",\n ])}\n >\n {titleText}\n </div>\n <div\n className={cn([\n \"oui-flex oui-items-center\",\n isMobile ? \"oui-gap-2\" : \"oui-gap-[10px]\",\n ])}\n >\n {timeUnits.map((unit, index) => (\n <div\n key={unit.label}\n className={cn([\n \"oui-flex oui-items-center\",\n isMobile ? \"oui-gap-2\" : \"oui-gap-[10px]\",\n ])}\n >\n <TimeUnit\n value={unit.value}\n label={unit.label}\n isMobile={isMobile}\n />\n {index < timeUnits.length - 1 && <Circle />}\n </div>\n ))}\n </div>\n </div>\n <div\n className=\"oui-max-w-[298px] oui-w-full oui-h-[1px] oui-bg-gradient-to-r oui-from-[rgba(var(--oui-gradient-brand-start))]\n oui-to-[rgba(var(--oui-gradient-brand-end)/0)]\"\n />\n </div>\n );\n};\n","import { FC, useCallback, useState, useEffect } from \"react\";\nimport useEmblaCarousel from \"embla-carousel-react\";\nimport { ChevronLeftIcon, ChevronRightIcon } from \"@orderly.network/ui\";\nimport { DefaultCampaign } from \"../DefaultCampaign\";\nimport { CampaignItemUI } from \"../campaign.item.ui\";\nimport { CampaignConfig } from \"../type\";\nimport { getCampaignTag } from \"../utils\";\n\nexport const CampaignsHeaderUI: FC<{\n campaigns: CampaignConfig[];\n currentCampaignId: string;\n onCampaignChange: (campaignId: string) => void;\n backgroundSrc?: string;\n}> = ({ campaigns, currentCampaignId, onCampaignChange, backgroundSrc }) => {\n const [isLargeScreen, setIsLargeScreen] = useState(false);\n const [canScrollPrev, setCanScrollPrev] = useState(false);\n const [canScrollNext, setCanScrollNext] = useState(false);\n\n useEffect(() => {\n const checkScreenSize = () => {\n setIsLargeScreen(window.innerWidth >= 1024);\n };\n\n // Check initial size\n checkScreenSize();\n\n // Add event listener\n window.addEventListener(\"resize\", checkScreenSize);\n\n // Cleanup\n return () => window.removeEventListener(\"resize\", checkScreenSize);\n }, []);\n\n const [emblaRef, emblaApi] = useEmblaCarousel({\n loop: false,\n align: \"start\",\n containScroll: \"keepSnaps\",\n slidesToScroll: 1,\n skipSnaps: false,\n dragFree: false,\n });\n\n // Update scroll availability\n const updateScrollAvailability = useCallback(() => {\n if (!emblaApi || !campaigns?.length) return;\n\n setCanScrollPrev(emblaApi.canScrollPrev());\n\n // Check if the last slide is in view\n const slidesInView = emblaApi.slidesInView();\n const lastSlideIndex = campaigns.length - 1;\n const isLastSlideInView = slidesInView.includes(lastSlideIndex);\n\n setCanScrollNext(emblaApi.canScrollNext() && !isLastSlideInView);\n }, [emblaApi, campaigns]);\n\n useEffect(() => {\n if (!emblaApi) return;\n\n // Initial check\n updateScrollAvailability();\n\n // Listen for scroll events\n emblaApi.on(\"select\", updateScrollAvailability);\n emblaApi.on(\"reInit\", updateScrollAvailability);\n emblaApi.on(\"scroll\", updateScrollAvailability);\n\n return () => {\n emblaApi.off(\"select\", updateScrollAvailability);\n emblaApi.off(\"reInit\", updateScrollAvailability);\n emblaApi.off(\"scroll\", updateScrollAvailability);\n };\n }, [emblaApi, updateScrollAvailability]);\n\n const scrollPrev = useCallback(() => {\n if (emblaApi) emblaApi.scrollPrev();\n }, [emblaApi]);\n\n const scrollNext = useCallback(() => {\n if (emblaApi) emblaApi.scrollNext();\n }, [emblaApi]);\n\n // Calculate width considering gap (0.5rem = 8px)\n // For 2 items: (100% - 1 * gap) / 2\n // For 3 items: (100% - 2 * gap) / 3\n const slideStyle = isLargeScreen\n ? { flexBasis: \"calc((100% - 1rem) / 3)\", width: \"calc((100% - 1rem) / 3)\" }\n : {\n flexBasis: \"calc((100% - 0.5rem) / 2)\",\n width: \"calc((100% - 0.5rem) / 2)\",\n };\n\n // Check if scroll buttons should be hidden based on screen size and campaign count\n const shouldHideScrollButtons = isLargeScreen\n ? campaigns.length <= 3\n : campaigns.length <= 2;\n\n return (\n <div className=\"oui-flex oui-gap-2 oui-w-full oui-items-center oui-px-6\">\n <div className=\"oui-flex-shrink-0\">\n <DefaultCampaign\n currentCampaignId={currentCampaignId}\n onCampaignChange={onCampaignChange}\n className=\"oui-min-w-[322px]\"\n />\n </div>\n\n <div className=\"oui-w-[1px] oui-h-[78px] oui-bg-white/[0.16]\" />\n\n <button\n onClick={scrollPrev}\n disabled={!canScrollPrev}\n className={`oui-group oui-flex oui-items-center oui-justify-center oui-shrink-0 oui-w-6 oui-h-[78px] oui-rounded-lg oui-transition-colors hover:oui-bg-base-7 disabled:oui-opacity-30 disabled:oui-cursor-not-allowed disabled:hover:oui-bg-transparent ${shouldHideScrollButtons ? \"oui-hidden\" : \"\"}`}\n aria-label=\"Previous campaigns\"\n >\n <ChevronLeftIcon\n opacity={1}\n className=\"oui-text-base-contrast-54 group-hover:oui-text-base-contrast\"\n />\n </button>\n\n <div className=\"oui-flex-1 oui-min-w-0 oui-overflow-hidden\">\n <div ref={emblaRef}>\n <div className=\"oui-flex oui-gap-2\">\n {campaigns?.map((campaign) => (\n <div\n key={campaign.campaign_id}\n className=\"oui-flex-shrink-0\"\n style={slideStyle}\n >\n <CampaignItemUI\n backgroundSrc={backgroundSrc}\n campaign={campaign}\n tag={getCampaignTag(campaign)}\n active={currentCampaignId == campaign.campaign_id}\n onCampaignChange={onCampaignChange}\n classNames={{\n tag: {\n container: \"oui-h-[23px] oui-py-1 oui-px-2\",\n },\n }}\n />\n </div>\n ))}\n </div>\n </div>\n </div>\n <button\n onClick={scrollNext}\n disabled={!canScrollNext}\n className={`oui-group oui-flex oui-items-center oui-justify-center oui-shrink-0 oui-w-6 oui-h-[78px] oui-rounded-lg oui-transition-colors hover:oui-bg-base-7 disabled:oui-opacity-30 disabled:oui-cursor-not-allowed disabled:hover:oui-bg-transparent ${shouldHideScrollButtons ? \"oui-hidden\" : \"\"}`}\n aria-label=\"Next campaigns\"\n >\n <ChevronRightIcon\n opacity={1}\n className=\"oui-text-base-contrast-54 group-hover:oui-text-base-contrast\"\n />\n </button>\n </div>\n );\n};\n","import { FC } from \"react\";\nimport { useTranslation } from \"@orderly.network/i18n\";\nimport { cn } from \"@orderly.network/ui\";\n\nexport const DefaultCampaign: FC<{\n currentCampaignId: string;\n onCampaignChange: (campaignId: string) => void;\n style?: React.CSSProperties;\n className?: string;\n}> = ({ currentCampaignId, onCampaignChange, style, className }) => {\n const { t } = useTranslation();\n return (\n <div\n className={cn([\n \"oui-trading-leaderboard-title\",\n \"oui-flex oui-items-center oui-justify-center oui-cursor-pointer\",\n \"oui-bg-base-9 oui-h-[78px] oui-rounded-lg oui-border oui-border-solid\",\n currentCampaignId === \"general\"\n ? \"oui-border-[rgba(var(--oui-gradient-brand-start))]\"\n : \"oui-border-transparent\",\n className,\n ])}\n style={style}\n onClick={() => onCampaignChange(\"general\")}\n >\n {t(\"tradingLeaderboard.generalLeaderboard\")}\n </div>\n );\n};\n","import { FC } from \"react\";\nimport { cn, Text } from \"@orderly.network/ui\";\nimport { CampaignConfig, CampaignTagEnum } from \"./type\";\n\ninterface CampaignItemUIProps {\n className?: string;\n active?: boolean;\n tag: CampaignTagEnum;\n onCampaignChange: (campaignId: string) => void;\n campaign: CampaignConfig;\n backgroundSrc?: string;\n classNames?: {\n container?: string;\n content?: string;\n tag?: {\n container?: string;\n text?: string;\n };\n title?: string;\n };\n}\n\nexport const CampaignItemUI: FC<CampaignItemUIProps> = ({\n active,\n tag,\n onCampaignChange,\n campaign,\n backgroundSrc,\n classNames,\n}) => {\n return (\n <div\n className={cn([\n \"oui-w-full\",\n \"oui-relative oui-h-[78px] oui-cursor-pointer oui-overflow-hidden oui-rounded-lg oui-bg-white/[0.04]\",\n \"oui-group oui-border oui-border-solid oui-backdrop-blur-[200px]\",\n active\n ? \"oui-border-[rgba(var(--oui-gradient-brand-start))]\"\n : \"oui-border-transparent\",\n \"hover:oui-border-base-contrast\",\n classNames?.container,\n ])}\n onClick={() => onCampaignChange(campaign.campaign_id.toString())}\n >\n <CampaignTag tag={tag} active={active} classNames={classNames?.tag} />\n <div\n className={cn([\n \"oui-size-full\",\n \"oui-absolute oui-left-0 oui-top-0\",\n \"oui-bg-cover oui-bg-center oui-bg-no-repeat oui-bg-blend-luminosity\",\n active ? \"oui-bg-transparent\" : \"oui-bg-[lightgray] oui-opacity-40\",\n \"group-hover:oui-bg-transparent group-hover:oui-opacity-100\",\n ])}\n style={{\n backgroundImage: `url(${campaign?.image || backgroundSrc})`,\n }}\n />\n <div\n className={cn([\n \"oui-flex oui-size-full oui-flex-col oui-items-center oui-justify-center oui-gap-1\",\n \"oui-absolute oui-left-0 oui-top-0 oui-z-10\",\n classNames?.content,\n ])}\n >\n <Text\n weight=\"semibold\"\n className={cn([\n active ? \"oui-text-base-contrast\" : \"oui-text-base-contrast-54\",\n \"group-hover:oui-text-base-contrast\",\n \"oui-trading-leaderboard-title\",\n \"oui-w-3/5 oui-text-center oui-text-sm\",\n classNames?.title,\n ])}\n >\n {campaign.title}\n </Text>\n {campaign.referral_codes && (\n <Text\n className={cn([\n \"oui-text-base-contrast-54\",\n \"oui-text-center oui-text-[10px]\",\n ])}\n >\n {Array.isArray(campaign.referral_codes)\n ? campaign.referral_codes.join(\",\")\n : campaign.referral_codes}\n </Text>\n )}\n </div>\n </div>\n );\n};\n\nconst CampaignTag: FC<{\n tag: CampaignTagEnum;\n active?: boolean;\n classNames?: {\n container?: string;\n text?: string;\n };\n}> = ({ tag, active, classNames }) => {\n const tagText = tag.slice(0, 1).toUpperCase() + tag.slice(1);\n return (\n <div\n className={cn([\n \"oui-w-fit oui-rounded-br-lg\",\n \"oui-absolute oui-left-0 oui-top-0 oui-z-10 oui-flex oui-items-center\",\n active && tag !== CampaignTagEnum.COMING\n ? \"oui-bg-[rgba(var(--oui-gradient-brand-start))]\"\n : \"oui-bg-base-4\",\n active && tag !== CampaignTagEnum.ENDED && \"group-hover:oui-bg-base-4\",\n tag === CampaignTagEnum.ENDED &&\n \"oui-bg-base-6 group-hover:oui-bg-base-6\",\n classNames?.container,\n ])}\n >\n {tag === CampaignTagEnum.ENDED ? (\n <Text\n size=\"2xs\"\n weight=\"semibold\"\n className={cn([\"oui-text-base-contrast-54\", classNames?.text])}\n >\n {tagText}\n </Text>\n ) : (\n <Text.gradient\n size=\"2xs\"\n weight=\"semibold\"\n color=\"brand\"\n className={cn([\n active &&\n tag !== CampaignTagEnum.COMING &&\n \"oui-text-black/[0.88] group-hover:oui-text-transparent\",\n classNames?.text,\n ])}\n >\n {tagText}\n </Text.gradient>\n )}\n </div>\n );\n};\n","import { FC, useCallback, useState, useEffect, memo, useRef } from \"react\";\nimport useEmblaCarousel from \"embla-carousel-react\";\nimport { ChevronLeftIcon, ChevronRightIcon } from \"@orderly.network/ui\";\nimport { DefaultCampaign } from \"../DefaultCampaign\";\nimport { CampaignItemUI } from \"../campaign.item.ui\";\nimport { CampaignConfig } from \"../type\";\nimport { getCampaignTag } from \"../utils\";\n\nexport const CampaignsHeaderMobileUI: FC<{\n campaigns: CampaignConfig[];\n currentCampaignId: string;\n onCampaignChange: (campaignId: string) => void;\n backgroundSrc?: string;\n}> = memo(\n ({ campaigns, currentCampaignId, onCampaignChange, backgroundSrc }) => {\n const [canScrollPrev, setCanScrollPrev] = useState(false);\n const [canScrollNext, setCanScrollNext] = useState(false);\n const hasInitialScrolled = useRef(false);\n const isInitializing = useRef(true);\n\n const [emblaRef, emblaApi] = useEmblaCarousel({\n loop: false,\n align: \"start\",\n containScroll: \"keepSnaps\",\n slidesToScroll: 1,\n skipSnaps: false,\n dragFree: false,\n });\n\n // All campaign items including default campaign\n const allCampaignItems = [\n { campaign_id: \"general\", isDefault: true },\n ...campaigns.map((campaign) => ({ ...campaign, isDefault: false })),\n ];\n\n // Update scroll availability and handle auto campaign change on slide\n const updateScrollAvailability = useCallback(() => {\n if (!emblaApi || !campaigns?.length) return;\n\n setCanScrollPrev(emblaApi.canScrollPrev());\n setCanScrollNext(emblaApi.canScrollNext());\n\n // Skip auto campaign change during initialization or before initial scroll is completed\n if (isInitializing.current || !hasInitialScrolled.current) return;\n\n // Auto trigger onCampaignChange when slide changes (only after user interaction)\n const selectedIndex = emblaApi.selectedScrollSnap();\n const selectedCampaign = allCampaignItems[selectedIndex];\n\n if (selectedCampaign) {\n const campaignId = selectedCampaign.isDefault\n ? \"general\"\n : String(selectedCampaign.campaign_id);\n if (campaignId != currentCampaignId) {\n onCampaignChange(campaignId);\n }\n }\n }, [\n emblaApi,\n campaigns,\n currentCampaignId,\n onCampaignChange,\n allCampaignItems,\n ]);\n\n // Auto scroll to current campaign on initial load\n const scrollToCurrentCampaign = useCallback(() => {\n if (!emblaApi || !campaigns?.length) return;\n\n const targetIndex = allCampaignItems.findIndex((item) => {\n const campaignId = item.isDefault\n ? \"general\"\n : String(item.campaign_id);\n return campaignId === currentCampaignId;\n });\n\n if (targetIndex !== -1 && targetIndex !== emblaApi.selectedScrollSnap()) {\n emblaApi.scrollTo(targetIndex, false); // false to disable animation for initial scroll\n }\n\n // Mark as scrolled and initialized after the scroll operation\n hasInitialScrolled.current = true;\n // Small delay to ensure the scroll operation is completed before enabling auto change\n setTimeout(() => {\n isInitializing.current = false;\n }, 100);\n }, [emblaApi, campaigns, currentCampaignId, allCampaignItems]);\n\n useEffect(() => {\n if (!emblaApi) return;\n\n // Initial check\n updateScrollAvailability();\n\n // Auto scroll to current campaign on initial load\n scrollToCurrentCampaign();\n\n // Listen for scroll events\n emblaApi.on(\"select\", updateScrollAvailability);\n emblaApi.on(\"reInit\", updateScrollAvailability);\n\n return () => {\n emblaApi.off(\"select\", updateScrollAvailability);\n emblaApi.off(\"reInit\", updateScrollAvailability);\n };\n }, [emblaApi, updateScrollAvailability, scrollToCurrentCampaign]);\n\n // Reset scroll flag when currentCampaignId changes externally\n useEffect(() => {\n hasInitialScrolled.current = false;\n isInitializing.current = true;\n if (emblaApi) {\n scrollToCurrentCampaign();\n }\n }, [currentCampaignId, scrollToCurrentCampaign, emblaApi]);\n\n const scrollPrev = useCallback(() => {\n if (emblaApi) {\n // Enable auto campaign change after user interaction\n isInitializing.current = false;\n emblaApi.scrollPrev();\n }\n }, [emblaApi]);\n\n const scrollNext = useCallback(() => {\n if (emblaApi) {\n // Enable auto campaign change after user interaction\n isInitializing.current = false;\n emblaApi.scrollNext();\n }\n }, [emblaApi]);\n\n // Mobile shows one item at full width\n const slideStyle = { flexBasis: \"100%\", width: \"100%\", height: \"42px\" };\n\n // Hide scroll buttons when there's only one or no campaigns\n const shouldHideScrollButtons = campaigns.length < 1;\n\n return (\n <div className=\"oui-flex oui-w-full oui-items-center oui-gap-2 oui-px-3\">\n <button\n onClick={scrollPrev}\n disabled={!canScrollPrev}\n className={`oui-group oui-flex oui-h-[42px] oui-w-6 oui-shrink-0 oui-items-center oui-justify-center oui-rounded-lg oui-transition-colors hover:oui-bg-base-7 disabled:oui-cursor-not-allowed disabled:oui-opacity-30 disabled:hover:oui-bg-transparent ${shouldHideScrollButtons ? \"oui-hidden\" : \"\"}`}\n aria-label=\"Previous campaigns\"\n >\n <ChevronLeftIcon\n opacity={1}\n className=\"oui-text-base-contrast-54 group-hover:oui-text-base-contrast\"\n />\n </button>\n\n <div className=\"oui-min-w-0 oui-flex-1 oui-overflow-hidden\">\n <div ref={emblaRef}>\n <div className=\"oui-flex oui-gap-2\">\n <DefaultCampaign\n key=\"general_campaign\"\n currentCampaignId={currentCampaignId}\n onCampaignChange={onCampaignChange}\n style={slideStyle}\n className=\"oui-w-full oui-shrink-0\"\n />\n {campaigns?.map((campaign) => (\n <div\n key={campaign.campaign_id}\n className=\"oui-shrink-0\"\n style={slideStyle}\n >\n <CampaignItemUI\n backgroundSrc={backgroundSrc}\n campaign={campaign}\n tag={getCampaignTag(campaign)}\n active={currentCampaignId == campaign.campaign_id}\n onCampaignChange={onCampaignChange}\n classNames={{\n container: \"!oui-h-[42px]\",\n title: \"!oui-text-[10px]\",\n content: \"!oui-gap-[2px]\",\n tag: {\n container: \"!oui-h-[14px] !oui-px-1 !oui-py-[2px]\",\n text: \"!oui-text-[10px]\",\n },\n }}\n />\n </div>\n ))}\n </div>\n </div>\n </div>\n <button\n onClick={scrollNext}\n disabled={!canScrollNext}\n className={`oui-group oui-flex oui-h-[42px] oui-w-6 oui-shrink-0 oui-items-center oui-justify-center oui-rounded-lg oui-transition-colors hover:oui-bg-base-7 disabled:oui-cursor-not-allowed disabled:oui-opacity-30 disabled:hover:oui-bg-transparent ${shouldHideScrollButtons ? \"oui-hidden\" : \"\"}`}\n aria-label=\"Next campaigns\"\n >\n <ChevronRightIcon\n opacity={1}\n className=\"oui-text-base-contrast-54 group-hover:oui-text-base-contrast\"\n />\n </button>\n </div>\n );\n },\n);\n","import { useScreen } from \"@orderly.network/ui\";\nimport { CampaignConfig } from \"../type\";\nimport { CampaignsHeaderUI } from \"./campaigns.header.desktop.ui\";\nimport { CampaignsHeaderMobileUI } from \"./campaigns.header.mobile.ui\";\n\nexport const CampaignsHeaderWidget = (props: {\n campaigns: CampaignConfig[];\n currentCampaignId: string;\n onCampaignChange: (campaignId: string) => void;\n backgroundSrc?: string;\n}) => {\n const { isMobile } = useScreen();\n return isMobile ? (\n <CampaignsHeaderMobileUI {...props} />\n ) : (\n <CampaignsHeaderUI {...props} />\n );\n};\n","import { useMemo } from \"react\";\nimport { useTranslation } from \"@orderly.network/i18n\";\nimport { useScreen } from \"@orderly.network/ui\";\nimport { LeaderboardTitle } from \"../../pages/leaderboard/page\";\nimport { useCampaignsScript } from \"../campaigns/campaigns.script\";\nimport { RewardsDesktopUI } from \"./rewards.desktop.ui\";\n\nexport const RewardsWidget = () => {\n const state = useCampaignsScript();\n const { t } = useTranslation();\n const { isMobile } = useScreen();\n\n const hideConfig = useMemo(() => {\n return {\n estimatedRewards: state.currentCampaign?.hide_estimated_rewards,\n };\n }, [state.currentCampaign]);\n\n if (\n state.currentCampaignId === \"general\" ||\n state.currentCampaign?.hide_rewards\n ) {\n return null;\n }\n\n return (\n <>\n <LeaderboardTitle\n title={t(\"tradingRewards.rewards\")}\n isMobile={isMobile}\n />\n <RewardsDesktopUI\n campaign={state.currentCampaign}\n userdata={state.userData}\n onLearnMore={state.onLearnMore}\n onTradeNow={state.onTradeNow}\n isMobile={isMobile}\n shouldShowJoinButton={state.shouldShowJoinButton}\n joinCampaign={state.joinCampaign}\n hideConfig={hideConfig}\n />\n </>\n );\n};\n","import { FC, useMemo, useState } from \"react\";\nimport { useTranslation, Trans } from \"@orderly.network/i18n\";\nimport { InfoCircleIcon, Tooltip, Text, Button, cn } from \"@orderly.network/ui\";\nimport { commify } from \"@orderly.network/utils\";\nimport { CampaignConfig, UserData } from \"../campaigns/type\";\nimport {\n calculateEstimatedRewards,\n calculateEstimatedTickets,\n calculateUserPoolReward,\n formatRewardAmount,\n formatTicketCount,\n calculateTicketProgress,\n} from \"./utils\";\n\ninterface RewardsDesktopUIProps {\n campaign?: CampaignConfig;\n userdata?: UserData;\n onLearnMore: () => void;\n onTradeNow: () => void;\n isMobile?: boolean;\n shouldShowJoinButton?: boolean;\n joinCampaign?: (data: { campaign_id: string | number }) => Promise<any>;\n isJoining?: boolean;\n hideConfig?: {\n estimatedRewards?: boolean;\n estimatedTickets?: boolean;\n };\n}\n\nexport const RewardsDesktopUI: FC<RewardsDesktopUIProps> = ({\n campaign,\n userdata,\n onLearnMore,\n onTradeNow,\n isMobile,\n shouldShowJoinButton,\n joinCampaign,\n isJoining,\n hideConfig,\n}) => {\n const { t } = useTranslation();\n // Use mock data for userdata if not provided\n const currentUserData = userdata;\n\n // Calculate estimated rewards\n const estimatedRewards =\n campaign && currentUserData\n ? calculateEstimatedRewards(currentUserData, campaign)\n : null;\n\n // Calculate estimated tickets\n const estimatedTickets =\n campaign?.ticket_rules && currentUserData\n ? calculateEstimatedTickets(currentUserData, campaign.ticket_rules)\n : 0;\n\n const rewardText = estimatedRewards\n ? formatRewardAmount(estimatedRewards.amount, estimatedRewards.currency)\n : \"0 USDC\";\n\n const ticketText = formatTicketCount(estimatedTickets);\n\n const canTrade = useMemo(() => {\n return (\n campaign?.start_time &&\n campaign?.end_time &&\n campaign.start_time < new Date().toISOString() &&\n campaign.end_time > new Date().toISOString()\n );\n }, [campaign]);\n\n const tooltipContent = useMemo(() => {\n // if (!campaign?.prize_pools || !currentUserData) {\n // return null;\n // }\n\n return (\n <div className=\"oui-flex oui-min-w-[240px] oui-flex-col oui-gap-1\">\n {campaign?.prize_pools?.map((pool) => {\n if (pool.tiers.length == 0) {\n return null;\n }\n const userPoolReward = currentUserData\n ? calculateUserPoolReward(currentUserData, pool)\n : 0;\n\n return (\n <div\n key={pool.pool_id}\n className=\"oui-flex oui-h-[18px] oui-items-center oui-justify-between\"\n >\n <Text\n size=\"2xs\"\n weight=\"semibold\"\n className=\"oui-text-base-contrast-54\"\n >\n {pool.label}\n </Text>\n <div className=\"oui-flex oui-items-center oui-gap-1\">\n <Text.numeral\n dp={2}\n size=\"2xs\"\n weight=\"semibold\"\n className=\"oui-text-base-contrast\"\n >\n {userPoolReward}\n </Text.numeral>\n <Text\n size=\"2xs\"\n weight=\"semibold\"\n className=\"oui-text-base-contrast\"\n >\n {pool.currency}\n </Text>\n </div>\n </div>\n );\n })}\n </div>\n );\n }, [campaign, currentUserData]);\n\n const ticketTooltipContent = useMemo(() => {\n const ticketRules = campaign?.ticket_rules;\n\n if (!ticketRules) {\n return null;\n }\n\n if (ticketRules.mode === \"linear\") {\n return (\n <div>\n {t(\"tradingLeaderboard.earnTickets\", {\n ticket: ticketRules?.linear?.tickets,\n amount: commify(ticketRules?.linear?.every || 0),\n })}\n </div>\n );\n }\n\n return (\n <div className=\"oui-flex oui-min-w-[240px] oui-flex-col oui-gap-1\">\n {ticketRules?.tiers?.map((tier) => {\n return (\n <div\n key={tier.value}\n className=\"h-[18px] oui-flex oui-items-center oui-justify-between oui-text-2xs oui-font-semibold\"\n >\n <Text.numeral\n currency=\"$\"\n suffix=\" volume\"\n dp={0}\n className=\"oui-text-base-contrast-54\"\n >\n {tier.value}\n </Text.numeral>\n <div className=\"oui-text-base-contrast\">\n {tier.tickets} tickets\n </div>\n </div>\n );\n })}\n </div>\n );\n }, [campaign]);\n\n const extraProps = useMemo(() => {\n if (\n !userdata ||\n !campaign?.ticket_rules ||\n campaign.end_time < new Date().toISOString() ||\n campaign.start_time > new Date().toISOString()\n ) {\n return {\n showExtraInfo: false,\n extraInfo: null,\n };\n }\n\n const progress = calculateTicketProgress(userdata, campaign.ticket_rules);\n\n if (!progress) {\n return {\n showExtraInfo: false,\n extraInfo: null,\n };\n }\n\n return {\n showExtraInfo: true,\n extraInfo: progress,\n };\n }, [campaign, userdata]);\n\n return (\n <div\n className={cn([\n \"oui-mx-auto oui-mb-10 oui-flex oui-max-w-[992px] oui-flex-col oui-pb-10\",\n isMobile ? \"oui-gap-3\" : \"oui-gap-6\",\n ])}\n >\n <div\n className={cn([\n \"oui-flex oui-w-full oui-items-stretch oui-gap-3\",\n isMobile ? \"oui-px-3\" : \"\",\n ])}\n >\n {!hideConfig?.estimatedRewards && (\n <RewardItem\n title={t(\"tradingLeaderboard.estimatedRewards\")}\n value={rewardText}\n showTooltip\n tooltip={tooltipContent}\n isMobile={isMobile}\n />\n )}\n <RewardItem\n showTooltip={!!campaign?.ticket_rules}\n title={t(\"tradingLeaderboard.estimatedTicketsEarned\")}\n value={ticketText}\n tooltip={ticketTooltipContent}\n {...extraProps}\n isMobile={isMobile}\n />\n </div>\n <div\n className={cn([\n \"oui-flex oui-justify-center oui-gap-3\",\n isMobile ? \"oui-px-3\" : \"\",\n ])}\n >\n {campaign?.rule_url && (\n <Button\n size={isMobile ? \"md\" : \"lg\"}\n variant=\"outlined\"\n className={cn([\n \"oui-border-[rgb(var(--oui-gradient-brand-start))] oui-text-[rgb(var(--oui-gradient-brand-start))] hover:oui-bg-[rgb(var(--oui-gradient-brand-start))]/[0.08] active:oui-bg-[rgb(var(--oui-gradient-brand-start))]/[0.08]\",\n isMobile ? \"oui-flex-1\" : \"oui-w-[140px]\",\n ])}\n onClick={onLearnMore}\n >\n {t(\"tradingLeaderboard.viewRules\")}\n </Button>\n )}\n {shouldShowJoinButton && (\n <Button\n size={isMobile ? \"md\" : \"lg\"}\n variant=\"gradient\"\n color=\"primary\"\n loading={isJoining}\n disabled={isJoining}\n className={cn([isMobile ? \"oui-flex-1\" : \"oui-w-[140px]\"])}\n onClick={() =>\n joinCampaign?.({ campaign_id: Number(campaign?.campaign_id) })\n }\n >\n {t(\"tradingLeaderboard.joinNow\")}\n </Button>\n )}\n {!shouldShowJoinButton && canTrade && (\n <Button\n size={isMobile ? \"md\" : \"lg\"}\n variant=\"gradient\"\n color=\"primary\"\n className={cn([isMobile ? \"oui-flex-1\" : \"oui-w-[140px]\"])}\n onClick={onTradeNow}\n >\n {t(\"tradingLeaderboard.tradeNow\")}\n </Button>\n )}\n </div>\n </div>\n );\n};\n\nconst RewardItem: FC<{\n title: string;\n value: string;\n showTooltip?: boolean;\n tooltip?: any;\n showExtraInfo?: boolean;\n extraInfo?: {\n percent: number;\n value: number;\n } | null;\n isMobile?: boolean;\n}> = (props) => {\n const [tooltipOpen, setTooltipOpen] = useState(false);\n\n const tooltipProps = useMemo(() => {\n if (!props.isMobile) {\n return {};\n }\n return {\n open: tooltipOpen,\n onOpenChange: setTooltipOpen,\n };\n }, [tooltipOpen, props.isMobile, setTooltipOpen]);\n\n return (\n <div className=\"oui-flex oui-flex-1 oui-flex-col oui-items-center oui-justify-center oui-rounded-2xl oui-bg-base-9 oui-px-5 oui-py-4\">\n <div\n className={cn([\n \"oui-text-base-contrast-54\",\n props.isMobile\n ? \"oui-h-[15px] oui-text-2xs oui-leading-[15px]\"\n : \"oui-text-sm oui-font-semibold\",\n ])}\n >\n {props.title}\n </div>\n <div className=\"oui-flex oui-items-center oui-gap-2\">\n <Text.gradient\n weight=\"bold\"\n color=\"brand\"\n className={cn([\n \"oui-trading-leaderboard-title\",\n props.isMobile\n ? \"oui-h-[16px] oui-text-base oui-leading-[16px]\"\n : \"oui-h-10 oui-text-[32px] oui-leading-10\",\n ])}\n >\n {props.value}\n </Text.gradient>\n {props.showTooltip && (\n <Tooltip content={props.tooltip} {...tooltipProps}>\n <div\n className=\"oui-flex oui-size-4 oui-items-center oui-justify-center\"\n onClick={() => setTooltipOpen(true)}\n >\n <InfoCircleIcon className=\"oui-cursor-pointer\" />\n </div>\n </Tooltip>\n )}\n </div>\n {props.showExtraInfo && (\n <div\n className={cn([\n \"oui-flex oui-flex-col oui-items-center oui-justify-end\",\n props.isMobile ? \"oui-mt-2\" : \"\",\n ])}\n >\n <div className=\"oui-flex oui-flex-col oui-items-center oui-gap-1 oui-text-2xs oui-font-semibold oui-text-base-contrast-36\">\n <div\n className={cn([\n \"oui-flex oui-h-[18px] oui-w-[225px] oui-items-center oui-rounded-[100px] oui-bg-base-5 oui-p-[2px]\",\n props.isMobile ? \"oui-w-full\" : \"oui-w-[225px]\",\n ])}\n >\n <div\n className={cn([\n \"oui-h-[14px] oui-rounded-[100px]\",\n \"oui-bg-[linear-gradient(270deg,rgb(var(--oui-gradient-brand-start))_0%,rgb(var(--oui-gradient-brand-end))_100%)]\",\n ])}\n style={{ width: `${props?.extraInfo?.percent}%` }}\n />\n </div>\n <div\n className={cn([\n \"oui-text-center oui-font-semibold\",\n props.isMobile ? \"oui-text-2xs oui-leading-[15px]\" : \"\",\n ])}\n >\n {/* @ts-ignore */}\n {props.extraInfo.atMax ? (\n <Trans i18nKey=\"tradingLeaderboard.maxTicketsAchieved\" />\n ) : (\n <Trans\n i18nKey=\"tradingLeaderboard.tradeForMoreTickets\"\n components={[\n <span key=\"0\" className=\"oui-text-base-contrast\">\n ${props?.extraInfo?.value?.toFixed(2)}\n </span>,\n ]}\n />\n )}\n </div>\n </div>\n </div>\n )}\n </div>\n );\n};\n","import { useScreen } from \"@orderly.network/ui\";\nimport { useCampaignsScript } from \"../campaigns/campaigns.script\";\nimport { CampaignRuleUI } from \"./rule\";\nimport { CampaignTermsUI } from \"./terms\";\n\nexport const RuleWidget = () => {\n const state = useCampaignsScript();\n const { isMobile } = useScreen();\n\n const rulesAndTerms = state.currentCampaign?.rule;\n\n if (\n state.currentCampaignId === \"general\" ||\n !state.currentCampaign?.rule_config\n ) {\n return null;\n }\n\n return (\n <>\n <CampaignRuleUI\n id={state.currentCampaign.rule_url || \"\"}\n className={isMobile ? \"oui-px-3\" : \"\"}\n rules={rulesAndTerms?.rule}\n ruleConfig={rulesAndTerms?.ruleConfig}\n isMobile={isMobile}\n />\n <CampaignTermsUI\n className={isMobile ? \"oui-px-3\" : \"\"}\n termsConfig={rulesAndTerms?.terms}\n isMobile={isMobile}\n />\n </>\n );\n};\n","import { FC } from \"react\";\nimport { useTranslation } from \"@orderly.network/i18n\";\nimport { cn } from \"@orderly.network/ui\";\nimport { LeaderboardTitle } from \"../../pages/leaderboard/page\";\nimport {\n DescriptionContent,\n DescriptionItem,\n DescriptionConfig,\n} from \"./description\";\n\ntype RuleUIProps = {\n id: string;\n className?: string;\n isMobile?: boolean;\n rules?: DescriptionItem[];\n ruleConfig?: DescriptionConfig;\n};\n\nexport const CampaignRuleUI: FC<RuleUIProps> = ({\n id,\n className,\n isMobile,\n rules,\n ruleConfig,\n}) => {\n const { t } = useTranslation();\n return (\n <div\n className={cn(\"oui-mx-auto oui-max-w-[992px] oui-py-10\", className)}\n id={id}\n >\n <LeaderboardTitle\n isMobile={isMobile}\n title={t(\"tradingLeaderboard.rules\")}\n />\n <DescriptionContent description={rules || []} config={ruleConfig} />\n </div>\n );\n};\n","import { FC } from \"react\";\nimport { cn } from \"@orderly.network/ui\";\n\n// import ReactMarkdown from \"react-markdown\";\n// import remarkGfm from \"remark-gfm\";\n\n// Enhanced type definition supporting multiple content formats\ntype ListStyle =\n | \"disc\"\n | \"decimal\"\n | \"none\"\n | \"circle\"\n | \"square\"\n | \"decimal-leading-zero\"\n | \"lower-alpha\"\n | \"upper-alpha\"\n | \"lower-roman\"\n | \"upper-roman\";\n\nexport type DescriptionItem = {\n content: string; // Support markdown syntax, plain text, or image URL\n type: \"markdown\" | \"text\" | \"image\";\n alt?: string; // For images\n className?: string; // Custom styling\n listStyle?: ListStyle; // List style for ul/ol elements\n listClassName?: string; // Custom list container class\n children?: DescriptionItem[];\n};\n\nexport type DescriptionConfig = {\n listStyle?: ListStyle; // Global list style\n listClassName?: string; // Global list container class\n};\n\n// Utility function to get list style classes\nconst getListStyleClass = (style: ListStyle): string => {\n const styleMap: Record<ListStyle, string> = {\n disc: \"oui-list-disc\",\n decimal: \"oui-list-decimal\",\n none: \"oui-list-none\",\n circle: \"oui-list-disc\", // Tailwind doesn't have circle, fallback to disc\n square: \"oui-list-disc\", // Tailwind doesn't have square, fallback to disc\n \"decimal-leading-zero\": \"oui-list-decimal\",\n \"lower-alpha\": \"oui-list-decimal\", // Fallback\n \"upper-alpha\": \"oui-list-decimal\", // Fallback\n \"lower-roman\": \"oui-list-decimal\", // Fallback\n \"upper-roman\": \"oui-list-decimal\", // Fallback\n };\n return styleMap[style] || \"oui-list-disc\";\n};\n\n// Custom rich text parser (no external dependencies)\nconst parseRichText = (text: string): JSX.Element[] => {\n const parts: JSX.Element[] = [];\n let currentIndex = 0;\n let key = 0;\n\n // Parse **bold** syntax\n const boldRegex = /\\*\\*(.*?)\\*\\*/g;\n // Parse [link text](url) syntax\n const linkRegex = /\\[([^\\]]+)\\]\\(([^)]+)\\)/g;\n // Parse  syntax\n const imageRegex = /!\\[([^\\]]*)\\]\\(([^)]+)\\)/g;\n\n const allMatches: Array<{\n type: \"bold\" | \"link\" | \"image\";\n match: RegExpMatchArray;\n index: number;\n }> = [];\n\n // Find all matches\n let match;\n while ((match = boldRegex.exec(text)) !== null) {\n allMatches.push({ type: \"bold\", match, index: match.index });\n }\n while ((match = linkRegex.exec(text)) !== null) {\n allMatches.push({ type: \"link\", match, index: match.index });\n }\n while ((match = imageRegex.exec(text)) !== null) {\n allMatches.push({ type: \"image\", match, index: match.index });\n }\n\n // Sort by index\n allMatches.sort((a, b) => a.index - b.index);\n\n for (const { type, match } of allMatches) {\n // Add text before match\n if (match.index !== undefined && match.index > currentIndex) {\n const beforeText = text.slice(currentIndex, match.index);\n if (beforeText) {\n parts.push(<span key={key++}>{beforeText}</span>);\n }\n }\n\n // Add formatted element\n switch (type) {\n case \"bold\":\n parts.push(\n <strong\n key={key++}\n className=\"oui-font-bold oui-text-base-contrast-54\"\n >\n {match[1]}\n </strong>,\n );\n break;\n case \"link\":\n parts.push(\n <a\n key={key++}\n href={match[2]}\n className=\"oui-text-base-contrast-54 oui-underline hover:oui-text-base-contrast-54\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {match[1]}\n </a>,\n );\n break;\n case \"image\":\n parts.push(\n <img\n key={key++}\n src={match[2]}\n alt={match[1]}\n className=\"oui-my-2 oui-block oui-h-auto oui-max-w-full\"\n />,\n );\n break;\n }\n\n currentIndex = (match.index ?? 0) + match[0].length;\n }\n\n // Add remaining text\n if (currentIndex < text.length) {\n const remainingText = text.slice(currentIndex);\n if (remainingText) {\n parts.push(<span key={key++}>{remainingText}</span>);\n }\n }\n\n return parts.length > 0 ? parts : [<span key={0}>{text}</span>];\n};\n\n// Custom rich text implementation (recommended for lightweight needs)\nexport const DescriptionContent: FC<{\n description: DescriptionItem[];\n config?: DescriptionConfig;\n}> = ({ description, config }) => {\n const renderContent = (contents: DescriptionItem[], level: number = 0) => {\n // Determine list style - item level overrides global config\n const defaultListStyle = config?.listStyle || \"disc\";\n const hasListItems = contents.some((item) => item.children?.length);\n\n if (!hasListItems && contents.length === 1) {\n // Single item without children - render without list wrapper\n const content = contents[0];\n return (\n <div className={cn(\"oui-mb-2\", content.className)}>\n {renderContentItem(content)}\n </div>\n );\n }\n\n return (\n <ul\n className={cn(\n // Use list-outside for proper alignment\n \"oui-list-outside\",\n // Add left padding for proper spacing\n level === 0 ? \"oui-pl-5\" : \"oui-pl-4\",\n // Get list style class\n getListStyleClass(defaultListStyle),\n // Custom list container class\n config?.listClassName,\n )}\n >\n {contents.map((content, index) => {\n const itemListStyle = content.listStyle || defaultListStyle;\n\n return (\n <li\n key={`${content.content}-${index}`}\n className={cn(\n \"oui-mb-1 oui-leading-relaxed\",\n // Override list style if specified on item\n content.listStyle && getListStyleClass(itemListStyle),\n content.className,\n )}\n >\n {renderContentItem(content)}\n {content?.children?.length && (\n <div className=\"oui-mt-2 oui-text-sm oui-text-base-contrast-36\">\n {renderContent(content.children, level + 1)}\n </div>\n )}\n </li>\n );\n })}\n </ul>\n );\n };\n\n const renderContentItem = (content: DescriptionItem) => {\n if (content.type === \"image\") {\n return (\n <img\n src={content.content}\n alt={content.alt || \"\"}\n className=\"oui-my-2 oui-h-auto oui-max-w-full\"\n />\n );\n }\n\n // Both markdown and text use the rich text parser\n return (\n <div className=\"rich-text-content inline\">\n {parseRichText(content.content)}\n </div>\n );\n };\n\n return (\n <div\n className={cn(\n \"oui-text-sm oui-font-semibold oui-leading-[28px] oui-text-base-contrast-54\",\n )}\n >\n {renderContent(description)}\n </div>\n );\n};\n\n// Alternative: React-markdown implementation (requires additional dependencies)\nexport const MarkdownDescriptionContent: FC<{\n description: DescriptionItem[];\n}> = ({ description }) => {\n const renderContent = (contents: DescriptionItem[]) => {\n return (\n <ul className=\"oui-list-inside oui-list-disc\">\n {contents.map((content, index) => (\n <li key={`${content.content}-${index}`} className={content.className}>\n {content.type === \"image\" ? (\n <img\n src={content.content}\n alt={content.alt || \"\"}\n className=\"oui-my-2 oui-h-auto oui-max-w-full\"\n />\n ) : (\n <div>{content.content}</div>\n )}\n {content?.children?.length && (\n <div className=\"oui-ml-4\">{renderContent(content.children)}</div>\n )}\n </li>\n ))}\n </ul>\n );\n };\n\n return (\n <div\n className={cn(\n \"oui-text-sm oui-font-semibold oui-leading-[28px] oui-text-base-contrast-54\",\n )}\n >\n {renderContent(description)}\n </div>\n );\n};\n","import { FC } from \"react\";\nimport { useTranslation } from \"@orderly.network/i18n\";\nimport { cn } from \"@orderly.network/ui\";\nimport { LeaderboardTitle } from \"../../pages/leaderboard/page\";\nimport { DescriptionContent, DescriptionItem } from \"./description\";\n\ntype TermsUIProps = {\n className?: string;\n isMobile?: boolean;\n termsConfig?: DescriptionItem[];\n};\n\nexport const CampaignTermsUI: FC<TermsUIProps> = ({\n className,\n isMobile,\n termsConfig,\n}) => {\n const { t } = useTranslation();\n return (\n <div className={cn(\"oui-mx-auto oui-max-w-[992px] oui-py-10\", className)}>\n <LeaderboardTitle\n isMobile={isMobile}\n title={t(\"tradingLeaderboard.termsAndConditions\")}\n />\n <DescriptionContent description={termsConfig || []} />\n </div>\n );\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/deprecated/components/provider/index.tsx","../src/deprecated/pages/leaderboard/leaderboard.mobile.ui.tsx","../src/deprecated/components/campaigns/campaigns.widget.tsx","../src/deprecated/components/campaigns/campaigns.mobile.ui.tsx","../src/deprecated/components/campaigns/campaigns.script.ts","../src/utils.ts","../src/deprecated/components/campaigns/campaigns.ui.tsx","../src/deprecated/components/tradingList/tradingList.mobile.ui.tsx","../src/deprecated/components/tradingList/column.tsx","../src/deprecated/components/tradingList/tradingList.script.ts","../src/hooks/useEndReached.ts","../src/deprecated/components/tradingList/tradingList.ui.tsx","../src/deprecated/components/tradingList/tradingList.widget.tsx","../src/deprecated/pages/leaderboard/leaderboard.script.ts","../src/deprecated/pages/leaderboard/leaderboard.ui.tsx","../src/deprecated/pages/leaderboard/leaderboard.widget.tsx","../src/components/provider/index.tsx","../src/components/ranking/shared/ranking.ui.tsx","../src/components/ranking/shared/column.tsx","../src/components/ranking/shared/util.ts","../src/components/ranking/generalRanking/generalRanking.script.ts","../src/components/ranking/generalRanking/generalRanking.widget.tsx","../src/components/ranking/campaignRanking/campaignRanking.script.ts","../src/components/rewards/utils.ts","../src/components/ranking/campaignRanking/campaignRanking.widget.tsx","../src/components/leaderboard/generalLeaderboard/generalLeaderboard.script.ts","../src/components/leaderboard/generalLeaderboard/generalLeaderboard.ui.tsx","../src/components/leaderboard/shared/LeaderboardFilter.tsx","../src/components/leaderboard/shared/LeaderboardTabs.tsx","../src/components/leaderboard/generalLeaderboard/generalLeaderboard.widget.tsx","../src/components/leaderboard/campaignLeaderboard/campaignLeaderboard.script.ts","../src/components/leaderboard/campaignLeaderboard/campaignLeaderboard.ui.tsx","../src/components/leaderboard/campaignLeaderboard/campaignLeaderboard.widget.tsx","../src/pages/leaderboard/page.tsx","../src/components/background/index.tsx","../src/components/campaigns/campaigns.widget.tsx","../src/components/campaigns/campaigns.content.desktop.ui.tsx","../src/components/campaigns/utils.ts","../src/components/campaigns/type.ts","../src/components/campaigns/campaigns.script.ts","../src/components/campaigns/components/time.desktop.ui.tsx","../src/components/campaigns/components/axis.tsx","../src/components/campaigns/components/countdown.tsx","../src/components/campaigns/header/campaigns.header.desktop.ui.tsx","../src/components/campaigns/DefaultCampaign.tsx","../src/components/campaigns/campaign.item.ui.tsx","../src/components/campaigns/header/campaigns.header.mobile.ui.tsx","../src/components/campaigns/header/campaigns.header.widget.tsx","../src/components/rewards/rewards.widget.tsx","../src/components/rewards/rewards.desktop.ui.tsx","../src/components/rule/rule.widget.tsx","../src/components/rule/rule.tsx","../src/components/rule/description.tsx","../src/components/rule/terms.tsx"],"names":["createContext","useContext","useMemo","jsx","TradingLeaderboardContext","TradingLeaderboardProvider","props","href","campaigns","backgroundSrc","children","memoizedValue","useTradingLeaderboardContext","cn","Flex","useScreen","useTranslation","Box","Text","Button","Select","jsxs","scrollIndicatorWidth","scrollIndicatorHeight","MobileCampaigns","Header","campaign","CampaignItem","ScrollIndicator","title","description","image","displayTime","learnMoreUrl","tradingUrl","t","style","scrollIndex","list","item","index","useEffect","useState","useEmblaCarousel","useTrack","TrackerEventName","format","subDays","getDateRange","offsetDay","formatDateRange","date","getUTCDateInfo","year","month","day","hours","minutes","formatCampaignDate","monthNames","formatUpdateDate","timestamp","time","useCampaignsScript","category","setCategory","track","tracking","filterCampaigns","now","acc","startTime","endTime","options","currentCampaigns","firstAvailableCategory","onCategoryChange","value","setScrollIndex","emblaRef","emblaApi","onLearnMore","onTradeNow","Campaigns","CampaignsWidget","state","isMobile","DataFilter","DataTable","Spinner","useCallback","useRef","differenceInDays","useAccount","useConfig","useInfiniteQuery","useQuery","usePrivateQuery","usePagination","useEndReached","sentinelRef","onEndReached","observer","cb","handleObserver","entries","entry","FilterDays","useTradingListScript","searchValue","setSearchValue","initialSort","sort","setSort","brokerId","dateRange","filterDay","updateFilterDay","filterItems","onFilter","useFilter","page","pageSize","setPage","parsePagination","getUrl","args","searchParams","prefix","data","isLoading","res","infiniteData","size","setSize","isValidating","pageIndex","previousPageData","top100Data","userDataRes","getAddressRank","address","isSameAddress","userDataList","getRowKey","addRankForList","total","rank","dataSource","rankList","dataList","flatList","pagination","onSearchValueChange","clearSearchValue","onSort","setFilterDay","setDateRange","filter","newDateRange","address1","address2","Fragment","useTradingListColumns","record","isYou","MobileTradingList","column","isFirst","isLast","CloseCircleFillIcon","Input","TradingList","SearchIcon","TradingListWidget","MobileLeaderboardWidget","isVideoSrc","src","extension","useLeaderboardScript","showCampaigns","isVideo","Leaderboard","renderBackground","linearGradient","LeaderboardWidget","parseISO","sortWith","descend","useMemoizedFn","campaignId","dataAdapter","onCampaignChange","userData","setUserData","updatedTime","setUpdatedTime","generateCode","generateCodeMutate","currentCampaign","filteredCampaigns","memoCampaignChange","id","getCurrentAddressRowKey","useRankingColumns","fields","enableSort","rankIcon","badgeImg","FirstRankIcon","first_badge_default","SecondRankIcon","second_badge_default","ThirdRankIcon","third_badge_default","linearGradientText","Ranking","onRow","isSecond","isThird","onCell","isFirstColumn","isLastColumn","isRank","useGeneralRankingScript","sortKey","formatData","GeneralRankingWidget","rest","getUserMetricValue","userdata","metric","estimateUserRank","userMetricValue","totalParticipants","findRewardInPool","pool","estimatedRank","tier","isInTier","start","end","calculateEstimatedRewards","totalEstimatedReward","mainCurrency","calculateEstimatedTickets","ticketRules","calculateTieredTickets","calculateLinearTickets","metricValue","tiers","sortedTiers","a","b","linearRule","formatRewardAmount","amount","currency","formatTicketCount","tickets","calculateUserPoolReward","calculateTicketProgress","every","nextTier","progress","nextTierValue","currentTier","i","useCampaignRankingScript","isCustomData","customData","getUserUrl","_data","rewards","CampaignRankingWidget","useGeneralLeaderboardScript","activeTab","setActiveTab","filterState","searchState","useSearch","Divider","LeaderboardFilter","input","dateRangeView","filterDayView","TabPanel","Tabs","LeaderboardTabs","updateTime","showVolume","showPnl","metrics","isMobileGeneral","renderTabs","GeneralLeaderboard","GeneralLeaderboardWidget","useCampaignLeaderboardScript","excludeColumns","difference","CampaignLeaderboard","CampaignLeaderboardWidget","Background","InfoCircleIcon","Tooltip","ChevronRightIcon","AuthGuard","i18n","CampaignTagEnum","DEFAULT_TIMEZONE_DISPLAY","getUserTimezoneDisplay","getCampaignTag","userReferralCode","currentTime","formatCampaignDateRange","showTimezone","startDate","endDate","startFormatted","endFormatted","timezoneDisplay","getTradingVolume","statistics","getTotalPrizePool","currencyTotals","currencies","getTicketPrizePool","formatPrizeAmount","generateCampaignTimeline","rewardTime","timeline","getTimelineType","isNow","formatTimeDisplay","formatted","CampaignsContentDesktopUI","classNames","shouldShowJoinButton","joinCampaign","isJoining","canTrade","bgSrc","tooltipOpen","setTooltipOpen","tooltipProps","tradingVolume","totalPrizePool","ticketPrizePool","showTradeButton","isCampaignStarted","highlightPool","tooltipContent","useMutation","AccountStatusEnum","toast","currentCampaignId","symbols","isCampaignEnded","stats","userCampaigns","refreshUserCampaigns","isParticipated","doJoinCampaign","joinError","result","error","CampaignsAxis","points","activeIndex","point","AxisPoint","getLineBackgroundClass","segmentIndex","widthPercentage","CampaignsAxisMobile","type","Circle","TimeUnit","label","CampaignsCountdown","timeLeft","setTimeLeft","isStarted","setIsStarted","calculateTimeLeft","hasStarted","days","seconds","timer","titleText","timeUnits","unit","CampaignsTimeDesktopUI","timelineData","ChevronLeftIcon","DefaultCampaign","className","CampaignItemUI","active","tag","CampaignTag","tagText","CampaignsHeaderUI","isLargeScreen","setIsLargeScreen","canScrollPrev","setCanScrollPrev","canScrollNext","setCanScrollNext","checkScreenSize","updateScrollAvailability","slidesInView","lastSlideIndex","isLastSlideInView","scrollPrev","scrollNext","slideStyle","shouldHideScrollButtons","memo","CampaignsHeaderMobileUI","hasInitialScrolled","isInitializing","allCampaignItems","selectedIndex","selectedCampaign","scrollToCurrentCampaign","targetIndex","CampaignsHeaderWidget","contentClassNames","Trans","commify","RewardsDesktopUI","hideConfig","currentUserData","estimatedRewards","estimatedTickets","rewardText","ticketText","userPoolReward","ticketTooltipContent","extraProps","RewardItem","RewardsWidget","LeaderboardTitle","getListStyleClass","parseRichText","text","parts","currentIndex","key","boldRegex","linkRegex","imageRegex","allMatches","match","beforeText","remainingText","DescriptionContent","config","renderContent","contents","level","defaultListStyle","content","renderContentItem","itemListStyle","CampaignRuleUI","rules","ruleConfig","EMPTY_LIST","CampaignTermsUI","termsConfig","RuleWidget","rulesAndTerms","LeaderboardPage","LeaderboardSection"],"mappings":"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","sourcesContent":["import React, { createContext, useContext, useMemo } from \"react\";\n\nexport type Campaign = {\n title: string;\n description: string;\n image: string;\n startTime: Date | string;\n endTime: Date | string;\n href:\n | string\n | {\n /** learn more url */\n learnMore: string;\n /** trading url, if provided, will override default trading now button url */\n trading: string;\n };\n};\n\n/**\n * Trading leaderboard provider state\n */\nexport type TradingLeaderboardState = {\n /** campaigns config, if not provided, will not show campaigns section */\n campaigns?: Campaign[];\n /** background src, it can be a image resource or video resource */\n backgroundSrc?: string;\n href?: {\n /** default trading now button url */\n trading: string;\n };\n};\n\n/**\n * Trading leaderboard context\n */\nexport const TradingLeaderboardContext = createContext<TradingLeaderboardState>(\n {},\n);\n\nexport type TradingLeaderboardProviderProps =\n React.PropsWithChildren<TradingLeaderboardState>;\n\nexport const TradingLeaderboardProvider: React.FC<\n Readonly<TradingLeaderboardProviderProps>\n> = (props) => {\n const { href, campaigns, backgroundSrc, children } = props;\n const memoizedValue = useMemo<TradingLeaderboardState>(() => {\n return {\n href: href,\n campaigns: campaigns,\n backgroundSrc: backgroundSrc,\n };\n }, [href, campaigns, backgroundSrc]);\n return (\n <TradingLeaderboardContext.Provider value={memoizedValue}>\n {children}\n </TradingLeaderboardContext.Provider>\n );\n};\n\nexport const useTradingLeaderboardContext = () => {\n return useContext(TradingLeaderboardContext);\n};\n","import { FC } from \"react\";\nimport { cn, Flex } from \"@orderly.network/ui\";\nimport { CampaignsWidget } from \"../../components/campaigns\";\nimport { TradingListWidget } from \"../../components/tradingList\";\nimport { LeaderboardScriptReturn } from \"./leaderboard.script\";\n\nexport type LeaderboardProps = {\n style?: React.CSSProperties;\n className?: string;\n} & LeaderboardScriptReturn;\n\nexport const MobileLeaderboardWidget: FC<LeaderboardProps> = (props) => {\n // const renderBackground = () => {\n // const linearGradient =\n // \"linear-gradient(180deg, rgba(var(--oui-color-base-10) / 0.3) 0%, rgba(var(--oui-color-base-10) / 0) 70%, rgba(var(--oui-color-base-10) / 1) 100%)\";\n\n // if (props.isVideo) {\n // return (\n // <div\n // className={cn(\"oui-absolute oui-left-0 oui-top-0\", \"oui-size-full\")}\n // >\n // <div\n // style={{\n // backgroundImage: linearGradient,\n // backgroundSize: \"cover\",\n // backgroundRepeat: \"no-repeat\",\n // }}\n // className={cn(\"oui-absolute oui-left-0 oui-top-0\", \"oui-size-full\")}\n // />\n // <video\n // playsInline\n // // eslint-disable-next-line react/no-unknown-property\n // webkit-playsinline // need to use this prop to ban full screen in iphone\n // autoPlay\n // loop\n // muted\n // className={cn(\n // // rest style\n // \"oui-pointer-events-none oui-border-none oui-bg-transparent oui-outline-none\",\n // \"oui-size-full\",\n // // \"oui-absolute oui-top-0 oui-left-0\",\n // \"oui-object-cover\",\n // \"oui-opacity-50\",\n // )}\n // // ref={(video) => {\n // // if (video) {\n // // video.setAttribute(\"playsinline\", \"true\");\n // // video.setAttribute(\"webkit-playsinline\", \"true\");\n // // }\n // // }}\n // >\n // <source src={props.backgroundSrc} type=\"video/mp4\" />\n // <source src={props.backgroundSrc} type=\"video/webm\" />\n // <source src={props.backgroundSrc} type=\"video/ogg\" />\n // <source src={props.backgroundSrc} type=\"video/avi\" />\n // Your browser does not support the video tag.\n // </video>\n // </div>\n // );\n // }\n\n // if (props.backgroundSrc) {\n // return (\n // <div\n // style={{\n // backgroundImage: `${linearGradient}, url(${props.backgroundSrc}) `,\n // backgroundSize: \"cover\",\n // backgroundRepeat: \"no-repeat\",\n // }}\n // className={cn(\n // \"oui-absolute oui-left-0 oui-top-0\",\n // \"oui-size-full\",\n // \"oui-opacity-50\",\n // )}\n // />\n // );\n // }\n // };\n return (\n <div\n style={{\n paddingBottom: \"calc(64px + env(safe-area-inset-bottom))\",\n }}\n className={cn(\n \"oui-relative oui-grid oui-h-[calc(100vh-44px)] oui-gap-1 oui-bg-base-10\",\n \"oui-mix-blend-screen\",\n props.className,\n )}\n >\n {/* {renderBackground()} */}\n <Flex\n direction=\"column\"\n gapY={3}\n height=\"100%\"\n px={3}\n pt={3}\n pb={3}\n className={cn(\n \"oui-trading-leaderboard-mobile oui-custom-scrollbar oui-overflow-y-auto\",\n \"oui-relative oui-h-[calc(100vh_-_64px)]\",\n )}\n >\n {props.showCampaigns && <CampaignsWidget />}\n <TradingListWidget />\n </Flex>\n </div>\n );\n};\n","import { FC } from \"react\";\nimport { useScreen } from \"@orderly.network/ui\";\nimport { MobileCampaigns } from \"./campaigns.mobile.ui\";\nimport { useCampaignsScript } from \"./campaigns.script\";\nimport { Campaigns } from \"./campaigns.ui\";\n\nexport type CampaignsWidgetProps = {\n className?: string;\n style?: React.CSSProperties;\n};\n\nexport const CampaignsWidget: FC<CampaignsWidgetProps> = (props) => {\n const state = useCampaignsScript();\n const { isMobile } = useScreen();\n\n if (isMobile) {\n return (\n <MobileCampaigns\n {...state}\n className={props.className}\n style={props.style}\n />\n );\n }\n return (\n <Campaigns {...state} className={props.className} style={props.style} />\n );\n};\n","import { FC } from \"react\";\nimport { useTranslation } from \"@orderly.network/i18n\";\nimport { cn, Box, Text, Flex, Button, Select } from \"@orderly.network/ui\";\nimport { CampaignsScriptReturn, CurrentCampaigns } from \"./campaigns.script\";\n\nexport type CampaignsProps = {\n className?: string;\n style?: React.CSSProperties;\n} & CampaignsScriptReturn;\n\nconst scrollIndicatorWidth = 25;\nconst scrollIndicatorHeight = 6;\n\nexport const MobileCampaigns: FC<CampaignsProps> = (props) => {\n if (props.currentCampaigns.length === 0) {\n return null;\n }\n\n return (\n <Box\n width=\"100%\"\n intensity={900}\n p={3}\n className={cn(\n \"oui-mobile-trading-leaderboard-campaigns oui-rounded-[20px]\",\n props.className,\n )}\n style={props.style}\n >\n <Header {...props} />\n <Box\n r=\"xl\"\n mt={3}\n ref={props.enableScroll ? props.emblaRef : undefined}\n className={cn(\n \"oui-w-full oui-min-w-0 oui-overflow-hidden\",\n \"oui-select-none oui-cursor-pointer\",\n )}\n >\n <Flex>\n {props.currentCampaigns.map((campaign) => {\n return <CampaignItem key={campaign.title} campaign={campaign} />;\n })}\n </Flex>\n </Box>\n {props.enableScroll && (\n <ScrollIndicator\n style={{\n width: scrollIndicatorWidth * props.currentCampaigns.length,\n }}\n list={props.currentCampaigns}\n scrollIndex={props.scrollIndex}\n scrollTo={props.emblaApi?.scrollTo}\n />\n )}\n </Box>\n );\n};\n\nconst Header: FC<CampaignsScriptReturn> = (props) => {\n const { t } = useTranslation();\n\n return (\n <Flex justify=\"between\" itemAlign=\"center\">\n <Text size=\"base\" intensity={80}>\n {t(\"tradingLeaderboard.campaigns\")}\n </Text>\n <Select.options\n size={\"xs\"}\n value={props.category}\n onValueChange={props.onCategoryChange}\n options={props.options}\n classNames={{\n // set the width of the trigger to the width of the content\n trigger: \"oui-w-[--radix-select-content-available-width]\",\n }}\n />\n </Flex>\n );\n};\n\nconst CampaignItem: FC<{ campaign: CurrentCampaigns }> = ({ campaign }) => {\n const { title, description, image, displayTime, learnMoreUrl, tradingUrl } =\n campaign;\n const { t } = useTranslation();\n\n return (\n <Box intensity={800} r=\"xl\" className=\"oui-flex-[0_0_100%]\">\n <img\n className=\"oui-w-full oui-h-[calc((100vw-48px)/2)] oui-rounded-t-xl oui-object-fill\"\n src={image}\n alt={title}\n />\n\n <Flex\n itemAlign=\"start\"\n justify=\"between\"\n direction=\"column\"\n height=\"100%\"\n p={4}\n gapY={3}\n className=\"oui-font-semibold\"\n >\n <Flex direction=\"column\" itemAlign=\"start\" gapY={1}>\n <Text size=\"sm\">{title}</Text>\n <Text size=\"2xs\" intensity={54}>\n {displayTime}\n </Text>\n <Text size=\"2xs\" intensity={36}>\n {description}\n </Text>\n </Flex>\n <Flex justify=\"between\" width=\"100%\" gapX={3}>\n <Button\n variant=\"outlined\"\n color=\"secondary\"\n fullWidth\n size=\"md\"\n onClick={() => {\n window.open(learnMoreUrl, \"_blank\");\n }}\n >\n {t(\"tradingLeaderboard.learnMore\")}\n </Button>\n <Button\n size=\"md\"\n fullWidth\n onClick={() => {\n window.open(tradingUrl, \"_self\");\n }}\n >\n {t(\"tradingLeaderboard.tradeNow\")}\n </Button>\n </Flex>\n </Flex>\n </Box>\n );\n};\n\ninterface ScrollIndicatorProps {\n style?: React.CSSProperties;\n list: CurrentCampaigns[];\n scrollIndex: number;\n scrollTo?: (index: number) => void;\n}\n\nconst ScrollIndicator: React.FC<ScrollIndicatorProps> = (props) => {\n const { style, scrollIndex, list } = props;\n\n return (\n <Flex\n mt={3}\n r=\"full\"\n height={scrollIndicatorHeight}\n className={cn(\"oui-bg-line oui-mx-auto oui-relative\")}\n style={props.style}\n >\n {list.map((item, index) => {\n return (\n <Box\n key={index}\n width={scrollIndicatorWidth}\n height={scrollIndicatorHeight}\n onClick={() => {\n props.scrollTo?.(index);\n }}\n r=\"full\"\n className=\"oui-cursor-pointer\"\n />\n );\n })}\n <Box\n width={scrollIndicatorWidth}\n height={scrollIndicatorHeight}\n r=\"full\"\n className={cn(\n \"oui-absolute oui-left-0 oui-top-0\",\n \"oui-transition-all oui-duration-300\",\n \"oui-bg-primary\",\n )}\n style={{\n transform: `translateX(${scrollIndex * scrollIndicatorWidth}px)`,\n }}\n />\n </Flex>\n );\n};\n","import { useEffect, useMemo, useState } from \"react\";\nimport useEmblaCarousel from \"embla-carousel-react\";\nimport { useTrack } from \"@orderly.network/hooks\";\nimport { useTranslation } from \"@orderly.network/i18n\";\nimport { TrackerEventName } from \"@orderly.network/types\";\nimport { formatCampaignDate } from \"../../../utils\";\nimport { useTradingLeaderboardContext, Campaign } from \"../provider\";\n\nexport type CampaignsScriptReturn = ReturnType<typeof useCampaignsScript>;\n\n// Define the type for our categorized campaigns\ntype CategorizedCampaigns = {\n ongoing: Campaign[];\n past: Campaign[];\n future: Campaign[];\n};\n\nexport type CurrentCampaigns = Campaign & {\n displayTime: string;\n learnMoreUrl: string;\n tradingUrl: string;\n};\n\nexport type TEmblaApi = {\n scrollTo?: (index: number) => void;\n};\n\ntype CategoryKey = keyof CategorizedCampaigns;\n\nexport function useCampaignsScript() {\n const { t } = useTranslation();\n const { campaigns = [], href } = useTradingLeaderboardContext();\n const [category, setCategory] = useState<CategoryKey>(\"ongoing\");\n\n const { track, tracking } = useTrack();\n\n const filterCampaigns = useMemo(() => {\n const now = new Date();\n\n return campaigns.reduce<CategorizedCampaigns>(\n (acc, campaign) => {\n const startTime = new Date(campaign.startTime);\n const endTime = new Date(campaign.endTime);\n\n if (now >= startTime && now <= endTime) {\n acc.ongoing.push(campaign);\n } else if (now > endTime) {\n acc.past.push(campaign);\n } else {\n acc.future.push(campaign);\n }\n\n return acc;\n },\n { ongoing: [], past: [], future: [] },\n );\n }, [campaigns]);\n\n const options = useMemo(() => {\n const opts: { label: string; value: CategoryKey }[] = [\n { label: t(\"tradingLeaderboard.ongoing\"), value: \"ongoing\" },\n { label: t(\"tradingLeaderboard.future\"), value: \"future\" },\n { label: t(\"tradingLeaderboard.past\"), value: \"past\" },\n ];\n\n // Filter out categories with no campaigns and map to the required format\n return opts.filter((item) => filterCampaigns[item.value].length > 0);\n }, [filterCampaigns, t]);\n\n const currentCampaigns = useMemo(() => {\n const list = filterCampaigns[category];\n return list.map((campaign) => {\n const { startTime, endTime } = campaign;\n\n let learnMoreUrl: string;\n let tradingUrl = href?.trading!;\n\n if (typeof campaign.href === \"object\") {\n learnMoreUrl = campaign.href.learnMore;\n tradingUrl = campaign.href.trading;\n } else {\n learnMoreUrl = campaign.href;\n }\n\n return {\n ...campaign,\n displayTime: `${formatCampaignDate(startTime)} - ${formatCampaignDate(\n endTime,\n )} UTC`,\n learnMoreUrl,\n tradingUrl,\n };\n });\n }, [filterCampaigns, category, href]);\n\n useEffect(() => {\n // Find the first non-empty category\n const categoryKeys: CategoryKey[] = [\"ongoing\", \"future\", \"past\"];\n\n const firstAvailableCategory = categoryKeys.find(\n (item) => filterCampaigns[item].length > 0,\n );\n\n if (firstAvailableCategory) {\n setCategory(firstAvailableCategory);\n }\n }, [filterCampaigns]);\n\n const onCategoryChange = (value: string) => {\n setCategory(value as CategoryKey);\n };\n const [scrollIndex, setScrollIndex] = useState(0);\n\n const [emblaRef, emblaApi] = useEmblaCarousel({\n loop: false,\n slidesToScroll: \"auto\",\n });\n\n useEffect(() => {\n emblaApi?.on(\"select\", () => {\n setScrollIndex(emblaApi?.selectedScrollSnap());\n });\n }, [emblaApi]);\n\n const onLearnMore = (campaign: CurrentCampaigns) => {\n track(TrackerEventName.leaderboardCampaignClickLearnMore, {\n campaign_title: campaign.title,\n });\n window.open(campaign.learnMoreUrl, \"_blank\");\n };\n\n const onTradeNow = (campaign: CurrentCampaigns) => {\n tracking(TrackerEventName.leaderboardCampaignClickTradeNow, {\n campaign_title: campaign.title,\n });\n window.open(campaign.tradingUrl, \"_self\");\n };\n\n return {\n options,\n currentCampaigns,\n category,\n onCategoryChange,\n tradingUrl: href?.trading,\n emblaRef,\n emblaApi: emblaApi as TEmblaApi,\n scrollIndex,\n enableScroll: currentCampaigns?.length > 1,\n onLearnMore,\n onTradeNow,\n };\n}\n","import { format, subDays } from \"date-fns\";\n\nexport const getDateRange = (offsetDay: number) => {\n return {\n from: subDays(new Date(), offsetDay - 1)!,\n to: new Date()!,\n };\n};\n\n/**\n * Format a date to \"yyyy-MM-dd\" format (e.g., \"2025-03-10\")\n * @param date The date to format\n * @returns Formatted date string\n */\nexport const formatDateRange = (date: Date): string => {\n return format(date, \"yyyy-MM-dd\");\n};\n\nfunction getUTCDateInfo(date: Date) {\n const year = date.getUTCFullYear();\n const month = date.getUTCMonth();\n const day = date.getUTCDate();\n const hours = String(date.getUTCHours()).padStart(2, \"0\");\n const minutes = String(date.getUTCMinutes()).padStart(2, \"0\");\n\n return { year, month, day, hours, minutes };\n}\n\nexport function formatCampaignDate(date: Date | string): string {\n const monthNames = [\n \"Jan\",\n \"Feb\",\n \"Mar\",\n \"Apr\",\n \"May\",\n \"Jun\",\n \"Jul\",\n \"Aug\",\n \"Sep\",\n \"Oct\",\n \"Nov\",\n \"Dec\",\n ];\n if (typeof date === \"string\") {\n date = new Date(date);\n }\n const { year, month, day, hours, minutes } = getUTCDateInfo(date);\n return `${monthNames[month]} ${day}, ${year} ${hours}:${minutes}`;\n}\n\nexport function formatUpdateDate(timestamp: number) {\n const time = new Date(timestamp);\n try {\n return format(time, \"yyyy-MM-dd HH:mm\");\n } catch (error) {\n console.error(\"Error formatting time:\", error);\n return \"\";\n }\n}\n","import { FC } from \"react\";\nimport { useTranslation } from \"@orderly.network/i18n\";\nimport { cn, Box, Text, Flex, Button, Select } from \"@orderly.network/ui\";\nimport { CampaignsScriptReturn, CurrentCampaigns } from \"./campaigns.script\";\n\nexport type CampaignsProps = {\n className?: string;\n style?: React.CSSProperties;\n} & CampaignsScriptReturn;\n\nexport const Campaigns: FC<CampaignsProps> = (props) => {\n if (props.currentCampaigns.length === 0) {\n return null;\n }\n\n return (\n <Box\n width=\"100%\"\n intensity={900}\n p={5}\n pr={2}\n height={288}\n className={cn(\n \"oui-trading-leaderboard-campaigns oui-rounded-[20px]\",\n props.className,\n )}\n style={props.style}\n >\n <Header {...props} />\n <Box\n mt={5}\n r=\"xl\"\n className={cn(\"oui-overflow-y-auto\", \"oui-custom-scrollbar\")}\n >\n <Flex\n gapY={5}\n height={200}\n direction=\"column\"\n r=\"xl\"\n className=\"oui-pr-1.5\"\n >\n {props.currentCampaigns.map((campaign) => {\n return (\n <CampaignItem\n key={campaign.title}\n campaign={campaign}\n onLearnMore={props.onLearnMore}\n onTradeNow={props.onTradeNow}\n />\n );\n })}\n </Flex>\n </Box>\n </Box>\n );\n};\n\nconst Header: FC<CampaignsScriptReturn> = (props) => {\n const { t } = useTranslation();\n return (\n <Flex justify=\"between\" itemAlign=\"center\" pr={3}>\n <Text size=\"xl\">{t(\"tradingLeaderboard.campaigns\")}</Text>\n <Select.options\n size={\"xs\"}\n value={props.category}\n onValueChange={props.onCategoryChange}\n options={props.options}\n classNames={{\n // set the width of the trigger to the width of the content\n trigger: \"oui-w-[--radix-select-content-available-width]\",\n }}\n />\n </Flex>\n );\n};\n\ntype CampaignItemProps = {\n campaign: CurrentCampaigns;\n onLearnMore: (campaign: CurrentCampaigns) => void;\n onTradeNow: (campaign: CurrentCampaigns) => void;\n};\n\nconst CampaignItem: FC<CampaignItemProps> = ({\n campaign,\n onLearnMore,\n onTradeNow,\n}) => {\n const { title, description, image, displayTime } = campaign;\n const { t } = useTranslation();\n\n return (\n <Flex intensity={800} r=\"xl\" width=\"100%\">\n <img\n className=\"oui-h-[200px] oui-w-[400px] oui-rounded-l-xl oui-object-fill\"\n src={image}\n alt={title}\n />\n\n <Flex\n itemAlign=\"start\"\n justify=\"between\"\n direction=\"column\"\n height=\"100%\"\n p={5}\n className=\"oui-flex-1 oui-font-semibold\"\n >\n <Flex gap={1} direction=\"column\" itemAlign=\"start\">\n <Text size=\"xl\">{title}</Text>\n <Text size=\"sm\" intensity={36}>\n {description}\n </Text>\n </Flex>\n <Flex justify=\"between\" width=\"100%\">\n <Text size=\"xs\" intensity={54}>\n {displayTime}\n </Text>\n <Flex gap={3}>\n <Button\n variant=\"outlined\"\n color=\"secondary\"\n size=\"md\"\n onClick={() => {\n onLearnMore(campaign);\n }}\n >\n {t(\"tradingLeaderboard.learnMore\")}\n </Button>\n <Button\n size=\"md\"\n onClick={() => {\n onTradeNow(campaign);\n }}\n >\n {t(\"tradingLeaderboard.tradeNow\")}\n </Button>\n </Flex>\n </Flex>\n </Flex>\n </Flex>\n );\n};\n","import { FC, SVGProps } from \"react\";\nimport { cn, DataFilter, DataTable, Flex, Spinner } from \"@orderly.network/ui\";\nimport { useTradingListColumns } from \"./column\";\nimport {\n getRowKey,\n TradingData,\n TradingListScriptReturn,\n} from \"./tradingList.script\";\n\nexport type TradingListProps = {\n style?: React.CSSProperties;\n className?: string;\n} & TradingListScriptReturn;\n\nexport const MobileTradingList: FC<TradingListProps> = (props) => {\n const column = useTradingListColumns(props.address);\n\n return (\n <Flex\n direction=\"column\"\n width=\"100%\"\n itemAlign=\"start\"\n intensity={900}\n r=\"2xl\"\n px={4}\n style={props.style}\n className={cn(\n \"oui-mobile-trading-leaderboard-trading-list\",\n props.className,\n )}\n >\n <Flex\n width=\"100%\"\n justify=\"between\"\n itemAlign=\"center\"\n className={cn(\"oui-mobile-trading-leaderboard-trading-filter\")}\n >\n {props.filterItems.length > 0 && (\n <DataFilter\n items={props.filterItems}\n onFilter={(value: any) => {\n props.onFilter(value);\n }}\n className=\"oui-h-[40px] oui-border-none\"\n />\n )}\n </Flex>\n\n <DataTable\n classNames={{\n root: \"oui-pb-4\",\n body: \"oui-text-2xs\",\n scroll: \"oui-overflow-y-hidden oui-h-full\",\n }}\n loading={props.isLoading}\n id=\"oui-trading-leaderboard-trading-table\"\n columns={column}\n initialSort={props.initialSort}\n onSort={props.onSort}\n dataSource={props.dataList}\n generatedRowKey={(record: TradingData) => record.key || record.address}\n manualPagination\n manualSorting\n onRow={(record, index) => {\n return {\n className: cn(\"oui-h-[30px]\"),\n };\n }}\n onCell={(column, record, index) => {\n if (record.key === getRowKey(props.address!)) {\n const isFirst = column.getIsFirstColumn();\n const isLast = column.getIsLastColumn();\n\n return {\n className: cn(\n \"after:oui-absolute after:oui-h-[30px] after:oui-w-full\",\n \"after:oui-border-[rgb(var(--oui-gradient-brand-start))]\",\n \" after:oui-left-0 after:oui-top-0 after:oui-z-[-1]\",\n \"after:oui-border-y\",\n isFirst && \"after:oui-rounded-l-lg after:oui-border-l\",\n isLast && \"after:oui-rounded-r-lg after:oui-border-r\",\n ),\n };\n }\n return {};\n }}\n />\n <div\n ref={props.sentinelRef}\n className=\"oui-invisible oui-relative oui-top-[-300px] oui-h-px\"\n />\n {props.isLoading && props.dataList.length > 0 && (\n <Flex itemAlign=\"center\" justify=\"center\" width=\"100%\" height={40}>\n <Spinner size=\"sm\" />\n </Flex>\n )}\n </Flex>\n );\n};\n\nexport const SearchIcon: FC<SVGProps<SVGSVGElement>> = (props) => (\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 14 14\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path d=\"M5.841 1.14a4.667 4.667 0 0 0 0 9.333 4.74 4.74 0 0 0 2.875-.975l2.54 2.56a.6.6 0 0 0 .838 0 .6.6 0 0 0 0-.838L9.537 8.677a4.72 4.72 0 0 0 .971-2.871 4.667 4.667 0 0 0-4.667-4.667m0 1.166a3.5 3.5 0 1 1 0 7 3.5 3.5 0 0 1 0-7\" />\n </svg>\n);\n","import { useMemo } from \"react\";\nimport { useTranslation } from \"@orderly.network/i18n\";\nimport { Text, Column, Box, useScreen } from \"@orderly.network/ui\";\nimport { getRowKey } from \"./tradingList.script\";\n\nexport const useTradingListColumns = (address?: string) => {\n const { t } = useTranslation();\n const { isMobile } = useScreen();\n\n return useMemo(() => {\n return [\n {\n title: t(\"tradingLeaderboard.rank\"),\n dataIndex: \"rank\",\n width: 40,\n render: (value: number) => {\n return (\n <Box width={20} className=\"oui-text-center\">\n {value}\n </Box>\n );\n },\n },\n {\n title: t(\"common.address\"),\n dataIndex: \"address\",\n render: (value: string, record: any) => {\n const isYou = record.key === getRowKey(address!);\n if (isMobile && isYou) {\n return <Text>You</Text>;\n }\n\n return (\n <>\n <Text.formatted rule=\"address\">{value}</Text.formatted>\n {isYou && <Text> (You)</Text>}\n </>\n );\n },\n width: 90,\n },\n {\n title: t(\"tradingLeaderboard.tradingVolume\"),\n dataIndex: \"perp_volume\",\n onSort: true,\n render: (value: string) => {\n if (!value) {\n return \"-\";\n }\n return (\n <Text.numeral prefix=\"$\" rule=\"price\" dp={2}>\n {value}\n </Text.numeral>\n );\n },\n width: 105,\n },\n {\n title: t(\"common.realizedPnl\"),\n dataIndex: \"realized_pnl\",\n onSort: true,\n align: isMobile ? \"right\" : \"left\",\n render: (value: string) => {\n if (!value) {\n return \"-\";\n }\n return (\n <Text.numeral prefix=\"$\" rule=\"price\" dp={2} coloring>\n {value}\n </Text.numeral>\n );\n },\n width: 90,\n },\n ] as Column[];\n }, [t, isMobile, address]);\n};\n","import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { differenceInDays } from \"date-fns\";\nimport {\n useAccount,\n useConfig,\n useInfiniteQuery,\n useQuery,\n usePrivateQuery,\n} from \"@orderly.network/hooks\";\nimport { API } from \"@orderly.network/types\";\nimport { TableSort, usePagination, useScreen } from \"@orderly.network/ui\";\nimport { useEndReached } from \"../../../hooks/useEndReached\";\nimport { getDateRange, formatDateRange } from \"../../../utils\";\n\nexport type TradingListScriptOptions = {};\n\nexport type TradingData = {\n account_id: string;\n address: string;\n broker_fee: number;\n date: string;\n perp_maker_volume: number;\n perp_taker_volume: number;\n perp_volume: number;\n total_fee: number;\n // custom field\n key?: string;\n};\n\nexport type TradingResponse = {\n meta: API.RecordsMeta;\n rows: TradingData[];\n};\nexport type TradingListScriptReturn = ReturnType<typeof useTradingListScript>;\n\nexport const FilterDays = [7, 14, 30, 90] as const;\nexport type TFilterDays = (typeof FilterDays)[number];\nexport type DateRange = {\n from?: Date;\n to?: Date;\n};\n\nexport function useTradingListScript() {\n const [searchValue, setSearchValue] = useState(\"\");\n const [initialSort] = useState<TableSort>({\n sortKey: \"perp_volume\",\n sort: \"desc\",\n });\n const [sort, setSort] = useState<TableSort | undefined>(initialSort);\n\n const { state } = useAccount();\n const brokerId = useConfig(\"brokerId\");\n\n const { isMobile } = useScreen();\n\n const { dateRange, filterDay, updateFilterDay, filterItems, onFilter } =\n useFilter();\n\n const { page, pageSize, setPage, parsePagination } = usePagination({\n pageSize: 100,\n });\n\n const getUrl = (args: {\n page: number;\n pageSize: number;\n address?: string;\n sort?: string | null;\n }) => {\n const searchParams = new URLSearchParams();\n\n searchParams.set(\"page\", args.page.toString());\n searchParams.set(\"size\", args.pageSize.toString());\n\n searchParams.set(\"aggregateBy\", \"address_per_builder\");\n\n if (brokerId) {\n searchParams.set(\"broker_id\", brokerId);\n }\n\n if (args.sort) {\n searchParams.set(\"sort\", args.sort);\n } else if (args.sort !== null && sort) {\n const prefix = sort.sort === \"asc\" ? \"ascending\" : \"descending\";\n searchParams.set(\"sort\", `${prefix}_${sort.sortKey}`);\n }\n\n if (dateRange.from) {\n searchParams.set(\"start_date\", formatDateRange(dateRange.from!));\n }\n\n if (dateRange.to) {\n searchParams.set(\"end_date\", formatDateRange(dateRange.to!));\n }\n\n if (args.address) {\n searchParams.set(\"address\", args.address);\n }\n\n return `/v1/broker/leaderboard/daily?${searchParams.toString()}`;\n };\n\n const { data, isLoading } = useQuery<TradingResponse>(\n getUrl({ page, pageSize, address: searchValue }),\n {\n formatter: (res) => res,\n revalidateOnFocus: false,\n },\n );\n\n const {\n data: infiniteData,\n size,\n setSize,\n isValidating,\n } = useInfiniteQuery<TradingResponse>(\n (pageIndex: number, previousPageData: any): string | null => {\n // reached the end\n if (previousPageData && !previousPageData.rows?.length) return null;\n\n if (!isMobile) {\n return null;\n }\n\n return getUrl({\n page: pageIndex + 1,\n pageSize,\n address: searchValue,\n });\n },\n {\n initialSize: 1,\n formatter: (res) => res,\n revalidateOnFocus: false,\n },\n );\n\n // it will use first page data cache\n const { data: top100Data } = useQuery<TradingResponse>(\n state.address\n ? getUrl({\n page: 1,\n pageSize: 100,\n sort: `descending_${sort?.sortKey || \"perp_volume\"}`,\n })\n : null,\n {\n formatter: (res) => res,\n revalidateOnFocus: false,\n },\n );\n\n const { data: userDataRes = [] } = usePrivateQuery<TradingData[]>(\n state.address\n ? getUrl({ page: 1, pageSize: 1, address: state.address, sort: null })\n : null,\n {\n revalidateOnFocus: false,\n },\n );\n\n const getAddressRank = useCallback(\n (address: string) => {\n const index = top100Data?.rows.findIndex((item) =>\n isSameAddress(item.address, address!),\n );\n return index !== -1 ? index! + 1 : \"100+\";\n },\n [top100Data],\n );\n\n const userDataList = useMemo(() => {\n if (!state.address || isLoading) {\n return [];\n }\n\n if (!userDataRes.length) {\n return [\n {\n key: getRowKey(state.address!),\n address: state.address,\n rank: \"-\",\n } as unknown as TradingData,\n ];\n }\n\n return userDataRes?.map((item) => ({\n ...item,\n rank: getAddressRank(item.address!),\n key: getRowKey(item.address!),\n }));\n }, [state.address, userDataRes, isLoading, getAddressRank]);\n\n const addRankForList = useCallback(\n (list: TradingData[], total: number) => {\n return list?.map((item, index) => {\n let rank: string | number = index + 1;\n\n if (searchValue) {\n rank = getAddressRank(item.address);\n } else {\n if (sort?.sort === \"asc\") {\n rank = total - (page - 1) * pageSize - index;\n } else if (sort?.sort === \"desc\") {\n rank = (page - 1) * pageSize + index + 1;\n }\n }\n\n return {\n ...item,\n rank,\n };\n });\n },\n [page, pageSize, sort, searchValue, getAddressRank],\n );\n\n const dataSource = useMemo(() => {\n const list = data?.rows || [];\n const total = data?.meta.total || 0;\n const rankList = addRankForList(list, total);\n if (page === 1 && !searchValue) {\n return [...userDataList, ...rankList];\n }\n return rankList;\n }, [data, page, userDataList, searchValue, addRankForList]);\n\n const dataList = useMemo(() => {\n if (!infiniteData?.length) {\n return [];\n }\n\n const total = infiniteData[0]?.meta.total || 0;\n const flatList = infiniteData?.map((item) => item.rows)?.flat();\n const rankList = addRankForList(flatList, total);\n\n if (!searchValue) {\n return [...userDataList, ...rankList];\n }\n\n return rankList;\n }, [infiniteData, userDataList, searchValue, addRankForList]);\n\n const sentinelRef = useRef<HTMLDivElement | null>(null);\n\n const pagination = useMemo(\n () => parsePagination(data?.meta),\n [parsePagination, data],\n );\n\n useEndReached(sentinelRef, () => {\n if (!isValidating && isMobile) {\n setSize(size + 1);\n }\n });\n\n const onSearchValueChange = (value: string) => {\n setSearchValue(value);\n };\n\n const clearSearchValue = useCallback(() => {\n setSearchValue(\"\");\n }, []);\n\n const onSort = useCallback(\n (sort?: TableSort) => {\n setSort(sort || initialSort);\n },\n [initialSort],\n );\n\n useEffect(() => {\n if (searchValue) {\n setPage(1);\n }\n }, [searchValue]);\n\n useEffect(() => {\n setPage(1);\n }, [state.address]);\n\n useEffect(() => {\n if (dateRange.to && dateRange.from) {\n setPage(1);\n }\n }, [dateRange]);\n\n return {\n pagination,\n dateRange,\n filterDay,\n updateFilterDay,\n filterItems,\n onFilter,\n initialSort,\n onSort,\n dataSource,\n isLoading: isLoading || isValidating,\n searchValue,\n onSearchValueChange,\n clearSearchValue,\n isMobile,\n sentinelRef,\n dataList,\n address: state.address,\n };\n}\n\nconst useFilter = () => {\n // default is 90d\n const [filterDay, setFilterDay] = useState<TFilterDays | null>(90);\n\n const [dateRange, setDateRange] = useState<DateRange>(getDateRange(90));\n\n const updateFilterDay = (day: TFilterDays) => {\n setFilterDay(day);\n setDateRange(getDateRange(day));\n };\n\n const onFilter = (filter: { name: string; value: any }) => {\n if (filter.name === \"dateRange\") {\n const newDateRange = filter.value;\n setDateRange(newDateRange);\n\n if (newDateRange.from && newDateRange.to) {\n const offsetDay =\n Math.abs(differenceInDays(newDateRange.from, newDateRange.to)) + 1;\n\n const dateRange = getDateRange(offsetDay);\n if (\n formatDateRange(dateRange.from) ===\n formatDateRange(newDateRange.from) &&\n formatDateRange(dateRange.to) === formatDateRange(newDateRange.to)\n ) {\n setFilterDay(offsetDay as any);\n } else {\n setFilterDay(null);\n }\n }\n }\n };\n\n const filterItems = useMemo(() => {\n const dateRangeFilter = {\n type: \"range\",\n name: \"dateRange\",\n value: dateRange,\n max: 90,\n };\n\n return [dateRangeFilter] as any;\n }, [dateRange]);\n\n return {\n filterItems,\n onFilter,\n dateRange,\n filterDay,\n updateFilterDay,\n };\n};\n\nexport function isSameAddress(address1: string, address2: string) {\n return address1.toLowerCase() === address2.toLowerCase();\n}\n\nexport function getRowKey(address: string) {\n return `current-address-${address?.toLowerCase()}`;\n}\n","import { useEffect, useRef, MutableRefObject } from \"react\";\n\n/**\n * Listen for the specified element to scroll to the bottom\n */\nexport function useEndReached(\n sentinelRef: MutableRefObject<HTMLDivElement | null>,\n onEndReached?: () => void\n) {\n const observer = useRef<IntersectionObserver>();\n const cb = useRef(onEndReached);\n\n cb.current = onEndReached;\n\n useEffect(() => {\n const options: IntersectionObserverInit = {\n root: null,\n rootMargin: \"0px\",\n threshold: 0,\n };\n\n const handleObserver = (entries: IntersectionObserverEntry[]) => {\n entries.forEach((entry) => {\n if (entry.isIntersecting) {\n cb.current?.();\n }\n });\n };\n\n observer.current = new IntersectionObserver(handleObserver, options);\n\n return () => {\n observer.current?.disconnect();\n };\n }, []);\n\n useEffect(() => {\n if (sentinelRef.current) {\n observer.current?.observe(sentinelRef.current);\n }\n }, [sentinelRef.current]);\n}\n","import { FC, SVGProps } from \"react\";\nimport { useTranslation } from \"@orderly.network/i18n\";\nimport {\n Box,\n CloseCircleFillIcon,\n cn,\n DataFilter,\n DataTable,\n Flex,\n Input,\n Text,\n} from \"@orderly.network/ui\";\nimport { useTradingListColumns } from \"./column\";\nimport {\n FilterDays,\n getRowKey,\n TradingData,\n TradingListScriptReturn,\n} from \"./tradingList.script\";\n\nexport type TradingListProps = {\n style?: React.CSSProperties;\n className?: string;\n} & TradingListScriptReturn;\n\nexport const TradingList: FC<TradingListProps> = (props) => {\n const column = useTradingListColumns(props.address);\n const { t } = useTranslation();\n\n return (\n <Flex\n direction=\"column\"\n width=\"100%\"\n itemAlign=\"start\"\n intensity={900}\n r=\"2xl\"\n px={4}\n style={props.style}\n className={cn(\"oui-trading-leaderboard-trading-list\", props.className)}\n >\n <Flex\n width=\"100%\"\n justify=\"between\"\n itemAlign=\"center\"\n mt={2}\n className={cn(\n \"oui-trading-leaderboard-trading-filter\",\n \"oui-border-b oui-border-line\",\n )}\n >\n <Flex gap={3}>\n {props.filterItems.length > 0 && (\n <DataFilter\n items={props.filterItems}\n onFilter={(value: any) => {\n props.onFilter(value);\n }}\n className=\"oui-h-[53px] oui-border-none\"\n />\n )}\n {FilterDays.map((value) => {\n return (\n <button\n className=\"oui-relative oui-px-2 oui-py-[2px] oui-text-sm\"\n key={value}\n >\n <div className=\"oui-z-10\">\n <Text.gradient\n color={props.filterDay === value ? \"brand\" : undefined}\n className={\n props.filterDay !== value\n ? \"oui-text-base-contrast-54\"\n : \"\"\n }\n >\n {`${value}D`}\n </Text.gradient>\n </div>\n <div\n className=\"oui-absolute oui-inset-0 oui-rounded oui-opacity-[.12] oui-gradient-primary\"\n onClick={() => {\n props.updateFilterDay(value as any);\n }}\n ></div>\n </button>\n );\n })}\n </Flex>\n <Input\n value={props.searchValue}\n onValueChange={props.onSearchValueChange}\n placeholder={t(\"common.address.search.placeholder\")}\n className={cn(\n \"oui-trading-leaderboard-trading-search-input\",\n \"oui-w-[240px]\",\n )}\n size=\"sm\"\n prefix={\n <Box pl={3} pr={1}>\n <SearchIcon className=\"oui-text-base-contrast-36\" />\n </Box>\n }\n suffix={\n props.searchValue && (\n <Box mr={2}>\n <CloseCircleFillIcon\n size={14}\n className=\"oui-cursor-pointer oui-text-base-contrast-36\"\n onClick={props.clearSearchValue}\n />\n </Box>\n )\n }\n autoComplete=\"off\"\n />\n </Flex>\n\n <DataTable\n loading={props.isLoading}\n id=\"oui-trading-leaderboard-trading-table\"\n columns={column}\n initialSort={props.initialSort}\n onSort={props.onSort}\n bordered\n dataSource={props.dataSource}\n generatedRowKey={(record: TradingData) => record.key || record.address}\n manualPagination\n manualSorting\n pagination={props.pagination}\n classNames={{\n root: \"!oui-h-[calc(100%_-_53px_-_8px)]\",\n }}\n onRow={(record, index) => {\n return {\n className: cn(\"oui-h-[48px]\"),\n };\n }}\n onCell={(column, record, index) => {\n if (record.key === getRowKey(props.address!)) {\n const isFirst = column.getIsFirstColumn();\n const isLast = column.getIsLastColumn();\n\n return {\n className: cn(\n \"after:oui-absolute after:oui-h-[48px] after:oui-w-full\",\n \"after:oui-border-[rgb(var(--oui-gradient-brand-start))]\",\n \"after:oui-left-0 after:oui-top-0 after:oui-z-[-1]\",\n \"after:oui-border-y\",\n isFirst && \"after:oui-rounded-l-lg after:oui-border-l\",\n isLast && \"after:oui-rounded-r-lg after:oui-border-r\",\n ),\n };\n }\n return {};\n }}\n />\n </Flex>\n );\n};\n\nexport const SearchIcon: FC<SVGProps<SVGSVGElement>> = (props) => (\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 14 14\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path d=\"M5.841 1.14a4.667 4.667 0 0 0 0 9.333 4.74 4.74 0 0 0 2.875-.975l2.54 2.56a.6.6 0 0 0 .838 0 .6.6 0 0 0 0-.838L9.537 8.677a4.72 4.72 0 0 0 .971-2.871 4.667 4.667 0 0 0-4.667-4.667m0 1.166a3.5 3.5 0 1 1 0 7 3.5 3.5 0 0 1 0-7\" />\n </svg>\n);\n","import { FC } from \"react\";\nimport { MobileTradingList } from \"./tradingList.mobile.ui\";\nimport { useTradingListScript } from \"./tradingList.script\";\nimport { TradingList, TradingListProps } from \"./tradingList.ui\";\n\nexport type TradingListWidgetProps = Pick<\n TradingListProps,\n \"style\" | \"className\"\n>;\n\n/**\n * @deprecated use TradingListPage instead\n * it will be removed in next version\n */\nexport const TradingListWidget: FC<TradingListWidgetProps> = (props) => {\n const state = useTradingListScript();\n if (state.isMobile) {\n return <MobileTradingList {...state} {...props} />;\n }\n return <TradingList {...state} {...props} />;\n};\n","import { useMemo } from \"react\";\nimport { useScreen } from \"@orderly.network/ui\";\nimport { Campaign } from \"../../components/provider\";\n\nexport type LeaderboardScriptReturn = ReturnType<typeof useLeaderboardScript>;\n\nexport type LeaderboardScriptOptions = {\n backgroundSrc?: string;\n campaigns?: Campaign[];\n};\n\nfunction isVideoSrc(src?: string) {\n const extension = src?.split(\".\").pop();\n return [\"mp4\", \"webm\", \"avi\", \"ogg\"].includes(extension ?? \"\");\n}\n\nexport function useLeaderboardScript(options: LeaderboardScriptOptions) {\n const { backgroundSrc, campaigns = [] } = options;\n const { isMobile } = useScreen();\n\n const showCampaigns = useMemo(() => campaigns?.length > 0, [campaigns]);\n\n const isVideo = useMemo(() => {\n return isVideoSrc(backgroundSrc);\n }, [backgroundSrc]);\n\n return {\n backgroundSrc,\n isVideo,\n showCampaigns,\n isMobile,\n };\n}\n","import { FC } from \"react\";\nimport { cn, Flex } from \"@orderly.network/ui\";\nimport { CampaignsWidget } from \"../../components/campaigns\";\nimport { TradingListWidget } from \"../../components/tradingList\";\nimport { LeaderboardScriptReturn } from \"./leaderboard.script\";\n\nexport type LeaderboardProps = {\n style?: React.CSSProperties;\n className?: string;\n} & LeaderboardScriptReturn;\n\nexport const Leaderboard: FC<LeaderboardProps> = (props) => {\n const renderBackground = () => {\n const linearGradient =\n \"linear-gradient(180deg, rgba(var(--oui-color-base-10) / 0.3) 0%, rgba(var(--oui-color-base-10) / 0) 70%, rgba(var(--oui-color-base-10) / 1) 100%)\";\n\n if (props.isVideo) {\n return (\n <div\n className={cn(\n \"oui-absolute oui-top-0 oui-left-0\",\n \"oui-w-full oui-h-full\",\n )}\n >\n <div\n style={{\n backgroundImage: linearGradient,\n backgroundSize: \"cover\",\n backgroundRepeat: \"no-repeat\",\n }}\n className={cn(\n \"oui-absolute oui-top-0 oui-left-0\",\n \"oui-w-full oui-h-full\",\n )}\n />\n <video\n autoPlay\n loop\n muted\n className={cn(\n // rest style\n \"oui-border-none oui-outline-none oui-bg-transparent\",\n \"oui-w-full oui-h-full\",\n // \"oui-absolute oui-top-0 oui-left-0\",\n \"oui-object-cover\",\n \"oui-opacity-50\",\n )}\n >\n <source src={props.backgroundSrc} type=\"video/mp4\" />\n <source src={props.backgroundSrc} type=\"video/webm\" />\n <source src={props.backgroundSrc} type=\"video/ogg\" />\n <source src={props.backgroundSrc} type=\"video/avi\" />\n Your browser does not support the video tag.\n </video>\n </div>\n );\n }\n\n if (props.backgroundSrc) {\n return (\n <div\n style={{\n backgroundImage: `${linearGradient}, url(${props.backgroundSrc}) `,\n backgroundSize: \"cover\",\n backgroundRepeat: \"no-repeat\",\n }}\n className={cn(\n \"oui-absolute oui-top-0 oui-left-0\",\n \"oui-w-full oui-h-full\",\n \"oui-opacity-50\",\n )}\n />\n );\n }\n };\n\n return (\n <div\n style={props.style}\n className={cn(\"oui-h-full oui-mix-blend-screen\", props.className)}\n >\n {renderBackground()}\n <Flex\n direction=\"column\"\n gapY={5}\n height=\"100%\"\n className={cn(\n \"oui-trading-leaderboard oui-relative\",\n \"oui-max-w-[1040px] oui-px-3 oui-mx-auto \",\n )}\n >\n {props.showCampaigns && <CampaignsWidget />}\n <TradingListWidget\n className={cn(\n props.showCampaigns\n ? \"oui-h-[calc(100%_-_288px_-_20px)]\"\n : \"oui-h-full\",\n )}\n />\n </Flex>\n </div>\n );\n};\n","import { FC } from \"react\";\nimport {\n TradingLeaderboardProvider,\n TradingLeaderboardProviderProps,\n} from \"../../components/provider\";\nimport { MobileLeaderboardWidget } from \"./leaderboard.mobile.ui\";\nimport { useLeaderboardScript } from \"./leaderboard.script\";\nimport { Leaderboard, LeaderboardProps } from \"./leaderboard.ui\";\n\nexport type LeaderboardWidgetProps = TradingLeaderboardProviderProps &\n Pick<LeaderboardProps, \"style\" | \"className\">;\n\n/**\n * @deprecated use LeaderboardPage instead\n * it will be removed in next version\n */\nexport const LeaderboardWidget: FC<LeaderboardWidgetProps> = (props) => {\n const state = useLeaderboardScript({\n backgroundSrc: props.backgroundSrc,\n campaigns: props.campaigns,\n });\n\n return (\n <TradingLeaderboardProvider campaigns={props.campaigns} href={props.href}>\n {state.isMobile ? (\n <MobileLeaderboardWidget {...state} />\n ) : (\n <Leaderboard\n {...state}\n className={props.className}\n style={props.style}\n />\n )}\n </TradingLeaderboardProvider>\n );\n};\n","import React, {\n createContext,\n useContext,\n useMemo,\n useState,\n useEffect,\n} from \"react\";\nimport { parseISO } from \"date-fns\";\nimport { sortWith, descend } from \"ramda\";\nimport {\n usePrivateQuery,\n RefferalAPI as API,\n useMemoizedFn,\n} from \"@orderly.network/hooks\";\nimport { CampaignConfig, UserData } from \"../campaigns/type\";\n\n/**\n * Trading leaderboard provider state\n */\nexport type TradingLeaderboardState = {\n /** campaigns config, if not provided, will not show campaigns section */\n campaigns?: CampaignConfig[];\n /** background src, it can be a image resource or video resource */\n backgroundSrc?: string;\n href?: {\n /** default trading now button url */\n trading: string;\n };\n currentCampaignId: string | number;\n currentCampaign?: CampaignConfig;\n onCampaignChange: (campaignId: string | number) => void;\n /** leaderboard user data, it will be used to calculate the rewards */\n userData?: UserData;\n /** set leaderboard user data */\n setUserData?: (userdata: UserData) => void;\n /** campaign ranking list updated time */\n updatedTime?: number;\n /** set snapshot time */\n setUpdatedTime?: (updatedTime?: number) => void;\n /** custom data, if use this, you can full control the data */\n dataAdapter?: (info: { page: number; pageSize: number }) => {\n loading: boolean;\n dataSource?: any[];\n dataList?: any[];\n userData?: any;\n updatedTime?: number;\n meta?: {\n total: number;\n current_page: number;\n records_per_page: number;\n };\n };\n};\n\n/**\n * Trading leaderboard context\n */\nexport const TradingLeaderboardContext = createContext<TradingLeaderboardState>(\n {} as TradingLeaderboardState,\n);\n\nexport type TradingLeaderboardProviderProps = Pick<\n TradingLeaderboardState,\n \"campaigns\" | \"href\" | \"backgroundSrc\" | \"dataAdapter\"\n> & {\n campaignId?: string | number;\n onCampaignChange?: (campaignId: string | number) => void;\n};\n\nexport const TradingLeaderboardProvider: React.FC<\n React.PropsWithChildren<TradingLeaderboardProviderProps>\n> = (props) => {\n const {\n campaignId,\n campaigns,\n backgroundSrc,\n href,\n children,\n dataAdapter,\n onCampaignChange,\n } = props;\n\n const [userData, setUserData] = useState<UserData>();\n const [updatedTime, setUpdatedTime] = useState<number>();\n\n const { data: generateCode, mutate: generateCodeMutate } = usePrivateQuery(\n \"/v1/referral/info\",\n {\n revalidateOnFocus: false,\n errorRetryCount: 2,\n formatter: (data) => {\n return {\n code: data?.referee_info?.referer_code || \"\",\n };\n },\n },\n );\n\n useEffect(() => {\n if (generateCode?.code && userData?.referral_code != generateCode.code) {\n setUserData({ ...userData!, referral_code: generateCode.code });\n generateCodeMutate();\n }\n }, [userData, generateCode, generateCodeMutate]);\n\n const currentCampaign = useMemo(() => {\n return campaigns?.find((campaign) => campaign.campaign_id == campaignId);\n }, [campaigns, campaignId]);\n\n const filteredCampaigns = useMemo(() => {\n // const filtered = campaigns?.filter((campaign) => {\n // // return true;\n // // Campaign without referral_codes is visible to all users\n // if (!campaign.referral_codes) {\n // return true;\n // }\n // return campaign.referral_codes?.includes(userData?.referral_code || \"\");\n // });\n\n // Using date-fns to parse date strings and sort by end_time in descending order\n return campaigns\n ? sortWith(\n [descend((campaign: CampaignConfig) => parseISO(campaign.end_time))],\n campaigns,\n )\n : campaigns;\n }, [campaigns]);\n\n const memoCampaignChange = useMemoizedFn((id: string | number) => {\n onCampaignChange?.(id);\n });\n\n const memoizedValue = useMemo<TradingLeaderboardState>(() => {\n return {\n campaigns: filteredCampaigns,\n href: href,\n backgroundSrc: backgroundSrc,\n currentCampaignId: campaignId || \"general\",\n currentCampaign,\n updatedTime,\n userData,\n setUserData,\n onCampaignChange: memoCampaignChange,\n setUpdatedTime: setUpdatedTime,\n dataAdapter: dataAdapter,\n };\n }, [\n backgroundSrc,\n currentCampaign,\n campaignId,\n filteredCampaigns,\n href,\n updatedTime,\n userData,\n dataAdapter,\n memoCampaignChange,\n ]);\n\n return (\n <TradingLeaderboardContext.Provider value={memoizedValue}>\n {children}\n </TradingLeaderboardContext.Provider>\n );\n};\n\nexport const useTradingLeaderboardContext = () => {\n const ctx = useContext<TradingLeaderboardState>(TradingLeaderboardContext);\n return ctx;\n};\n","import { FC, useCallback } from \"react\";\nimport {\n cn,\n DataTable,\n Flex,\n Spinner,\n TanstackColumn,\n useScreen,\n} from \"@orderly.network/ui\";\nimport { type CampaignRankingData } from \"../campaignRanking/campaignRanking.script\";\nimport {\n type GeneralRankingData,\n GeneralRankingScriptReturn,\n} from \"../generalRanking/generalRanking.script\";\nimport { type RankingColumnFields, useRankingColumns } from \"./column\";\nimport { getCurrentAddressRowKey } from \"./util\";\n\ntype RankingData = GeneralRankingData | CampaignRankingData;\n\nexport type RankingProps = {\n style?: React.CSSProperties;\n className?: string;\n fields: RankingColumnFields[];\n} & Omit<GeneralRankingScriptReturn, \"dataList\" | \"dataSource\"> & {\n dataList: RankingData[];\n dataSource: RankingData[];\n };\n\nexport const Ranking: FC<RankingProps> = (props) => {\n const column = useRankingColumns(\n props.fields,\n props.address,\n typeof props.onSort === \"function\",\n );\n const { isMobile } = useScreen();\n\n const onRow = useCallback(\n (record: RankingData, index: number) => {\n const isYou = record.key === getCurrentAddressRowKey(props.address!);\n const isFirst = record.rank === 1;\n const isSecond = record.rank === 2;\n const isThird = record.rank === 3;\n\n const showBg = isFirst || isSecond || isThird;\n\n return {\n className: cn(\n \"oui-h-[40px] md:oui-h-[48px]\",\n // use oui-relative to let the background image position based on row\n \"oui-relative\",\n isYou\n ? // add 4px extra height to make row has 2px space\n \"oui-h-[44px] md:oui-h-[52px]\"\n : cn(\n showBg && \"oui-border-b-2 oui-border-b-transparent\",\n isFirst &&\n \"oui-bg-[linear-gradient(270deg,rgba(241,215,121,0.0225)_-2.05%,rgba(255,203,70,0.45)_100%)]\",\n isSecond &&\n \"oui-bg-[linear-gradient(270deg,rgba(255,255,255,0.0225)_-2.05%,rgba(199,199,199,0.45)_100%)]\",\n isThird &&\n \"oui-bg-[linear-gradient(270deg,rgba(255,233,157,0.0225)_-1.3%,rgba(160,101,46,0.45)_100%)]\",\n ),\n ),\n };\n },\n [props.address],\n );\n\n const onCell = useCallback(\n (\n column: TanstackColumn<RankingData>,\n record: RankingData,\n index: number,\n ) => {\n const isFirstColumn = column.getIsFirstColumn();\n const isLastColumn = column.getIsLastColumn();\n const isRank = [1, 2, 3].includes(record.rank as number);\n if (record.key === getCurrentAddressRowKey(props.address!)) {\n return {\n className: cn(\n \"after:oui-absolute after:oui-h-[40px] after:oui-w-full md:after:oui-h-[48px]\",\n \"after:oui-border-[rgb(var(--oui-gradient-brand-start))]\",\n \"after:oui-left-0 after:oui-top-[2px] after:oui-z-[-1]\",\n \"after:oui-border-y\",\n isFirstColumn && \"after:oui-rounded-l-lg after:oui-border-l\",\n isLastColumn && \"after:oui-rounded-r-lg after:oui-border-r\",\n ),\n };\n }\n return {\n className: cn(\n isFirstColumn &&\n isRank &&\n \"oui-rounded-l-lg oui-mix-blend-luminosity\",\n isLastColumn && isRank && \"oui-rounded-r-lg oui-mix-blend-luminosity\",\n ),\n // style: isRank\n // ? {\n // position: \"unset\",\n // }\n // : undefined,\n };\n },\n [props.address],\n );\n\n if (isMobile) {\n return (\n <>\n <DataTable\n classNames={{\n root: \"oui-trading-leaderboard-ranking-table\",\n body: \"oui-text-2xs\",\n scroll: \"oui-overflow-y-hidden oui-h-full\",\n }}\n loading={props.isLoading}\n columns={column}\n bordered\n initialSort={props.initialSort}\n onSort={props.onSort}\n dataSource={props.dataList}\n generatedRowKey={(record: RankingData) =>\n record.key || record.address\n }\n manualPagination\n manualSorting\n onRow={onRow}\n onCell={onCell}\n />\n <div\n ref={props.sentinelRef}\n className=\"oui-invisible oui-relative oui-top-[-300px] oui-h-px\"\n />\n {props.isLoading && props.dataList.length > 0 && (\n <Flex itemAlign=\"center\" justify=\"center\" width=\"100%\" height={40}>\n <Spinner size=\"sm\" />\n </Flex>\n )}\n </>\n );\n }\n\n return (\n <DataTable\n loading={props.isLoading}\n columns={column}\n initialSort={props.initialSort}\n onSort={props.onSort}\n bordered\n dataSource={props.dataSource}\n generatedRowKey={(record: RankingData) => record.key || record.address}\n manualPagination\n manualSorting\n pagination={props.pagination}\n classNames={{\n root: cn(\n \"oui-trading-leaderboard-ranking-table\",\n \"!oui-h-[calc(100%_-_53px_-_8px)]\",\n ),\n scroll: \"oui-min-h-[600px]\",\n }}\n onRow={onRow}\n onCell={onCell}\n />\n );\n};\n","import { ReactNode, useMemo } from \"react\";\nimport { useTranslation } from \"@orderly.network/i18n\";\nimport { Text, Column, Box, useScreen, cn } from \"@orderly.network/ui\";\nimport firstBadge from \"../../../img/first_badge.png\";\nimport secondBadge from \"../../../img/second_badge.png\";\nimport thirdBadge from \"../../../img/third_badge.png\";\nimport { getCurrentAddressRowKey } from \"./util\";\n\nexport type RankingColumnFields =\n | \"rank\"\n | \"address\"\n | \"volume\"\n | \"pnl\"\n | \"rewards\";\n\nexport const useRankingColumns = (\n fields?: RankingColumnFields[],\n address?: string,\n enableSort?: boolean,\n) => {\n const { t } = useTranslation();\n const { isMobile } = useScreen();\n\n return useMemo(() => {\n const columns = [\n {\n title: t(\"tradingLeaderboard.rank\"),\n dataIndex: \"rank\",\n width: 50,\n render: (value: number, record: any) => {\n const isYou = record.key === getCurrentAddressRowKey(address!);\n\n let rankIcon: ReactNode;\n let badgeImg: ReactNode = null;\n\n if (!isYou) {\n if (value === 1) {\n rankIcon = <FirstRankIcon />;\n badgeImg = firstBadge;\n } else if (value === 2) {\n rankIcon = <SecondRankIcon />;\n badgeImg = secondBadge;\n } else if (value === 3) {\n rankIcon = <ThirdRankIcon />;\n badgeImg = thirdBadge;\n }\n }\n\n return (\n <>\n {badgeImg && (\n <img\n src={badgeImg as string}\n alt={`${value}th badge`}\n className={cn(\n \"oui-z-0 oui-h-[38px] oui-opacity-30 md:oui-h-[46px]\",\n \"oui-absolute oui-left-0 oui-top-0\",\n \"oui-mix-blend-luminosity\",\n // force create a separate layer in order to fix mix-blend-luminosity not working on ios\n \"oui-transform-gpu\",\n )}\n />\n )}\n <div className=\"oui-relative\">\n {rankIcon || (\n <Box width={20} pl={2} className=\"oui-text-center\">\n {value}\n </Box>\n )}\n </div>\n </>\n );\n },\n },\n {\n title: t(\"common.address\"),\n dataIndex: \"address\",\n render: (value: string, record: any) => {\n const isYou = record.key === getCurrentAddressRowKey(address!);\n if (isMobile && isYou) {\n return <Text>You</Text>;\n }\n\n let linearGradientText;\n\n if (!isYou) {\n if (record.rank === 1) {\n linearGradientText =\n \"linear-gradient(169deg, #FBE67B 2.09%, #FCFBE7 15.8%, #F7D14E 40.73%, #D4A041 58.8%)\";\n } else if (record.rank === 2) {\n linearGradientText =\n \"linear-gradient(201.05deg, #D9D9D9 38.79%, #F7F6F4 53.85%, #D9D9D9 71.71%, #7F7F7F 91.87%), rgba(255, 255, 255, 0.8)\";\n } else if (record.rank === 3) {\n linearGradientText =\n \"linear-gradient(149.05deg, #B6947E 15.63%, #F8DAC8 31.37%, #B6947E 44.29%, #F8DCCB 56.6%), rgba(255, 255, 255, 0.8)\";\n }\n }\n\n return (\n <>\n <Text.formatted\n rule=\"address\"\n key={record.rank}\n style={\n linearGradientText\n ? {\n background: linearGradientText,\n WebkitBackgroundClip: \"text\",\n WebkitTextFillColor: \"transparent\",\n backgroundClip: \"text\",\n }\n : {}\n }\n >\n {value}\n </Text.formatted>\n {isYou && <Text> (You)</Text>}\n </>\n );\n },\n width: 90,\n },\n {\n title: t(\"tradingLeaderboard.tradingVolume\"),\n dataIndex: \"volume\",\n onSort: enableSort,\n align: isMobile ? \"right\" : \"left\",\n render: (value: string) => {\n if (!value) {\n return \"-\";\n }\n return (\n <Text.numeral prefix=\"$\" rule=\"price\" dp={2}>\n {value}\n </Text.numeral>\n );\n },\n width: 105,\n },\n {\n title: t(\"common.realizedPnl\"),\n dataIndex: \"pnl\",\n onSort: enableSort,\n align: isMobile ? \"right\" : \"left\",\n render: (value: string) => {\n if (!value) {\n return \"-\";\n }\n return (\n <Text.numeral prefix=\"$\" rule=\"price\" dp={2} coloring>\n {value}\n </Text.numeral>\n );\n },\n width: 90,\n },\n {\n title: t(\"tradingLeaderboard.estimatedRewards\"),\n dataIndex: \"rewards\",\n align: isMobile ? \"right\" : \"left\",\n render: (value: { amount: number; currency: string }) => {\n if (!value) {\n return \"-\";\n }\n return (\n <Text.numeral\n suffix={` ${value?.currency || \"\"}`}\n rule=\"price\"\n dp={0}\n >\n {value?.amount}\n </Text.numeral>\n );\n },\n width: 90,\n },\n ] as Column[];\n\n return columns.filter((column) =>\n fields?.includes(column.dataIndex as RankingColumnFields),\n );\n }, [t, isMobile, address, fields, enableSort]);\n};\n\nconst FirstRankIcon = () => {\n return (\n <svg\n width=\"25\"\n height=\"25\"\n viewBox=\"0 0 25 25\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M3.88281 2.5L7.78711 10.3105C6.38111 11.5855 5.5 13.427 5.5 15.5C5.5 19.4 8.6 22.5 12.5 22.5C16.4 22.5 19.5 19.4 19.5 15.5C19.5 13.427 18.6189 11.5855 17.2129 10.3105L21.1172 2.5H15.5L12.5 8.5L9.5 2.5H3.88281ZM12.5 10.5C15.3 10.5 17.5 12.7 17.5 15.5C17.5 18.3 15.3 20.5 12.5 20.5C9.7 20.5 7.5 18.3 7.5 15.5C7.5 12.7 9.7 10.5 12.5 10.5ZM12.5 12.5C12.4 12.8 11.9 13.6992 11 13.6992V14.6992H12.0996V18.5H13.4004H13.5V12.5H12.5Z\"\n fill=\"url(#paint0_linear_21940_39199)\"\n />\n <defs>\n <linearGradient\n id=\"paint0_linear_21940_39199\"\n x1=\"6.18073\"\n y1=\"6\"\n x2=\"20.1338\"\n y2=\"18.1659\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#8C421D\" />\n <stop offset=\"0.325272\" stopColor=\"#FBE67B\" />\n <stop offset=\"0.535488\" stopColor=\"#FCFBE7\" />\n <stop offset=\"0.769917\" stopColor=\"#F7D14E\" />\n <stop offset=\"1\" stopColor=\"#D4A041\" />\n </linearGradient>\n </defs>\n </svg>\n );\n};\n\nconst SecondRankIcon = () => {\n return (\n <svg\n width=\"25\"\n height=\"25\"\n viewBox=\"0 0 25 25\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M3.88281 2.5L7.78711 10.3105C6.38111 11.5855 5.5 13.427 5.5 15.5C5.5 19.4 8.6 22.5 12.5 22.5C16.4 22.5 19.5 19.4 19.5 15.5C19.5 13.427 18.6189 11.5855 17.2129 10.3105L21.1172 2.5H15.5L12.5 8.5L9.5 2.5H3.88281ZM12.5 10.5C15.3 10.5 17.5 12.7 17.5 15.5C17.5 18.3 15.3 20.5 12.5 20.5C9.7 20.5 7.5 18.3 7.5 15.5C7.5 12.7 9.7 10.5 12.5 10.5ZM12.5469 12.5C10.7729 12.5 10.481 13.901 10.5 14.5H11.6738C11.6738 14.357 11.809 13.5 12.5 13.5C13.163 13.5 13.291 14.0232 13.291 14.2852C13.291 15.0512 12.245 15.7623 10.5 17.6973V18.5L14.4883 18.4766L14.4863 17.5332H12.2285C13.8425 15.8792 14.5 15.1309 14.5 14.1719C14.5 13.4869 14.1149 12.5 12.5469 12.5Z\"\n fill=\"url(#paint0_linear_21940_39214)\"\n />\n <defs>\n <linearGradient\n id=\"paint0_linear_21940_39214\"\n x1=\"6.18073\"\n y1=\"6\"\n x2=\"20.1338\"\n y2=\"18.1659\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#7F7F7F\" />\n <stop offset=\"0.325272\" stopColor=\"#D9D9D9\" />\n <stop offset=\"0.535488\" stopColor=\"#F7F6F4\" />\n <stop offset=\"0.769917\" stopColor=\"#D9D9D9\" />\n <stop offset=\"1\" stopColor=\"#7F7F7F\" />\n </linearGradient>\n </defs>\n </svg>\n );\n};\n\nconst ThirdRankIcon = () => {\n return (\n <svg\n width=\"29\"\n height=\"25\"\n viewBox=\"0 0 29 25\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M5.88281 2.5L9.78711 10.3105C8.38111 11.5855 7.5 13.427 7.5 15.5C7.5 19.4 10.6 22.5 14.5 22.5C18.4 22.5 21.5 19.4 21.5 15.5C21.5 13.427 20.6189 11.5855 19.2129 10.3105L23.1172 2.5H17.5L14.5 8.5L11.5 2.5H5.88281ZM14.5 10.5C17.3 10.5 19.5 12.7 19.5 15.5C19.5 18.3 17.3 20.5 14.5 20.5C11.7 20.5 9.5 18.3 9.5 15.5C9.5 12.7 11.7 10.5 14.5 10.5ZM14.4688 12.5C13.6927 12.5 12.5898 12.9348 12.5898 14.0918H13.7266C13.7266 13.9118 13.8461 13.4336 14.4941 13.4336C14.6251 13.4336 15.2715 13.4767 15.2715 14.1797C15.2715 14.8967 14.7109 14.9844 14.4219 14.9844H13.8145V15.8906H14.4219C14.5659 15.8906 15.3613 15.8537 15.3613 16.7637C15.3613 16.8837 15.3111 17.5625 14.4961 17.5625C13.8081 17.5625 13.6233 17.0284 13.6562 16.8164H12.5195C12.4615 17.4334 12.9757 18.4961 14.4688 18.4961C15.3018 18.4961 16.5 18.0942 16.5 16.7812C16.5 15.8643 15.8621 15.536 15.5391 15.418C15.6781 15.354 16.4082 14.9771 16.4082 14.1641C16.4082 13.7131 16.2127 12.5 14.4688 12.5Z\"\n fill=\"url(#paint0_linear_21940_39224)\"\n />\n <defs>\n <linearGradient\n id=\"paint0_linear_21940_39224\"\n x1=\"8.61159\"\n y1=\"5.33333\"\n x2=\"22.7368\"\n y2=\"20.4383\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#B6947E\" />\n <stop offset=\"0.2\" stopColor=\"#8F6959\" />\n <stop offset=\"0.475\" stopColor=\"#F8DAC8\" />\n <stop offset=\"0.67\" stopColor=\"#AC836E\" />\n <stop offset=\"0.83\" stopColor=\"#B6947E\" />\n <stop offset=\"1\" stopColor=\"#F8DCCB\" />\n </linearGradient>\n </defs>\n </svg>\n );\n};\n","export function isSameAddress(address1: string, address2: string) {\n return address1.toLowerCase() === address2.toLowerCase();\n}\n\nexport function getCurrentAddressRowKey(address: string) {\n return `current-address-${address?.toLowerCase()}`;\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n useAccount,\n useConfig,\n useInfiniteQuery,\n useQuery,\n} from \"@orderly.network/hooks\";\nimport { API } from \"@orderly.network/types\";\nimport { TableSort, usePagination, useScreen } from \"@orderly.network/ui\";\nimport { useEndReached } from \"../../../hooks/useEndReached\";\nimport { DateRange } from \"../../../type\";\nimport { formatDateRange, getDateRange } from \"../../../utils\";\nimport { getCurrentAddressRowKey, isSameAddress } from \"../shared/util\";\n\nexport type GeneralRankingData = {\n account_id: string;\n address: string;\n broker_fee: number;\n date: string;\n perp_maker_volume: number;\n perp_taker_volume: number;\n perp_volume: number;\n realized_pnl: number;\n total_fee: number;\n\n // custom field\n key?: string;\n rank?: number | string;\n volume?: number;\n pnl?: number;\n};\n\nexport type GeneralRankingResponse = {\n meta: API.RecordsMeta;\n rows: GeneralRankingData[];\n};\nexport type GeneralRankingScriptReturn = ReturnType<\n typeof useGeneralRankingScript\n>;\n\nexport type GeneralRankingScriptOptions = {\n dateRange?: DateRange;\n address?: string;\n sortKey?: \"perp_volume\" | \"realized_pnl\";\n};\n\nexport function useGeneralRankingScript(options?: GeneralRankingScriptOptions) {\n const {\n dateRange = getDateRange(90),\n address: searchValue,\n sortKey = \"perp_volume\",\n } = options || {};\n\n const [initialSort] = useState<TableSort>({\n sortKey,\n sort: \"desc\",\n });\n\n const [sort, setSort] = useState<TableSort | undefined>(initialSort);\n\n const { state } = useAccount();\n const brokerId = useConfig(\"brokerId\");\n\n const { isMobile } = useScreen();\n\n const { page, pageSize, setPage, parsePagination } = usePagination({\n pageSize: isMobile ? 100 : 20,\n });\n\n const getUrl = (args: {\n page: number;\n pageSize: number;\n address?: string;\n sort?: string | null;\n }) => {\n const searchParams = new URLSearchParams();\n\n searchParams.set(\"page\", args.page.toString());\n searchParams.set(\n \"size\",\n // if page is 1, we need to set page size to 100 to get the top 100 data to judge user rank\n args.page === 1 ? \"100\" : args.pageSize.toString(),\n );\n searchParams.set(\"aggregateBy\", \"address_per_builder\");\n\n if (brokerId) {\n searchParams.set(\"broker_id\", brokerId);\n }\n\n if (args.sort) {\n searchParams.set(\"sort\", args.sort);\n } else if (args.sort !== null && sort) {\n const prefix = sort.sort === \"asc\" ? \"ascending\" : \"descending\";\n searchParams.set(\"sort\", `${prefix}_${sort.sortKey}`);\n }\n\n if (dateRange?.from) {\n searchParams.set(\"start_date\", formatDateRange(dateRange.from!));\n }\n\n if (dateRange?.to) {\n searchParams.set(\"end_date\", formatDateRange(dateRange.to!));\n }\n\n if (args.address) {\n searchParams.set(\"address\", args.address);\n }\n\n // https://orderly.network/docs/build-on-omnichain/evm-api/restful-api/private/get-builders-leaderboard\n return `/v1/broker/leaderboard/daily?${searchParams.toString()}`;\n };\n\n const { data, isLoading } = useQuery<GeneralRankingResponse>(\n getUrl({ page, pageSize, address: searchValue }),\n {\n formatter: (res) => res,\n revalidateOnFocus: false,\n },\n );\n\n const {\n data: infiniteData,\n size,\n setSize,\n isValidating,\n } = useInfiniteQuery<GeneralRankingResponse>(\n (pageIndex: number, previousPageData: any): string | null => {\n // reached the end\n if (previousPageData && !previousPageData.rows?.length) return null;\n\n if (!isMobile) {\n return null;\n }\n\n return getUrl({\n page: pageIndex + 1,\n pageSize,\n address: searchValue,\n });\n },\n {\n initialSize: 1,\n formatter: (res) => res,\n revalidateOnFocus: false,\n },\n );\n\n // it will use first page data cache\n const { data: top100Data } = useQuery<GeneralRankingResponse>(\n state.address\n ? getUrl({\n page: 1,\n pageSize: 100,\n sort: `descending_${sort?.sortKey || \"perp_volume\"}`,\n })\n : null,\n {\n formatter: (res) => res,\n revalidateOnFocus: false,\n },\n );\n\n const { data: userDataRes = [] } = useQuery<GeneralRankingData[]>(\n state.address\n ? getUrl({ page: 1, pageSize: 1, address: state.address, sort: null })\n : null,\n {\n revalidateOnFocus: false,\n },\n );\n\n const getAddressRank = useCallback(\n (address: string) => {\n const index = top100Data?.rows.findIndex((item) =>\n isSameAddress(item.address, address!),\n );\n return index !== -1 ? index! + 1 : \"100+\";\n },\n [top100Data],\n );\n\n const userDataList = useMemo(() => {\n if (!state.address || isLoading) {\n return [];\n }\n\n if (!userDataRes.length) {\n return [\n {\n key: getCurrentAddressRowKey(state.address!),\n address: state.address,\n rank: \"-\",\n } as unknown as GeneralRankingData,\n ];\n }\n\n return userDataRes?.map((item) => ({\n ...item,\n rank: getAddressRank(item.address!),\n key: getCurrentAddressRowKey(item.address!),\n }));\n }, [state.address, userDataRes, isLoading, getAddressRank]);\n\n const addRankForList = useCallback(\n (list: GeneralRankingData[], total: number) => {\n return list?.map((item, index) => {\n let rank: string | number = index + 1;\n\n if (searchValue) {\n rank = getAddressRank(item.address);\n } else {\n if (sort?.sort === \"asc\") {\n rank = total - (page - 1) * pageSize - index;\n } else if (sort?.sort === \"desc\") {\n rank = (page - 1) * pageSize + index + 1;\n }\n }\n\n return {\n ...item,\n rank,\n };\n });\n },\n [page, pageSize, sort, searchValue, getAddressRank],\n );\n\n const dataSource = useMemo(() => {\n let list = data?.rows || [];\n if (page === 1) {\n list = list.slice(0, pageSize);\n }\n const total = data?.meta.total || 0;\n const rankList = addRankForList(list, total);\n\n if (page === 1 && !searchValue) {\n return formatData([...userDataList, ...rankList]);\n }\n return formatData(rankList);\n }, [data, page, pageSize, userDataList, searchValue, addRankForList]);\n\n const dataList = useMemo(() => {\n if (!infiniteData?.length) {\n return [];\n }\n\n const total = infiniteData[0]?.meta.total || 0;\n const flatList = infiniteData?.map((item) => item.rows)?.flat();\n const rankList = addRankForList(flatList, total);\n\n if (!searchValue) {\n return formatData([...userDataList, ...rankList]);\n }\n return formatData(rankList);\n }, [infiniteData, userDataList, searchValue, addRankForList]);\n\n const sentinelRef = useRef<HTMLDivElement | null>(null);\n\n const pagination = useMemo(\n () =>\n parsePagination({\n total: data?.meta?.total || 0,\n current_page: data?.meta?.current_page || 1,\n records_per_page: pageSize,\n }),\n [data?.meta?.total, data?.meta?.current_page, pageSize],\n );\n\n useEndReached(sentinelRef, () => {\n if (!isValidating && isMobile) {\n setSize(size + 1);\n }\n });\n\n const onSort = useCallback(\n (sort?: TableSort) => {\n // befause table column dataIndex is not the same as the api sort, so we need to map the sortKey\n if (sort?.sortKey === \"volume\") {\n sort.sortKey = \"perp_volume\";\n } else if (sort?.sortKey === \"pnl\") {\n sort.sortKey = \"realized_pnl\";\n }\n setSort(sort || initialSort);\n },\n [initialSort],\n );\n\n useEffect(() => {\n if (searchValue) {\n setPage(1);\n }\n }, [searchValue]);\n\n useEffect(() => {\n setPage(1);\n }, [state.address]);\n\n useEffect(() => {\n if (dateRange?.to && dateRange?.from) {\n setPage(1);\n }\n }, [dateRange]);\n\n useEffect(() => {\n setSort({ sortKey, sort: \"desc\" });\n }, [sortKey]);\n\n return {\n pagination,\n initialSort,\n onSort,\n dataSource,\n isLoading: isLoading || isValidating,\n isMobile,\n sentinelRef,\n dataList,\n address: state.address,\n };\n}\n\nfunction formatData(data: any[]) {\n return data.map((item) => ({\n ...item,\n volume: item.perp_volume,\n pnl: item.realized_pnl,\n }));\n}\n","import { FC } from \"react\";\nimport { Ranking, RankingProps } from \"../shared/ranking.ui\";\nimport {\n GeneralRankingScriptOptions,\n useGeneralRankingScript,\n} from \"./generalRanking.script\";\n\nexport type GeneralRankingWidgetProps = Pick<\n RankingProps,\n \"style\" | \"className\" | \"fields\"\n> &\n GeneralRankingScriptOptions;\n\nexport const GeneralRankingWidget: FC<GeneralRankingWidgetProps> = (props) => {\n const { dateRange, address, fields, sortKey, ...rest } = props;\n const state = useGeneralRankingScript({\n dateRange,\n address,\n sortKey,\n });\n\n return <Ranking {...state} {...rest} fields={fields} />;\n};\n","import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n useAccount,\n useConfig,\n useInfiniteQuery,\n useQuery,\n} from \"@orderly.network/hooks\";\nimport { API } from \"@orderly.network/types\";\nimport { TableSort, usePagination, useScreen } from \"@orderly.network/ui\";\nimport { useEndReached } from \"../../../hooks/useEndReached\";\nimport { CampaignConfig, UserData } from \"../../campaigns/type\";\nimport { useTradingLeaderboardContext } from \"../../provider\";\nimport { calculateUserPoolReward } from \"../../rewards/utils\";\nimport { getCurrentAddressRowKey, isSameAddress } from \"../shared/util\";\n\nexport type CampaignRankingData = {\n broker_id: string;\n account_id: string;\n address: string;\n volume: number;\n pnl: number;\n total_deposit_amount: number;\n total_withdrawal_amount: number;\n start_account_value: number;\n end_account_value: number;\n\n // custom field\n key?: string;\n rank?: number | string;\n rewards?: {\n amount: number;\n currency: string;\n };\n};\n\ntype CampaignRankingResponse = {\n meta: API.RecordsMeta;\n rows: CampaignRankingData[];\n updated_time: number;\n};\nexport type CampaignRankingScriptReturn = ReturnType<\n typeof useCampaignRankingScript\n>;\n\nexport type CampaignRankingScriptOptions = {\n campaignId: number | string;\n sortKey?: \"volume\" | \"pnl\";\n};\n\nexport function useCampaignRankingScript(\n options: CampaignRankingScriptOptions,\n) {\n const { campaignId, sortKey = \"volume\" } = options;\n const [initialSort] = useState<TableSort>({\n sortKey,\n sort: \"desc\",\n });\n const [sort, setSort] = useState<TableSort | undefined>(initialSort);\n\n const { currentCampaign, setUserData, setUpdatedTime, dataAdapter } =\n useTradingLeaderboardContext();\n\n const { state } = useAccount();\n const brokerId = useConfig(\"brokerId\");\n\n const { isMobile } = useScreen();\n\n const { page, pageSize, setPage, parsePagination } = usePagination({\n pageSize: isMobile ? 100 : 20,\n });\n\n const isCustomData = typeof dataAdapter === \"function\";\n\n const customData = useMemo(() => {\n if (typeof dataAdapter === \"function\") {\n return dataAdapter({ page, pageSize });\n }\n }, [dataAdapter, page, pageSize]);\n\n const getUrl = (args: {\n page: number;\n pageSize: number;\n sort?: string | null;\n }) => {\n if (isCustomData) {\n return null;\n }\n const searchParams = new URLSearchParams();\n\n searchParams.set(\"page\", args.page.toString());\n searchParams.set(\n \"size\",\n // if page is 1, we need to set page size to 100 to get the top 100 data to judge user rank\n args.page === 1 ? \"100\" : args.pageSize.toString(),\n );\n\n if (campaignId) {\n searchParams.set(\"campaign_id\", campaignId.toString());\n }\n\n if (brokerId) {\n searchParams.set(\"broker_id\", brokerId);\n }\n\n if (args.sort) {\n searchParams.set(\"sort_by\", args.sort);\n } else if (args.sort !== null && sort) {\n searchParams.set(\"sort_by\", sort.sortKey);\n }\n\n // https://orderly.network/docs/build-on-omnichain/evm-api/restful-api/public/get-campaign-ranking\n // only get prod ranking data\n return `https://api.orderly.org/v1/public/campaign/ranking?${searchParams.toString()}`;\n };\n\n const { data, isLoading } = useQuery<CampaignRankingResponse>(\n getUrl({ page, pageSize }),\n {\n formatter: (res) => res,\n revalidateOnFocus: false,\n },\n );\n\n const {\n data: infiniteData,\n size,\n setSize,\n isValidating,\n } = useInfiniteQuery<CampaignRankingResponse>(\n (pageIndex: number, previousPageData: any): string | null => {\n // reached the end\n if (previousPageData && !previousPageData.rows?.length) return null;\n\n if (!isMobile) {\n return null;\n }\n\n return getUrl({\n page: pageIndex + 1,\n pageSize,\n });\n },\n {\n initialSize: 1,\n formatter: (res) => res,\n revalidateOnFocus: false,\n },\n );\n\n // it will use first page data cache\n const { data: top100Data } = useQuery<CampaignRankingResponse>(\n state.address\n ? getUrl({\n page: 1,\n pageSize: 100,\n // sort: \"desc\",\n })\n : null,\n {\n formatter: (res) => res,\n revalidateOnFocus: false,\n },\n );\n\n const getUserUrl = () => {\n if (!state.address || !campaignId || isCustomData) {\n return null;\n }\n\n const searchParams = new URLSearchParams();\n\n if (brokerId) {\n searchParams.set(\"broker_id\", brokerId);\n }\n\n searchParams.set(\"campaign_id\", campaignId.toString());\n searchParams.set(\"address\", state.address!);\n\n // https://orderly.network/docs/build-on-omnichain/evm-api/restful-api/public/get-campaign-user-info\n // only get prod user data\n return `https://api.orderly.org/v1/public/campaign/user?${searchParams.toString()}`;\n };\n\n const { data: userDataRes } = useQuery<CampaignRankingData[]>(getUserUrl(), {\n revalidateOnFocus: false,\n });\n\n const getAddressRank = useCallback(\n (address: string) => {\n if (top100Data?.rows?.length === 0) {\n return \"-\";\n }\n\n const index = top100Data?.rows.findIndex((item) =>\n isSameAddress(item.address, address!),\n );\n return index !== -1 ? index! + 1 : \"100+\";\n },\n [top100Data],\n );\n\n const userData = useMemo(() => {\n if (customData) {\n return customData?.userData;\n }\n\n if (!state.address || isLoading) {\n return undefined;\n }\n\n if (!userDataRes) {\n return {\n key: getCurrentAddressRowKey(state.address!),\n address: state.address,\n rank: \"-\",\n } as unknown as CampaignRankingData;\n }\n\n return {\n ...userDataRes,\n address: state.address,\n rank: getAddressRank(state.address!),\n key: getCurrentAddressRowKey(state.address!),\n };\n }, [state.address, userDataRes, isLoading, getAddressRank, customData]);\n\n const addRankForList = useCallback(\n (list: CampaignRankingData[], total: number) => {\n return list?.map((item, index) => {\n let rank: string | number = index + 1;\n\n if (sort?.sort === \"asc\") {\n rank = total - (page - 1) * pageSize - index;\n } else if (sort?.sort === \"desc\") {\n rank = (page - 1) * pageSize + index + 1;\n }\n\n return {\n ...item,\n rank,\n };\n });\n },\n [page, pageSize, sort],\n );\n\n const dataSource = useMemo(() => {\n if (customData) {\n return formatData(customData?.dataSource, currentCampaign, sortKey);\n }\n\n let list = data?.rows || [];\n if (page === 1) {\n list = list.slice(0, pageSize);\n }\n const total = data?.meta.total || 0;\n const rankList = addRankForList(list, total);\n\n const _data =\n page === 1 ? (userData ? [userData, ...rankList] : rankList) : rankList;\n\n return formatData(_data, currentCampaign, sortKey);\n }, [\n data,\n page,\n pageSize,\n userData,\n addRankForList,\n currentCampaign,\n sortKey,\n customData,\n ]);\n\n const dataList = useMemo(() => {\n if (customData) {\n return formatData(customData?.dataList, currentCampaign, sortKey);\n }\n\n if (!infiniteData?.length) {\n return [];\n }\n\n const total = infiniteData[0]?.meta.total || 0;\n const flatList = infiniteData?.map((item) => item.rows)?.flat();\n const rankList = addRankForList(flatList, total);\n\n const _data = userData ? [userData, ...rankList] : rankList;\n\n return formatData(_data, currentCampaign, sortKey);\n }, [\n infiniteData,\n userData,\n addRankForList,\n currentCampaign,\n sortKey,\n customData,\n ]);\n\n const sentinelRef = useRef<HTMLDivElement | null>(null);\n\n const pagination = useMemo(\n () =>\n parsePagination({\n total: customData?.meta?.total || data?.meta?.total || 0,\n current_page:\n customData?.meta?.current_page || data?.meta?.current_page || 1,\n records_per_page: pageSize,\n }),\n [\n data?.meta?.total,\n data?.meta?.current_page,\n pageSize,\n parsePagination,\n customData,\n ],\n );\n\n useEndReached(sentinelRef, () => {\n if (!isValidating && isMobile) {\n setSize(size + 1);\n }\n });\n\n useEffect(() => {\n setPage(1);\n }, [state.address]);\n\n useEffect(() => {\n if (userData) {\n setUserData?.(userData as any);\n }\n }, [userData]);\n\n useEffect(() => {\n const time = customData?.updatedTime || data?.updated_time || 0;\n setUpdatedTime?.(time);\n // when currentCampaign changed, we need to reset the campaign ranking list updated time\n }, [data, currentCampaign, customData]);\n\n useEffect(() => {\n setSort({ sortKey, sort: \"desc\" });\n }, [sortKey]);\n\n return {\n pagination,\n initialSort,\n dataSource,\n isLoading: isLoading || isValidating || customData?.loading,\n isMobile,\n sentinelRef,\n dataList,\n address: state.address,\n };\n}\n\nfunction formatData(\n data?: any[],\n currentCampaign?: CampaignConfig,\n metric?: \"volume\" | \"pnl\",\n) {\n const pool = currentCampaign?.prize_pools?.find(\n (item) => item.metric === metric,\n );\n\n return data?.map((item) => {\n const rewards = pool ? calculateUserPoolReward(item as UserData, pool!) : 0;\n\n return {\n ...item,\n rewards: {\n amount: rewards,\n currency: pool?.currency,\n },\n };\n });\n}\n","import {\n TicketTierRule,\n TicketLinearRule,\n TicketRules,\n CampaignConfig,\n UserData,\n PrizePool,\n} from \"../campaigns/type\";\n\n/**\n * Get user metric value based on pool metric type\n */\nfunction getUserMetricValue(\n userdata: UserData,\n metric: \"volume\" | \"pnl\",\n): number {\n return metric === \"volume\" ? userdata.volume : userdata.pnl;\n}\n\n/**\n * Estimate user's rank based on current performance\n */\nfunction estimateUserRank(\n userdata: UserData,\n metric: \"volume\" | \"pnl\",\n): number | null {\n // If we have actual rank data, use it\n if (userdata.rank) {\n return Number(userdata.rank);\n }\n\n // Otherwise, make a simple estimation based on performance\n const userMetricValue = getUserMetricValue(userdata, metric);\n const totalParticipants = userdata.total_participants || 1000;\n\n if (userMetricValue <= 0) return null;\n\n // Simple heuristic: assume better performance means better rank\n // In reality, you would compare against actual leaderboard data\n if (userMetricValue >= 100000) return 1;\n if (userMetricValue >= 50000) return Math.floor(totalParticipants * 0.05); // Top 5%\n if (userMetricValue >= 10000) return Math.floor(totalParticipants * 0.2); // Top 20%\n if (userMetricValue >= 1000) return Math.floor(totalParticipants * 0.5); // Top 50%\n\n return Math.floor(totalParticipants * 0.8); // Bottom 80%\n}\n\n/**\n * Find reward amount for user based on estimated rank in a specific pool\n */\nfunction findRewardInPool(userdata: UserData, pool: PrizePool): number {\n const userMetricValue = getUserMetricValue(userdata, pool.metric);\n\n // Skip if user has no relevant data\n if (userMetricValue <= 0) return 0;\n\n const estimatedRank = estimateUserRank(userdata, pool.metric);\n if (estimatedRank === null) return 0;\n\n // Find matching tier based on estimated rank\n for (const tier of pool.tiers) {\n let isInTier = false;\n\n if (tier.position && estimatedRank === tier.position) {\n isInTier = true;\n } else if (tier.position_range) {\n const [start, end] = tier.position_range;\n if (estimatedRank >= start && estimatedRank <= end) {\n isInTier = true;\n }\n }\n\n if (isInTier) {\n return tier.amount;\n }\n }\n\n return 0;\n}\n\n/**\n * Calculate estimated rewards based on user's current performance and campaign configuration\n * @param userdata User's current trading data\n * @param campaign Campaign configuration\n * @returns Estimated reward amount with currency\n */\nexport function calculateEstimatedRewards(\n userdata: UserData,\n campaign: CampaignConfig,\n): { amount: number; currency: string } | null {\n if (!campaign.prize_pools || campaign.prize_pools.length === 0) {\n return null;\n }\n\n let totalEstimatedReward = 0;\n const mainCurrency = campaign.prize_pools[0].currency;\n\n // Only sum rewards from pools with the same currency to avoid mixing different currencies\n for (const pool of campaign.prize_pools) {\n totalEstimatedReward += findRewardInPool(userdata, pool);\n }\n\n return totalEstimatedReward > 0\n ? { amount: totalEstimatedReward, currency: mainCurrency }\n : null;\n}\n\n/**\n * Calculate estimated tickets earned based on user's trading performance\n * @param userdata User's current trading data\n * @param ticketRules Ticket configuration rules\n * @returns Estimated number of tickets\n */\nexport function calculateEstimatedTickets(\n userdata: UserData,\n ticketRules: TicketRules,\n): number {\n const userMetricValue =\n ticketRules.metric === \"volume\" ? userdata.volume : userdata.pnl;\n\n if (!userMetricValue) return 0;\n\n if (userMetricValue <= 0) return 0;\n\n if (ticketRules.mode === \"tiered\") {\n return calculateTieredTickets(userMetricValue, ticketRules.tiers || []);\n } else if (ticketRules.mode === \"linear\") {\n return calculateLinearTickets(userMetricValue, ticketRules.linear);\n }\n\n return 0;\n}\n\n/**\n * Calculate tickets using tiered mode\n * ≥ 25,000 volume → 10 tickets\n * ≥ 10,000 and < 25,000 → 5 tickets\n * ≥ 5,000 and < 10,000 → 1 ticket\n * < 5,000 → 0 tickets\n */\nfunction calculateTieredTickets(\n metricValue: number,\n tiers: TicketTierRule[],\n): number {\n // Sort tiers by value in descending order\n const sortedTiers = [...tiers].sort((a, b) => b.value - a.value);\n\n for (const tier of sortedTiers) {\n if (metricValue >= tier.value) {\n return tier.tickets;\n }\n }\n\n return 0;\n}\n\n/**\n * Calculate tickets using linear mode\n * Get X ticket for every Y volume/pnl\n */\nfunction calculateLinearTickets(\n metricValue: number,\n linearRule?: TicketLinearRule,\n): number {\n if (!linearRule || linearRule.every <= 0) return 0;\n\n const multiplier = Math.floor(metricValue / linearRule.every);\n return multiplier * linearRule.tickets;\n}\n\n/**\n * Format reward amount with currency for display\n */\nexport function formatRewardAmount(amount: number, currency: string): string {\n return `${amount.toLocaleString()} ${currency}`;\n}\n\n/**\n * Format ticket count for display\n */\nexport function formatTicketCount(tickets: number): string {\n return tickets.toLocaleString();\n}\n\n/**\n * Calculate user's estimated reward for a specific prize pool\n * @param userdata User's current trading data\n * @param pool Specific prize pool\n * @returns Estimated reward amount for this pool, or 0 if not eligible\n */\nexport function calculateUserPoolReward(\n userdata: UserData,\n pool: PrizePool,\n): number {\n return findRewardInPool(userdata, pool);\n}\n\n/**\n * Calculate progress percentage and next tier requirements for tickets\n * @param userdata User's current trading data\n * @param ticketRules Ticket configuration rules\n * @returns Object containing progress percentage and next tier requirements\n */\nexport function calculateTicketProgress(\n userdata: UserData,\n ticketRules: TicketRules,\n): { percent: number; value: number; atMax?: boolean } | null {\n if (!userdata || !ticketRules) return null;\n\n const userMetricValue = getUserMetricValue(userdata, ticketRules.metric);\n\n if (!userMetricValue) {\n if (ticketRules.mode === \"linear\") {\n return {\n percent: 0,\n value: ticketRules.linear?.every || 0,\n };\n } else {\n return {\n percent: 0,\n value: ticketRules.tiers?.[0]?.value || 0,\n };\n }\n }\n\n if (ticketRules.mode === \"linear\") {\n if (!ticketRules.linear) return null;\n\n const { every, tickets } = ticketRules.linear;\n const currentTier = Math.floor(userMetricValue / every);\n const nextTier = currentTier + 1;\n const progress = ((userMetricValue % every) / every) * 100;\n const nextTierValue = nextTier * every;\n\n return {\n percent: progress,\n value: nextTierValue - userMetricValue,\n };\n }\n\n if (ticketRules.mode === \"tiered\" && ticketRules.tiers) {\n const sortedTiers = [...ticketRules.tiers].sort(\n (a, b) => a.value - b.value,\n );\n\n // Check if tiers array is empty\n if (sortedTiers.length === 0) {\n return null;\n }\n\n // Special case: if user metric value is 0 or negative, show progress to first tier\n if (userMetricValue <= 0) {\n return {\n percent: 0,\n value: sortedTiers[0].value,\n };\n }\n\n // Find current tier and next tier\n let currentTier = null;\n let nextTier = sortedTiers[0]; // Default next tier is the first one\n\n for (let i = 0; i < sortedTiers.length; i++) {\n if (userMetricValue >= sortedTiers[i].value) {\n currentTier = sortedTiers[i];\n nextTier = sortedTiers[i + 1] || null; // Next tier or null if at max\n } else {\n // User hasn't reached this tier yet, so this is the next tier\n nextTier = sortedTiers[i];\n break;\n }\n }\n\n if (!nextTier) {\n return {\n percent: 100,\n value: 0,\n atMax: true,\n };\n }\n\n // If user hasn't reached any tier yet, calculate progress to first tier\n if (!currentTier) {\n const progress = (userMetricValue / nextTier.value) * 100;\n return {\n percent: progress,\n value: nextTier.value - userMetricValue,\n };\n }\n\n const progress =\n ((userMetricValue - currentTier.value) /\n (nextTier.value - currentTier.value)) *\n 100;\n\n return {\n percent: progress,\n value: nextTier.value - userMetricValue,\n };\n }\n\n return null;\n}\n","import { FC } from \"react\";\nimport { Ranking, RankingProps } from \"../shared/ranking.ui\";\nimport {\n CampaignRankingScriptOptions,\n useCampaignRankingScript,\n} from \"./campaignRanking.script\";\n\nexport type CampaignRankingWidgetProps = Pick<\n RankingProps,\n \"style\" | \"className\" | \"fields\"\n> &\n CampaignRankingScriptOptions;\n\nexport const CampaignRankingWidget: FC<CampaignRankingWidgetProps> = (\n props,\n) => {\n const { campaignId, fields, sortKey, ...rest } = props;\n const state = useCampaignRankingScript({\n campaignId,\n sortKey,\n });\n\n // @ts-ignore\n return <Ranking {...state} {...rest} fields={fields} />;\n};\n","import { useCallback, useMemo, useState } from \"react\";\nimport { differenceInDays } from \"date-fns\";\nimport { DateRange, LeaderboardTab } from \"../../../type\";\nimport { formatDateRange, getDateRange } from \"../../../utils\";\n\nexport type GeneralLeaderboardScriptReturn = ReturnType<\n typeof useGeneralLeaderboardScript\n>;\n\nexport const FilterDays = [7, 14, 30, 90] as const;\nexport type TFilterDays = (typeof FilterDays)[number];\n\nexport function useGeneralLeaderboardScript() {\n const [activeTab, setActiveTab] = useState<LeaderboardTab>(\n LeaderboardTab.Volume,\n );\n const filterState = useFilter();\n const searchState = useSearch();\n\n return {\n ...filterState,\n ...searchState,\n activeTab,\n onTabChange: setActiveTab,\n };\n}\n\nfunction useFilter() {\n // default is 90d\n const [filterDay, setFilterDay] = useState<TFilterDays | null>(90);\n\n const [dateRange, setDateRange] = useState<DateRange>(getDateRange(90));\n\n const updateFilterDay = (day: TFilterDays) => {\n setFilterDay(day);\n setDateRange(getDateRange(day));\n };\n\n const onFilter = (filter: { name: string; value: any }) => {\n if (filter.name === \"dateRange\") {\n const newDateRange = filter.value;\n setDateRange(newDateRange);\n\n if (newDateRange.from && newDateRange.to) {\n const offsetDay =\n Math.abs(differenceInDays(newDateRange.from, newDateRange.to)) + 1;\n\n const dateRange = getDateRange(offsetDay);\n if (\n formatDateRange(dateRange.from) ===\n formatDateRange(newDateRange.from) &&\n formatDateRange(dateRange.to) === formatDateRange(newDateRange.to)\n ) {\n setFilterDay(offsetDay as any);\n } else {\n setFilterDay(null);\n }\n }\n }\n };\n\n const filterItems = useMemo(() => {\n const dateRangeFilter = {\n type: \"range\",\n name: \"dateRange\",\n value: dateRange,\n max: 90,\n };\n\n return [dateRangeFilter] as any;\n }, [dateRange]);\n\n return {\n filterItems,\n onFilter,\n dateRange,\n filterDay,\n updateFilterDay,\n };\n}\n\nfunction useSearch() {\n const [searchValue, setSearchValue] = useState(\"\");\n const onSearchValueChange = useCallback((value: string) => {\n setSearchValue(value);\n }, []);\n\n const clearSearchValue = useCallback(() => {\n setSearchValue(\"\");\n }, []);\n\n return {\n searchValue,\n onSearchValueChange,\n clearSearchValue,\n };\n}\n","import { FC, useMemo } from \"react\";\nimport { cn, Box, useScreen, Divider } from \"@orderly.network/ui\";\nimport { LeaderboardTab } from \"../../../type\";\nimport { GeneralRankingWidget } from \"../../ranking/generalRanking\";\nimport { RankingColumnFields } from \"../../ranking/shared/column\";\nimport { LeaderboardFilter } from \"../shared/LeaderboardFilter\";\nimport { LeaderboardTabs } from \"../shared/LeaderboardTabs\";\nimport { GeneralLeaderboardScriptReturn } from \"./generalLeaderboard.script\";\n\nexport type GeneralLeaderboardProps = {\n style?: React.CSSProperties;\n className?: string;\n} & GeneralLeaderboardScriptReturn;\n\nexport const GeneralLeaderboard: FC<GeneralLeaderboardProps> = (props) => {\n const { isMobile } = useScreen();\n\n const fields = useMemo<RankingColumnFields[]>(() => {\n if (isMobile) {\n return [\n \"rank\",\n \"address\",\n props.activeTab === LeaderboardTab.Volume ? \"volume\" : \"pnl\",\n ];\n }\n return [\"rank\", \"address\", \"volume\", \"pnl\"];\n }, [isMobile, props.activeTab]);\n\n if (isMobile) {\n return (\n <Box\n pt={2}\n px={3}\n r=\"2xl\"\n intensity={900}\n width=\"100%\"\n className={cn(\n \"oui-trading-leaderboard-general-leaderboard oui-relative\",\n props.className,\n )}\n style={props.style}\n >\n <LeaderboardFilter {...props} />\n <LeaderboardTabs\n isMobile={isMobile}\n className=\"oui-pt-0\"\n activeTab={props.activeTab}\n onTabChange={props.onTabChange}\n />\n\n <GeneralRankingWidget\n dateRange={props.dateRange}\n address={props.searchValue}\n sortKey={\n props.activeTab === LeaderboardTab.Volume\n ? \"perp_volume\"\n : \"realized_pnl\"\n }\n fields={fields}\n />\n </Box>\n );\n }\n\n return (\n <Box\n pt={2}\n px={6}\n r=\"2xl\"\n intensity={900}\n className={cn(\n \"oui-trading-leaderboard-general-leaderboard oui-relative\",\n \"oui-mx-auto oui-max-w-[992px]\",\n props.className,\n )}\n style={props.style}\n >\n <LeaderboardFilter {...props} />\n <Divider intensity={8} />\n\n <GeneralRankingWidget\n dateRange={props.dateRange}\n address={props.searchValue}\n fields={fields}\n />\n </Box>\n );\n};\n","import { FC, SVGProps } from \"react\";\nimport { useTranslation } from \"@orderly.network/i18n\";\nimport {\n Box,\n CloseCircleFillIcon,\n cn,\n DataFilter,\n Flex,\n Input,\n Text,\n useScreen,\n} from \"@orderly.network/ui\";\nimport { ScrollIndicator } from \"@orderly.network/ui\";\nimport {\n FilterDays,\n GeneralLeaderboardScriptReturn,\n} from \"../generalLeaderboard/generalLeaderboard.script\";\n\nexport type LeaderboardFilterProps = GeneralLeaderboardScriptReturn;\n\nexport const LeaderboardFilter: FC<LeaderboardFilterProps> = (props) => {\n const { t } = useTranslation();\n const { isMobile } = useScreen();\n\n const input = (\n <Input\n value={props.searchValue}\n onValueChange={props.onSearchValueChange}\n placeholder={t(\"common.address.search.placeholder\")}\n className={cn(\n \"oui-trading-leaderboard-trading-search-input\",\n \"oui-w-full\",\n )}\n size=\"sm\"\n prefix={\n <Box pl={3} pr={1}>\n <SearchIcon className=\"oui-text-base-contrast-36\" />\n </Box>\n }\n suffix={\n props.searchValue && (\n <Box mr={2}>\n <CloseCircleFillIcon\n size={14}\n className=\"oui-cursor-pointer oui-text-base-contrast-36\"\n onClick={props.clearSearchValue}\n />\n </Box>\n )\n }\n autoComplete=\"off\"\n />\n );\n\n const dateRangeView = props.filterItems.length > 0 && (\n <DataFilter\n items={props.filterItems}\n onFilter={(value) => {\n props.onFilter(value);\n }}\n className=\"oui-h-[53px] oui-border-none\"\n />\n );\n\n const filterDayView = FilterDays.map((value) => {\n return (\n <button\n className=\"oui-relative oui-px-2 oui-py-[2px] oui-text-sm\"\n key={value}\n >\n <div className=\"oui-z-10\">\n <Text.gradient\n color={props.filterDay === value ? \"brand\" : undefined}\n className={\n props.filterDay !== value ? \"oui-text-base-contrast-54\" : \"\"\n }\n >\n {`${value}D`}\n </Text.gradient>\n </div>\n <div\n className=\"oui-absolute oui-inset-0 oui-rounded oui-opacity-[.12] oui-gradient-primary\"\n onClick={() => {\n props.updateFilterDay(value as any);\n }}\n ></div>\n </button>\n );\n });\n\n if (isMobile) {\n return (\n <Flex\n width=\"100%\"\n justify=\"between\"\n itemAlign=\"center\"\n direction=\"column\"\n mt={3}\n className={cn(\"oui-mobile-trading-leaderboard-ranking-filter\")}\n >\n {input}\n <Flex gap={3} className=\"oui-w-full\">\n {dateRangeView}\n <ScrollIndicator className=\"oui-w-full\">\n <Flex gap={3}>{filterDayView}</Flex>\n </ScrollIndicator>\n </Flex>\n </Flex>\n );\n }\n\n return (\n <Flex\n width=\"100%\"\n justify=\"between\"\n itemAlign=\"center\"\n className={cn(\"oui-trading-leaderboard-ranking-filter\")}\n >\n <Flex gap={3}>\n {dateRangeView}\n {filterDayView}\n </Flex>\n <Box width={240}>{input}</Box>\n </Flex>\n );\n};\n\nexport const SearchIcon: FC<SVGProps<SVGSVGElement>> = (props) => (\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 14 14\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path d=\"M5.841 1.14a4.667 4.667 0 0 0 0 9.333 4.74 4.74 0 0 0 2.875-.975l2.54 2.56a.6.6 0 0 0 .838 0 .6.6 0 0 0 0-.838L9.537 8.677a4.72 4.72 0 0 0 .971-2.871 4.667 4.667 0 0 0-4.667-4.667m0 1.166a3.5 3.5 0 1 1 0 7 3.5 3.5 0 0 1 0-7\" />\n </svg>\n);\n","import { FC, useEffect, useMemo } from \"react\";\nimport { useTranslation } from \"@orderly.network/i18n\";\nimport { cn, Flex, TabPanel, Tabs } from \"@orderly.network/ui\";\nimport { LeaderboardTab } from \"../../../type\";\nimport { formatUpdateDate } from \"../../../utils\";\nimport { useTradingLeaderboardContext } from \"../../provider\";\n\ntype LeaderboardTabsProps = {\n isMobile?: boolean;\n className?: string;\n activeTab: LeaderboardTab;\n onTabChange: (tab: LeaderboardTab) => void;\n};\n\nexport const LeaderboardTabs: FC<LeaderboardTabsProps> = (props) => {\n const { t } = useTranslation();\n const { updatedTime, currentCampaign } = useTradingLeaderboardContext();\n\n const updateTime = useMemo(() => {\n if (updatedTime && currentCampaign) {\n return formatUpdateDate(updatedTime);\n }\n return \"\";\n }, [props.isMobile, updatedTime, currentCampaign]);\n\n const { showVolume, showPnl } = useMemo(() => {\n const metrics = currentCampaign?.prize_pools?.map((item) => item.metric);\n const isMobileGeneral = props.isMobile && !currentCampaign;\n const showVolume = isMobileGeneral\n ? true\n : metrics?.includes(LeaderboardTab.Volume);\n const showPnl = isMobileGeneral\n ? true\n : metrics?.includes(LeaderboardTab.Pnl);\n\n return {\n showVolume,\n showPnl,\n };\n }, [currentCampaign, props.activeTab, props.isMobile]);\n\n useEffect(() => {\n // set default tab\n if (showVolume && showPnl) {\n props.onTabChange(LeaderboardTab.Volume);\n } else if (showVolume) {\n props.onTabChange(LeaderboardTab.Volume);\n } else if (showPnl) {\n props.onTabChange(LeaderboardTab.Pnl);\n }\n }, [currentCampaign, showVolume, showPnl]);\n\n const renderTabs = () => {\n if (showVolume && showPnl) {\n return (\n <Tabs\n value={props.activeTab}\n onValueChange={props.onTabChange as (tab: string) => void}\n variant=\"contained\"\n size=\"lg\"\n key={currentCampaign?.campaign_id}\n >\n <TabPanel\n title={t(\"tradingLeaderboard.tradingVolume\")}\n value={LeaderboardTab.Volume}\n ></TabPanel>\n <TabPanel\n title={t(\"tradingLeaderboard.realizedPnl\")}\n value={LeaderboardTab.Pnl}\n ></TabPanel>\n </Tabs>\n );\n }\n\n if (showVolume) {\n return (\n <Tabs\n value={props.activeTab}\n onValueChange={props.onTabChange as (tab: string) => void}\n variant=\"contained\"\n size=\"lg\"\n key={currentCampaign?.campaign_id}\n >\n <TabPanel\n title={t(\"tradingLeaderboard.tradingVolume\")}\n value={LeaderboardTab.Volume}\n ></TabPanel>\n </Tabs>\n );\n }\n\n if (showPnl) {\n return (\n <Tabs\n value={props.activeTab}\n onValueChange={props.onTabChange as (tab: string) => void}\n variant=\"contained\"\n size=\"lg\"\n key={currentCampaign?.campaign_id}\n >\n <TabPanel\n title={t(\"tradingLeaderboard.realizedPnl\")}\n value={LeaderboardTab.Pnl}\n ></TabPanel>\n </Tabs>\n );\n }\n return <div></div>;\n };\n\n return (\n <Flex\n width=\"100%\"\n py={3}\n justify=\"between\"\n className={cn(\n \"oui-trading-leaderboard-ranking-tabs\",\n \"oui-border-b oui-border-line\",\n props.className,\n )}\n >\n {renderTabs()}\n {/* <Tabs\n value={props.activeTab}\n onValueChange={props.onTabChange as (tab: string) => void}\n variant=\"contained\"\n size=\"lg\"\n >\n <TabPanel\n title=\"Trading volume\"\n value={LeaderboardTab.Volume}\n ></TabPanel>\n <TabPanel title=\"Realized PnL\" value={LeaderboardTab.Pnl}></TabPanel>\n </Tabs> */}\n {updateTime && (\n <Flex\n itemAlign=\"start\"\n direction={props.isMobile ? \"column\" : \"row\"}\n gap={1}\n className={cn(\n props.isMobile ? \"oui-text-3xs\" : \"oui-text-sm\",\n \"oui-text-base-contrast-36\",\n )}\n >\n <span>{t(\"tradingLeaderboard.lastUpdate\")}:</span>\n <span>{updateTime}</span>\n </Flex>\n )}\n </Flex>\n );\n};\n","import { FC } from \"react\";\nimport { useGeneralLeaderboardScript } from \"./generalLeaderboard.script\";\nimport {\n GeneralLeaderboard,\n GeneralLeaderboardProps,\n} from \"./generalLeaderboard.ui\";\n\nexport type GeneralLeaderboardWidgetProps = Pick<\n GeneralLeaderboardProps,\n \"style\" | \"className\"\n>;\n\nexport const GeneralLeaderboardWidget: FC<GeneralLeaderboardWidgetProps> = (\n props,\n) => {\n const state = useGeneralLeaderboardScript();\n\n return (\n <GeneralLeaderboard\n {...state}\n className={props.className}\n style={props.style}\n />\n );\n};\n","import { useMemo, useState } from \"react\";\nimport { LeaderboardTab } from \"../../../type\";\nimport { useTradingLeaderboardContext } from \"../../provider\";\n\nexport type CampaignLeaderboardScriptReturn = ReturnType<\n typeof useCampaignLeaderboardScript\n>;\n\nexport function useCampaignLeaderboardScript() {\n const [activeTab, setActiveTab] = useState<LeaderboardTab>(\n LeaderboardTab.Volume,\n );\n const { currentCampaign } = useTradingLeaderboardContext();\n\n const excludeColumns = useMemo(() => {\n return currentCampaign?.exclude_leaderboard_columns || [];\n }, [currentCampaign]);\n\n return {\n activeTab,\n onTabChange: setActiveTab,\n excludeColumns,\n };\n}\n","import { FC, useMemo } from \"react\";\nimport { difference } from \"ramda\";\nimport { cn, Box, useScreen } from \"@orderly.network/ui\";\nimport { LeaderboardTab } from \"../../../type\";\nimport { CampaignRankingWidget } from \"../../ranking/campaignRanking\";\nimport { RankingColumnFields } from \"../../ranking/shared/column\";\nimport { LeaderboardTabs } from \"../shared/LeaderboardTabs\";\nimport { CampaignLeaderboardScriptReturn } from \"./campaignLeaderboard.script\";\n\nexport type CampaignLeaderboardProps = {\n style?: React.CSSProperties;\n className?: string;\n campaignId: number | string;\n} & CampaignLeaderboardScriptReturn;\n\nexport const CampaignLeaderboard: FC<CampaignLeaderboardProps> = (props) => {\n const { isMobile } = useScreen();\n\n const sortKey = useMemo(() => {\n return props.activeTab === LeaderboardTab.Volume ? \"volume\" : \"pnl\";\n }, [props.activeTab]);\n\n const fields = useMemo<RankingColumnFields[]>(() => {\n const allFields: RankingColumnFields[] = [\n \"rank\",\n \"address\",\n sortKey,\n \"rewards\",\n ];\n return difference(allFields, props.excludeColumns || []);\n }, [isMobile, sortKey, props.excludeColumns]);\n\n if (isMobile) {\n return (\n <Box\n pt={2}\n px={3}\n r=\"2xl\"\n intensity={900}\n width=\"100%\"\n className={cn(\n \"oui-trading-leaderboard-campaign-leaderboard oui-relative\",\n )}\n >\n <LeaderboardTabs\n isMobile={isMobile}\n activeTab={props.activeTab}\n onTabChange={props.onTabChange}\n />\n\n <CampaignRankingWidget\n campaignId={props.campaignId}\n fields={fields}\n sortKey={sortKey}\n />\n </Box>\n );\n }\n\n return (\n <Box\n pt={2}\n px={6}\n r=\"2xl\"\n intensity={900}\n className={cn(\n \"oui-trading-leaderboard-campaign-leaderboard oui-relative\",\n \"oui-mx-auto oui-max-w-[992px]\",\n )}\n >\n <LeaderboardTabs\n isMobile={isMobile}\n activeTab={props.activeTab}\n onTabChange={props.onTabChange}\n />\n <CampaignRankingWidget\n campaignId={props.campaignId}\n fields={fields}\n sortKey={sortKey}\n />\n </Box>\n );\n};\n","import { FC } from \"react\";\nimport { useCampaignLeaderboardScript } from \"./campaignLeaderboard.script\";\nimport {\n CampaignLeaderboard,\n CampaignLeaderboardProps,\n} from \"./campaignLeaderboard.ui\";\n\nexport type CampaignLeaderboardWidgetProps = Pick<\n CampaignLeaderboardProps,\n \"style\" | \"className\" | \"campaignId\"\n>;\n\nexport const CampaignLeaderboardWidget: FC<CampaignLeaderboardWidgetProps> = (\n props,\n) => {\n const state = useCampaignLeaderboardScript();\n\n return (\n <CampaignLeaderboard\n {...state}\n className={props.className}\n style={props.style}\n campaignId={props.campaignId}\n />\n );\n};\n","import { FC, ReactNode } from \"react\";\nimport { useTranslation } from \"@orderly.network/i18n\";\nimport { Box, cn, Flex, Text, useScreen } from \"@orderly.network/ui\";\nimport { Background } from \"../../components/background\";\nimport { CampaignsWidget } from \"../../components/campaigns/campaigns.widget\";\nimport { CampaignLeaderboardWidget } from \"../../components/leaderboard/campaignLeaderboard\";\nimport {\n GeneralLeaderboardWidget,\n GeneralLeaderboardWidgetProps,\n} from \"../../components/leaderboard/generalLeaderboard\";\nimport {\n TradingLeaderboardProvider,\n TradingLeaderboardProviderProps,\n useTradingLeaderboardContext,\n} from \"../../components/provider\";\nimport { RewardsWidget } from \"../../components/rewards/rewards.widget\";\nimport { RuleWidget } from \"../../components/rule\";\n\nexport type LeaderboardPageProps = GeneralLeaderboardWidgetProps &\n TradingLeaderboardProviderProps & {\n style?: React.CSSProperties;\n className?: string;\n };\n\nexport const LeaderboardPage: FC<LeaderboardPageProps> = (props) => {\n return (\n <TradingLeaderboardProvider {...props}>\n <div\n style={{\n paddingBottom: \"calc(64px + env(safe-area-inset-bottom))\",\n }}\n className={cn(\n \"oui-trading-leaderboard-page\",\n \"oui-relative oui-bg-base-10\",\n \"oui-font-semibold\",\n props.className,\n )}\n >\n <CampaignsWidget className=\"oui-relative oui-z-[1] oui-mx-6\" />\n <RewardsWidget />\n <LeaderboardSection {...props} />\n <RuleWidget />\n </div>\n </TradingLeaderboardProvider>\n );\n};\n\ntype LeaderboardSectionProps = {\n style?: React.CSSProperties;\n className?: string;\n};\n\nexport const LeaderboardSection: FC<LeaderboardSectionProps> = (props) => {\n const { t } = useTranslation();\n const { isMobile } = useScreen();\n const { currentCampaignId, currentCampaign, backgroundSrc } =\n useTradingLeaderboardContext();\n\n if (currentCampaignId === \"general\") {\n return (\n <Box px={3} className={cn(\"oui-mix-blend-screen\")}>\n <Background backgroundSrc={backgroundSrc} />\n <GeneralLeaderboardWidget {...props} className=\"oui-mt-10\" />\n </Box>\n );\n }\n\n if (\n currentCampaign &&\n !currentCampaign.hide_arena &&\n currentCampaignId != \"general\"\n ) {\n return (\n <Box px={3}>\n <LeaderboardTitle\n title={t(\"tradingLeaderboard.arena\")}\n isMobile={isMobile}\n />\n <CampaignLeaderboardWidget {...props} campaignId={currentCampaignId} />\n </Box>\n );\n }\n\n return null;\n};\n\nexport const LeaderboardTitle = (props: {\n title: ReactNode;\n isMobile?: boolean;\n}) => {\n return (\n <Flex\n mb={props.isMobile ? 3 : 6}\n gapY={1}\n justify=\"center\"\n direction=\"column\"\n >\n <Text\n className={cn(\n \"oui-trading-leaderboard-title oui-font-bold\",\n props.isMobile\n ? \"oui-text-[20px] oui-leading-[24px]\"\n : \"oui-text-[32px] oui-leading-[44px]\",\n )}\n >\n {props.title}\n </Text>\n <Box\n width={24}\n height={6}\n r=\"base\"\n className=\"oui-bg-[linear-gradient(270deg,rgb(var(--oui-gradient-brand-start))_0%,rgb(var(--oui-gradient-brand-end))_100%)]\"\n />\n </Flex>\n );\n};\n","import { FC, useMemo } from \"react\";\nimport { cn, useScreen } from \"@orderly.network/ui\";\n\ntype BackgroundProps = {\n backgroundSrc?: string;\n};\n\nexport const Background: FC<BackgroundProps> = (props) => {\n const { isMobile } = useScreen();\n\n const isVideo = useMemo(() => {\n return isVideoSrc(props.backgroundSrc);\n }, [props.backgroundSrc]);\n\n if (isMobile) {\n return null;\n }\n\n const linearGradient =\n \"linear-gradient(180deg, rgba(var(--oui-color-base-10) / 0.3) 0%, rgba(var(--oui-color-base-10) / 0) 70%, rgba(var(--oui-color-base-10) / 1) 100%)\";\n\n if (isVideo) {\n return (\n <div className={cn(\"oui-absolute oui-left-0 oui-top-0\", \"oui-size-full\")}>\n <div\n style={{\n backgroundImage: linearGradient,\n backgroundSize: \"cover\",\n backgroundRepeat: \"no-repeat\",\n }}\n className={cn(\"oui-absolute oui-left-0 oui-top-0\", \"oui-size-full\")}\n />\n <video\n autoPlay\n loop\n muted\n className={cn(\n // rest style\n \"oui-border-none oui-bg-transparent oui-outline-none\",\n \"oui-size-full\",\n // \"oui-absolute oui-top-0 oui-left-0\",\n \"oui-object-cover\",\n \"oui-opacity-50\",\n )}\n >\n <source src={props.backgroundSrc} type=\"video/mp4\" />\n <source src={props.backgroundSrc} type=\"video/webm\" />\n <source src={props.backgroundSrc} type=\"video/ogg\" />\n <source src={props.backgroundSrc} type=\"video/avi\" />\n Your browser does not support the video tag.\n </video>\n </div>\n );\n }\n\n if (props.backgroundSrc) {\n return (\n <div\n style={{\n backgroundImage: `${linearGradient}, url(${props.backgroundSrc}) `,\n backgroundSize: \"cover\",\n backgroundRepeat: \"no-repeat\",\n }}\n className={cn(\n \"oui-general-leaderboard-background\",\n \"oui-absolute oui-left-0 oui-top-0 oui-z-[-1]\",\n \"oui-size-full\",\n \"oui-opacity-50\",\n )}\n />\n );\n }\n};\n\nfunction isVideoSrc(src?: string) {\n const extension = src?.split(\".\").pop();\n return [\"mp4\", \"webm\", \"avi\", \"ogg\"].includes(extension ?? \"\");\n}\n","import { FC, useMemo } from \"react\";\nimport { cn, useScreen } from \"@orderly.network/ui\";\nimport { CampaignsContentDesktopUI } from \"./campaigns.content.desktop.ui\";\nimport { useCampaignsScript } from \"./campaigns.script\";\nimport { CampaignsTimeDesktopUI } from \"./components/time.desktop.ui\";\nimport { CampaignsHeaderWidget } from \"./header\";\n\nexport type CampaignsWidgetProps = {\n className?: string;\n style?: React.CSSProperties;\n};\n\nexport const CampaignsWidget: FC<CampaignsWidgetProps> = (props) => {\n const state = useCampaignsScript();\n const { isMobile } = useScreen();\n\n const contentClassNames = useMemo(() => {\n if (!isMobile) return undefined;\n return {\n container: \"oui-h-[400px] oui-gap-5\",\n time: \"oui-text-sm oui-h-5\",\n title: \"oui-text-[24px] oui-leading-[32px]\",\n description: \"oui-text-2xs oui-leading-[15px]\",\n topContainer: \"oui-gap-1 oui-w-[284px]\",\n };\n }, [isMobile]);\n\n return (\n <div\n className={cn([\"oui-relative oui-z-[1] oui-overflow-hidden\"])}\n style={props.style}\n >\n <CampaignsHeaderWidget\n backgroundSrc={state.backgroundSrc}\n campaigns={state.campaigns}\n currentCampaignId={state.currentCampaignId.toString()}\n onCampaignChange={state.onCampaignChange}\n />\n {state.currentCampaign && (\n <CampaignsContentDesktopUI\n campaign={state.currentCampaign}\n statistics={state.statistics}\n onLearnMore={state.onLearnMore}\n onTradeNow={state.onTradeNow}\n backgroundSrc={state.backgroundSrc}\n classNames={contentClassNames}\n isMobile={isMobile}\n isParticipated={state.isParticipated}\n shouldShowJoinButton={state.shouldShowJoinButton}\n joinCampaign={state.joinCampaign}\n isJoining={state.isJoining}\n joinError={state.joinError}\n canTrade={state.canTrade}\n />\n )}\n {state.currentCampaign && (\n <CampaignsTimeDesktopUI\n campaign={state.currentCampaign}\n isMobile={isMobile}\n />\n )}\n </div>\n );\n};\n","import { FC, useMemo, useState } from \"react\";\nimport { useTranslation } from \"@orderly.network/i18n\";\nimport { AccountStatusEnum } from \"@orderly.network/types\";\nimport {\n cn,\n Text,\n InfoCircleIcon,\n Button,\n Tooltip,\n ChevronRightIcon,\n} from \"@orderly.network/ui\";\nimport { AuthGuard } from \"@orderly.network/ui-connector\";\nimport { CampaignConfig, CampaignStatistics } from \"./type\";\nimport {\n formatCampaignDateRange,\n getTradingVolume,\n getTotalPrizePool,\n getTicketPrizePool,\n formatPrizeAmount,\n} from \"./utils\";\n\nexport const CampaignsContentDesktopUI: FC<{\n campaign: CampaignConfig;\n statistics?: CampaignStatistics;\n onLearnMore: () => void;\n onTradeNow: () => void;\n backgroundSrc?: string;\n classNames?: {\n container?: string;\n title?: string;\n description?: string;\n time?: string;\n topContainer?: string;\n descriptionContainer?: string;\n };\n isMobile?: boolean;\n isParticipated?: boolean;\n shouldShowJoinButton?: boolean;\n joinCampaign?: (data: { campaign_id: string | number }) => Promise<any>;\n isJoining?: boolean;\n joinError?: any;\n canTrade?: boolean;\n}> = ({\n campaign,\n statistics,\n onLearnMore,\n onTradeNow,\n backgroundSrc,\n classNames,\n isMobile,\n shouldShowJoinButton,\n joinCampaign,\n isJoining,\n canTrade,\n}) => {\n const { t } = useTranslation();\n const bgSrc = campaign?.image || backgroundSrc;\n const dateRange = formatCampaignDateRange(\n campaign?.start_time,\n campaign?.end_time,\n );\n // for mobile\n const [tooltipOpen, setTooltipOpen] = useState(false);\n\n const tooltipProps = useMemo(() => {\n if (!isMobile) {\n return {};\n }\n return {\n open: tooltipOpen,\n onOpenChange: setTooltipOpen,\n };\n }, [tooltipOpen, isMobile, setTooltipOpen]);\n\n // Get campaign data using utility functions\n const tradingVolume = getTradingVolume(statistics);\n const totalPrizePool = getTotalPrizePool(campaign);\n const ticketPrizePool = getTicketPrizePool(campaign);\n\n const showTradeButton = useMemo(() => {\n return (\n !shouldShowJoinButton && new Date().toISOString() < campaign.end_time\n );\n }, [shouldShowJoinButton, campaign.end_time]);\n\n const isCampaignStarted = useMemo(() => {\n return campaign.start_time < new Date().toISOString();\n }, [campaign]);\n\n const highlightPool = useMemo(() => {\n if (!campaign?.highlight_pool_id) {\n return null;\n }\n return campaign?.prize_pools?.find(\n (pool) => pool.pool_id === campaign.highlight_pool_id,\n );\n }, [campaign]);\n\n const tooltipContent = useMemo(() => {\n if (!campaign?.prize_pools) {\n return null;\n }\n\n return (\n <div className=\"oui-flex oui-min-w-[240px] oui-flex-col oui-gap-1\">\n {campaign?.prize_pools?.map((pool) => {\n return (\n <div\n key={pool.pool_id}\n className=\"oui-flex oui-h-[18px] oui-items-center oui-justify-between\"\n >\n <Text\n size=\"2xs\"\n weight=\"semibold\"\n className=\"oui-text-base-contrast-54\"\n >\n {pool.label}\n </Text>\n <div className=\"oui-flex oui-items-center oui-gap-1\">\n <Text.numeral\n dp={2}\n size=\"2xs\"\n weight=\"semibold\"\n className=\"oui-text-base-contrast\"\n >\n {pool.total_prize}\n </Text.numeral>\n <Text\n size=\"2xs\"\n weight=\"semibold\"\n className=\"oui-text-base-contrast\"\n >\n {pool.currency}\n </Text>\n </div>\n </div>\n );\n })}\n </div>\n );\n }, [campaign]);\n\n return (\n <div\n className={cn([\n \"oui-flex oui-h-[500px] oui-w-full oui-flex-col oui-items-center oui-justify-center oui-gap-10\",\n `oui-bg-cover oui-bg-center oui-bg-no-repeat`,\n classNames?.container,\n ])}\n style={{\n backgroundImage: `linear-gradient(180deg, rgba(var(--oui-color-base-10) / 1) 0%, rgba(var(--oui-color-base-10) / 0.8) 15%, rgba(var(--oui-color-base-10) / 0.4) 40%, rgba(var(--oui-color-base-10) / 0.4) 60%, rgba(var(--oui-color-base-10) / 0.8) 85%, rgba(var(--oui-color-base-10) / 1) 100%), url(${bgSrc})`,\n }}\n >\n <div\n className={cn([\n \"oui-flex oui-flex-col oui-items-center oui-justify-center oui-gap-[10px]\",\n classNames?.topContainer,\n ])}\n >\n <Text\n size=\"sm\"\n weight=\"semibold\"\n className={cn([\"oui-text-base-contrast-54\", classNames?.time])}\n >\n {dateRange}\n </Text>\n <Text\n className={cn([\n \"oui-trading-leaderboard-title oui-text-center oui-text-[48px] oui-font-bold oui-leading-[56px] oui-text-base-contrast\",\n classNames?.title,\n ])}\n >\n {campaign.title}\n </Text>\n <div\n className={cn([\n \"oui-w-[342px] oui-text-center\",\n classNames?.descriptionContainer,\n ])}\n >\n <Text\n size=\"sm\"\n weight=\"semibold\"\n className={cn([\n \"oui-text-base-contrast-54\",\n classNames?.description,\n ])}\n >\n {campaign.description}\n </Text>\n </div>\n </div>\n <div className=\"oui-overflow-hidden oui-rounded-2xl oui-border oui-border-solid oui-border-base-contrast/[0.08]\">\n <div\n className={cn([\n \"oui-flex oui-items-center oui-gap-4 oui-px-4 oui-py-3 oui-backdrop-blur-[10px]\",\n isCampaignStarted ? \"\" : \"oui-hidden\",\n ])}\n >\n <div className=\"oui-flex oui-items-center oui-gap-1\">\n <Text\n size=\"2xs\"\n weight=\"semibold\"\n className=\"oui-text-base-contrast-54\"\n >\n {campaign?.user_account_label ||\n t(\"tradingLeaderboard.participants\")}\n </Text>\n <Text\n size=\"2xs\"\n weight=\"semibold\"\n className=\"oui-text-base-contrast-80\"\n >\n {statistics?.total_participants}\n </Text>\n </div>\n <div className=\"oui-flex oui-items-center oui-gap-1\">\n <Text\n size=\"2xs\"\n weight=\"semibold\"\n className=\"oui-text-base-contrast-54\"\n >\n {t(\"tradingLeaderboard.tradingVolume\")}\n </Text>\n <Text.numeral\n dp={2}\n currency=\"$\"\n size=\"2xs\"\n weight=\"semibold\"\n className=\"oui-text-base-contrast-80\"\n >\n {tradingVolume}\n </Text.numeral>\n </div>\n </div>\n <div\n className={cn([\n \"oui-rounded-2xl oui-border oui-border-solid oui-border-base-contrast/[0.08] oui-bg-primary/[0.08] oui-p-4 oui-backdrop-blur-[10px]\",\n \"oui-flex oui-flex-col oui-gap-4\",\n isCampaignStarted ? \"\" : \"oui-border-transparent\",\n ])}\n >\n <div className=\"oui-flex oui-items-center oui-gap-6\">\n <div className=\"oui-flex oui-flex-col\">\n <div className=\"oui-flex oui-items-center oui-gap-1\">\n <Text\n size={isMobile ? \"2xs\" : \"xs\"}\n weight=\"semibold\"\n className=\"oui-text-base-contrast-54\"\n >\n {/* {t(\"tradingLeaderboard.prizePool\")} */}\n {\"Total prize pool\"}\n </Text>\n <Tooltip\n // @ts-ignore\n content={tooltipContent}\n {...tooltipProps}\n className=\"oui-max-w-[260px] oui-bg-base-5 oui-px-2 oui-py-1\"\n >\n <div\n className=\"oui-flex oui-size-4 oui-items-center oui-justify-center\"\n onClick={() => setTooltipOpen(true)}\n >\n <InfoCircleIcon className=\"oui-cursor-pointer\" />\n </div>\n </Tooltip>\n </div>\n <div>\n <Text.gradient\n weight=\"bold\"\n color=\"brand\"\n className={cn([\n \"oui-trading-leaderboard-title\",\n isMobile\n ? \"oui-text-[20px] oui-leading-[24px]\"\n : \"oui-text-[24px] oui-leading-[28px]\",\n ])}\n >\n {totalPrizePool\n ? formatPrizeAmount(\n totalPrizePool.amount,\n totalPrizePool.currency,\n )\n : \"0 USDC\"}\n </Text.gradient>\n </div>\n </div>\n {(ticketPrizePool || highlightPool) && (\n <div className=\"oui-flex oui-flex-col\">\n <div className=\"oui-flex oui-items-center oui-gap-1\">\n <Text\n size={isMobile ? \"2xs\" : \"xs\"}\n weight=\"semibold\"\n className=\"oui-text-base-contrast-54\"\n >\n {/* {t(\"tradingLeaderboard.ticketPrizePool\")} */}\n {highlightPool?.label || \"Raffle prize\"}\n </Text>\n </div>\n <div>\n <Text.gradient\n weight=\"bold\"\n color=\"brand\"\n className={cn([\n \"oui-trading-leaderboard-title\",\n isMobile\n ? \"oui-text-[20px] oui-leading-[24px]\"\n : \"oui-text-[24px] oui-leading-[28px]\",\n ])}\n >\n {formatPrizeAmount(\n ticketPrizePool?.amount ||\n highlightPool?.total_prize ||\n 0,\n ticketPrizePool?.currency ||\n highlightPool?.currency ||\n \"USDC\",\n )}\n </Text.gradient>\n </div>\n </div>\n )}\n </div>\n {isMobile && campaign?.rule_url && (\n <div\n className=\"-oui-mb-1 -oui-mt-2 oui-flex oui-items-center oui-gap-0.5 oui-text-2xs oui-leading-[15px] oui-text-base-contrast-36\"\n onClick={onLearnMore}\n >\n {t(\"tradingLeaderboard.viewRules\")}\n <ChevronRightIcon\n size={16}\n className=\"oui-text-base-contrast-36\"\n />\n </div>\n )}\n <div\n className={cn([\n \"oui-flex oui-gap-4\",\n campaign?.rule_url || canTrade ? \"\" : \"oui-hidden\",\n ])}\n >\n {!isMobile && campaign?.rule_url && (\n <Button\n size=\"md\"\n variant=\"outlined\"\n className=\"oui-flex-1 \n oui-border-[rgb(var(--oui-gradient-brand-start))] \n oui-text-[rgb(var(--oui-gradient-brand-start))] \n hover:oui-bg-[rgb(var(--oui-gradient-brand-start))]/[0.08]\n active:oui-bg-[rgb(var(--oui-gradient-brand-start))]/[0.08]\n \"\n onClick={onLearnMore}\n >\n {t(\"tradingLeaderboard.viewRules\")}\n </Button>\n )}\n <AuthGuard\n buttonProps={{\n size: isMobile ? \"sm\" : \"md\",\n className: \"oui-px-5\",\n }}\n >\n {shouldShowJoinButton && (\n <Button\n size={isMobile ? \"sm\" : \"md\"}\n variant=\"gradient\"\n color=\"primary\"\n className=\"oui-flex-1\"\n loading={isJoining}\n disabled={isJoining}\n onClick={async () => {\n try {\n await joinCampaign?.({\n campaign_id: Number(campaign.campaign_id),\n });\n } catch (error) {\n console.error(\"Failed to join campaign:\", error);\n }\n }}\n >\n {t(\"tradingLeaderboard.joinNow\")}\n </Button>\n )}\n {showTradeButton && (\n <Button\n size={isMobile ? \"sm\" : \"md\"}\n variant=\"gradient\"\n color=\"primary\"\n className=\"oui-flex-1\"\n onClick={onTradeNow}\n >\n {campaign?.trading_config?.format ||\n t(\"tradingLeaderboard.tradeNow\")}\n </Button>\n )}\n </AuthGuard>\n </div>\n </div>\n </div>\n </div>\n );\n};\n","import { format } from \"date-fns\";\nimport { i18n } from \"@orderly.network/i18n\";\nimport { TimelinePoint } from \"./components/axis\";\nimport { CampaignConfig, CampaignTagEnum, CampaignStatistics } from \"./type\";\n\n// Default timezone display for campaigns\nconst DEFAULT_TIMEZONE_DISPLAY = \"UTC\";\n\n/**\n * Get user's current timezone display name\n * @returns Display name for the user's timezone (e.g., 'UTC', 'EST', 'PST')\n */\nexport const getUserTimezoneDisplay = (): string => {\n try {\n const date = new Date();\n const timeString = date.toLocaleTimeString(\"en-US\", {\n timeZoneName: \"short\",\n });\n const shortName = timeString.split(\" \").pop();\n return shortName || DEFAULT_TIMEZONE_DISPLAY;\n } catch (error) {\n console.warn(\"Failed to detect user timezone, using default:\", error);\n return DEFAULT_TIMEZONE_DISPLAY;\n }\n};\n\n/**\n * Get the appropriate tag for a campaign based on its configuration and current conditions\n * @param campaign Campaign configuration object\n * @param userReferralCode User's referral code (optional)\n * @returns CampaignTagEnum representing the current status of the campaign\n */\nexport const getCampaignTag = (\n campaign: CampaignConfig,\n userReferralCode?: string,\n): CampaignTagEnum => {\n const currentTime = new Date();\n const startTime = new Date(campaign.start_time);\n const endTime = new Date(campaign.end_time);\n\n // For non-exclusive campaigns, check time-based status\n if (currentTime < startTime) {\n return CampaignTagEnum.COMING;\n } else if (currentTime > endTime) {\n return CampaignTagEnum.ENDED;\n } else {\n if (campaign.referral_codes && campaign.referral_codes.length > 0) {\n if (\n !userReferralCode ||\n !campaign.referral_codes.includes(userReferralCode)\n ) {\n return CampaignTagEnum.EXCLUSIVE;\n }\n }\n return CampaignTagEnum.ONGOING;\n }\n};\n\n/**\n * Check if a campaign is visible to the current user\n * @param campaign Campaign configuration object\n * @param userReferralCode User's referral code (optional)\n * @returns boolean indicating if the campaign should be displayed\n */\nexport const isCampaignVisible = (\n campaign: CampaignConfig,\n userReferralCode?: string,\n): boolean => {\n // If campaign has referral code restrictions\n if (campaign.referral_codes && campaign.referral_codes.length > 0) {\n // Only show if user has a valid referral code\n return (\n !!userReferralCode && campaign.referral_codes.includes(userReferralCode)\n );\n }\n\n // For non-exclusive campaigns, always visible\n return true;\n};\n\n/**\n * Format campaign date range to display format like \"Feb 28, 2025 - March 2, 2025 PST\"\n * @param startTime Start time string or timestamp (should be UTC)\n * @param endTime End time string or timestamp (should be UTC)\n * @param showTimezone Whether to show timezone suffix (defaults to true)\n * @returns Formatted date range string with user's timezone\n */\nexport const formatCampaignDateRange = (\n startTime: string | number | Date,\n endTime: string | number | Date,\n showTimezone: boolean = true,\n): string => {\n try {\n // Convert to Date objects - JavaScript automatically handles UTC conversion to local time\n const startDate = new Date(startTime);\n const endDate = new Date(endTime);\n\n // Check if dates are valid\n if (isNaN(startDate.getTime()) || isNaN(endDate.getTime())) {\n console.warn(\"Invalid date value provided to formatCampaignDateRange:\", {\n startTime,\n endTime,\n });\n return \"Invalid date range\";\n }\n\n // Format dates using date-fns (will display in user's local timezone)\n // MMM d, yyyy format gives us \"Feb 28, 2025\" style\n const startFormatted = format(startDate, \"MMM d, yyyy\");\n const endFormatted = format(endDate, \"MMM d, yyyy\");\n\n const dateRange = `${startFormatted} - ${endFormatted}`;\n\n if (!showTimezone) {\n return dateRange;\n }\n\n // Add user's timezone suffix\n const timezoneDisplay = getUserTimezoneDisplay();\n return `${dateRange} ${timezoneDisplay}`;\n } catch (error) {\n console.error(\"Error formatting campaign date range:\", error, {\n startTime,\n endTime,\n });\n return \"Date formatting error\";\n }\n};\n\n/**\n * Get total participants count from campaign statistics\n * @param statistics Campaign statistics data from API\n * @returns Formatted participants count\n */\nexport const getParticipantsCount = (\n statistics?: CampaignStatistics,\n): number => {\n return statistics?.total_participants || 0;\n};\n\n/**\n * Get total trading volume from campaign statistics\n * @param statistics Campaign statistics data from API\n * @returns Total trading volume amount\n */\nexport const getTradingVolume = (statistics?: CampaignStatistics): number => {\n return statistics?.total_volume || 0;\n};\n\n/**\n * Calculate total prize pool amount from campaign configuration\n * @param campaign Campaign configuration object\n * @returns Object with total amount and currency, or null if no prize pools\n */\nexport const getTotalPrizePool = (\n campaign?: CampaignConfig,\n): { amount: number; currency: string } | null => {\n if (!campaign?.prize_pools || campaign.prize_pools.length === 0) {\n return null;\n }\n\n // Group by currency and sum up the amounts\n const currencyTotals: Record<string, number> = {};\n\n campaign.prize_pools.forEach((pool) => {\n currencyTotals[pool.currency] =\n (currencyTotals[pool.currency] || 0) + pool.total_prize;\n });\n\n // For now, return the first currency found (typically USDC)\n // In the future, we might want to handle multiple currencies differently\n const currencies = Object.keys(currencyTotals);\n if (currencies.length === 0) return null;\n\n const mainCurrency = currencies[0];\n return {\n amount: currencyTotals[mainCurrency],\n currency: mainCurrency,\n };\n};\n\n/**\n * Get ticket prize pool amount from campaign configuration\n * @param campaign Campaign configuration object\n * @returns Object with amount and currency, or null if no ticket rules\n */\nexport const getTicketPrizePool = (\n campaign?: CampaignConfig,\n): { amount: number; currency: string } | null => {\n if (!campaign?.ticket_rules) {\n return null;\n }\n\n return {\n amount: campaign.ticket_rules.total_prize,\n currency: campaign.ticket_rules.currency,\n };\n};\n\n/**\n * Format prize amount for display\n * @param amount Prize amount\n * @param currency Currency symbol\n * @returns Formatted string like \"15,000 USDC\"\n */\nexport const formatPrizeAmount = (amount: number, currency: string): string => {\n return `${amount.toLocaleString()} ${currency}`;\n};\n\n/**\n * Format trading volume for display with currency symbol\n * @param volume Trading volume amount\n * @returns Formatted string with $ prefix\n */\nexport const formatTradingVolume = (volume: number): string => {\n if (volume >= 1_000_000) {\n return `$${(volume / 1_000_000).toFixed(1)}M`;\n } else if (volume >= 1_000) {\n return `$${(volume / 1_000).toFixed(1)}K`;\n } else {\n return `$${volume.toFixed(0)}`;\n }\n};\n\n/**\n * Format participants count for display\n * @param count Participants count\n * @returns Formatted string with proper formatting\n */\nexport const formatParticipantsCount = (count: number): string => {\n if (count >= 1_000_000) {\n return `${(count / 1_000_000).toFixed(1)}M`;\n } else if (count >= 1_000) {\n return `${(count / 1_000).toFixed(1)}K`;\n } else {\n return count.toLocaleString();\n }\n};\n\n/**\n * Generate timeline data points for campaign visualization\n * @param campaign Campaign configuration object\n * @returns Array of TimelinePoint objects (max 4 points) in user's local timezone\n */\nexport const generateCampaignTimeline = (\n campaign: CampaignConfig,\n): TimelinePoint[] => {\n const currentTime = new Date();\n const startTime = new Date(campaign.start_time);\n const endTime = new Date(campaign.end_time);\n const rewardTime = campaign.reward_distribution_time\n ? new Date(campaign.reward_distribution_time)\n : null;\n\n const timeline: TimelinePoint[] = [];\n\n // Helper function to determine point type based on time\n const getTimelineType = (\n time: Date,\n isNow: boolean = false,\n ): \"past\" | \"active\" | \"future\" => {\n if (isNow) return \"active\";\n return currentTime >= time ? \"past\" : \"future\";\n };\n\n // Helper function to format time for display in user's local timezone\n const formatTimeDisplay = (time: Date): string => {\n try {\n // Format time using date-fns (displays in user's local timezone)\n const formatted = format(time, \"yyyy-MM-dd HH:mm\");\n const timezoneDisplay = getUserTimezoneDisplay();\n return `${formatted} ${timezoneDisplay}`;\n } catch (error) {\n console.error(\"Error formatting time:\", error);\n return time.toISOString();\n }\n };\n\n // Battle starts point\n timeline.push({\n title: i18n.t(\"tradingLeaderboard.battleStarts\"),\n type: getTimelineType(startTime),\n time: formatTimeDisplay(startTime),\n });\n\n // Add \"Now\" point if battle is ongoing\n const isOngoing = currentTime >= startTime && currentTime <= endTime;\n if (isOngoing) {\n timeline.push({\n title: i18n.t(\"chart.now\"),\n type: \"active\",\n time: formatTimeDisplay(currentTime),\n });\n }\n\n // Battle ends point\n timeline.push({\n title: i18n.t(\"tradingLeaderboard.battleEnds\"),\n type: getTimelineType(endTime),\n time: formatTimeDisplay(endTime),\n });\n\n // Reward distribution point (if provided)\n if (rewardTime) {\n timeline.push({\n title: i18n.t(\"tradingLeaderboard.rewardDistribution\"),\n type: getTimelineType(rewardTime),\n time: formatTimeDisplay(rewardTime),\n });\n }\n\n // Ensure we don't exceed 4 points\n return timeline.slice(0, 4);\n};\n","import { RankingColumnFields } from \"../ranking/shared/column\";\nimport { DescriptionConfig, DescriptionItem } from \"../rule/description\";\n\nexport enum CampaignTagEnum {\n ONGOING = \"ongoing\",\n COMING = \"coming\",\n ENDED = \"ended\",\n EXCLUSIVE = \"exclusive\",\n}\n\n// Campaign statistics data structure (from campaign statistics API)\nexport interface CampaignStatistics {\n total_participants?: number;\n total_volume?: number;\n}\n\n// Campaign prize pool configuration types\nexport interface PrizePoolTier {\n position?: number;\n position_range?: [number, number];\n amount: number;\n}\n\nexport interface PrizePool {\n pool_id: string;\n label: string;\n total_prize: number;\n currency: string;\n metric: \"volume\" | \"pnl\";\n tiers: PrizePoolTier[];\n}\n\n// Ticket prize configuration types\nexport interface TicketTierRule {\n value: number;\n tickets: number;\n}\n\nexport interface TicketLinearRule {\n every: number;\n tickets: number;\n}\n\nexport interface TicketRules {\n total_prize: number;\n currency: string;\n metric: \"volume\" | \"pnl\";\n mode: \"tiered\" | \"linear\";\n tiers?: TicketTierRule[];\n linear?: TicketLinearRule;\n}\n\n// Campaign configuration\nexport interface CampaignConfig {\n campaign_id: number | string;\n title: string;\n description: string;\n start_time: string;\n end_time: string;\n reward_distribution_time?: string;\n volume_scope?: string | string[];\n referral_codes?: string[] | string;\n prize_pools?: PrizePool[];\n ticket_rules?: TicketRules;\n image?: string;\n rule_url?: string;\n rule_config?: {\n action?: \"scroll\" | \"click\";\n };\n trading_url?: string;\n trading_config?: {\n format?: string;\n };\n href?: string;\n hide_arena?: boolean;\n hide_rewards?: boolean;\n hide_estimated_rewards?: boolean;\n highlight_pool_id?: string;\n user_account_label?: string;\n rule?: {\n rule: DescriptionItem[];\n terms: DescriptionItem[];\n ruleConfig?: DescriptionConfig;\n };\n exclude_leaderboard_columns?: RankingColumnFields[];\n}\n\n// User data for calculations\nexport interface UserData {\n rank?: number | string;\n pnl: number;\n total_participants?: number;\n volume: number;\n referral_code?: string;\n}\n\nexport type CampaignStatsDetailsResponse = {\n broker_id: string;\n user_count: number;\n volume: number;\n symbol: string;\n}[];\n\nexport type CampaignStatsResponse = {\n sign_up_count: number;\n user_count: number;\n volume: number;\n updated_time: number;\n};\n\nexport type UserCampaignsResponse = {\n id: string;\n register_time: number;\n}[];\n","import { useMemo, useCallback } from \"react\";\nimport {\n useQuery,\n useConfig,\n useMutation,\n useAccount,\n} from \"@orderly.network/hooks\";\nimport { AccountStatusEnum } from \"@orderly.network/types\";\nimport { toast } from \"@orderly.network/ui\";\nimport { useTradingLeaderboardContext } from \"../provider\";\nimport { CampaignStatsResponse, UserCampaignsResponse } from \"./type\";\n\n/**\n * Hook for managing campaigns data and statistics\n * TODO: Replace mock data with real API calls when backend is ready\n */\nexport const useCampaignsScript = () => {\n const {\n campaigns = [],\n currentCampaignId,\n onCampaignChange,\n currentCampaign,\n userData,\n backgroundSrc,\n } = useTradingLeaderboardContext();\n\n const symbols = Array.isArray(currentCampaign?.volume_scope)\n ? currentCampaign?.volume_scope.join(\",\")\n : currentCampaign?.volume_scope;\n\n const brokerId = useConfig(\"brokerId\");\n\n const isCampaignEnded = useMemo(() => {\n return (\n currentCampaign?.end_time &&\n currentCampaign?.end_time < new Date().toISOString()\n );\n }, [currentCampaign]);\n\n const searchParams = useMemo(() => {\n return {\n campaign_id: currentCampaignId.toString(),\n symbols: symbols || \"\",\n broker_id: brokerId,\n group_by: \"BROKER\",\n };\n }, [currentCampaignId, symbols, brokerId]);\n\n const { data: stats } = useQuery<CampaignStatsResponse>(\n currentCampaignId !== \"general\"\n ? `https://api.orderly.org/v1/public/campaign/stats?${new URLSearchParams(searchParams).toString()}`\n : null,\n { revalidateOnFocus: false },\n );\n\n const { state } = useAccount();\n\n const { data: userCampaigns, mutate: refreshUserCampaigns } =\n useQuery<UserCampaignsResponse>(\n currentCampaignId !== \"general\" && state.address\n ? `https://api.orderly.org/v1/public/campaigns?address=${state.address}`\n : null,\n { revalidateOnFocus: false },\n );\n\n const isParticipated = useMemo(() => {\n const target = userCampaigns?.find((item) => item.id == currentCampaignId);\n return !!target;\n }, [userCampaigns, currentCampaignId]);\n\n const shouldShowJoinButton = useMemo(() => {\n // return false;\n return !!state.address && !isCampaignEnded && !isParticipated;\n }, [state.address, isCampaignEnded, isParticipated]);\n\n const [doJoinCampaign, { isMutating: isJoining, error: joinError }] =\n useMutation(`/v1/client/campaign/sign_up`, \"POST\");\n\n const joinCampaign = useCallback(\n async (data: { campaign_id: string | number }) => {\n try {\n if (state.status < AccountStatusEnum.EnableTrading) {\n toast.error(\"Please enable trading to proceed.\");\n return;\n }\n // console.log(\"data\", data);\n const result = await doJoinCampaign(data);\n // console.log(\"result\", result);\n\n if (result?.success !== false) {\n // Refresh user campaigns data to update participation status\n await refreshUserCampaigns();\n toast.success(result?.message || \"Campaign joined successfully\");\n return result;\n } else {\n toast.error(result?.message || \"Failed to join campaign\");\n }\n } catch (error) {\n console.error(\"Failed to join campaign:\", error);\n throw error;\n }\n },\n [doJoinCampaign, refreshUserCampaigns, state.status],\n );\n\n const statistics = {\n total_participants: stats?.user_count,\n total_volume: stats?.volume,\n };\n\n const onLearnMore = () => {\n if (currentCampaign?.rule_url) {\n if (currentCampaign.rule_config?.action === \"scroll\") {\n document\n .getElementById(currentCampaign.rule_url)\n ?.scrollIntoView({ behavior: \"smooth\" });\n } else {\n window.open(currentCampaign.rule_url, \"_blank\");\n }\n }\n };\n\n const onTradeNow = () => {\n if (currentCampaign?.trading_url) {\n window.open(currentCampaign.trading_url, \"_self\");\n }\n };\n\n const canTrade = useMemo(() => {\n if (!currentCampaign) return false;\n return (\n currentCampaign?.start_time < new Date().toISOString() &&\n currentCampaign?.end_time > new Date().toISOString() &&\n state.status >= AccountStatusEnum.EnableTrading\n );\n }, [currentCampaign, state.status]);\n\n return {\n campaigns,\n currentCampaignId,\n currentCampaign,\n onCampaignChange,\n statistics,\n userData,\n onLearnMore,\n onTradeNow,\n backgroundSrc,\n joinCampaign,\n isJoining,\n isParticipated,\n shouldShowJoinButton,\n joinError,\n canTrade,\n };\n};\n","import { FC } from \"react\";\nimport { cn } from \"@orderly.network/ui\";\nimport { CampaignConfig } from \"../type\";\nimport { generateCampaignTimeline } from \"../utils\";\nimport { CampaignsAxis, CampaignsAxisMobile } from \"./axis\";\nimport { CampaignsCountdown } from \"./countdown\";\n\nexport const CampaignsTimeDesktopUI: FC<{\n campaign: CampaignConfig;\n isMobile?: boolean;\n}> = ({ campaign, isMobile }) => {\n const timelineData = generateCampaignTimeline(campaign);\n\n return (\n <div\n className={cn([\n \"oui-max-w-[992px] oui-mx-auto oui-flex oui-flex-col oui-items-center\",\n isMobile ? \"oui-pt-4 oui-gap-10 oui-pb-10\" : \"oui-py-10 oui-gap-4\",\n ])}\n >\n <CampaignsCountdown campaign={campaign} isMobile={isMobile} />\n {isMobile ? (\n <CampaignsAxisMobile points={timelineData} />\n ) : (\n <CampaignsAxis points={timelineData} />\n )}\n </div>\n );\n};\n","import { FC } from \"react\";\nimport { cn } from \"@orderly.network/ui\";\n\nexport interface TimelinePoint {\n title: string;\n type: \"past\" | \"active\" | \"future\";\n time: string;\n}\n\nexport interface CampaignsAxisProps {\n points: TimelinePoint[];\n}\n\nexport const CampaignsAxis: FC<CampaignsAxisProps> = ({ points }) => {\n if (!points || points.length === 0) {\n return null;\n }\n\n // Find the index of the active point\n const activeIndex = points.findIndex((point) => point.type === \"active\");\n\n // For single point, center it without any lines\n if (points.length === 1) {\n return (\n <div className=\"oui-flex oui-w-full oui-justify-center\">\n <div className=\"oui-flex oui-flex-col oui-items-center\">\n <AxisPoint type={points[0].type} />\n <div className=\"oui-mt-4 oui-flex oui-flex-col oui-items-center oui-text-center\">\n <div className=\"oui-trading-leaderboard-title oui-mb-1 oui-whitespace-nowrap oui-text-sm oui-font-medium oui-text-base-contrast-54\">\n {points[0].title}\n </div>\n <div className=\"oui-whitespace-nowrap oui-text-xs oui-text-base-contrast-36\">\n {points[0].time}\n </div>\n </div>\n </div>\n </div>\n );\n }\n\n // Helper function to determine line background class\n const getLineBackgroundClass = (segmentIndex: number): string => {\n // If there's an active point and this segment is to the left of it, use oui-bg-base-3\n if (activeIndex !== -1 && segmentIndex < activeIndex) {\n return \"oui-bg-base-3\";\n }\n // Otherwise use regular color\n return \"oui-bg-base-8\";\n };\n\n const widthPercentage = points?.length > 3 ? \"110%\" : \"120%\";\n\n return (\n <div className=\"oui-flex oui-w-full\" style={{ width: widthPercentage }}>\n {points.map((point, index) => {\n const isFirst = index === 0;\n const isLast = index === points.length - 1;\n\n return (\n <div\n key={index}\n className=\"oui-relative oui-flex oui-flex-1 oui-flex-col oui-items-center\"\n >\n {/* Point container with connecting lines */}\n <div className=\"oui-relative oui-flex oui-w-full oui-items-center\">\n {/* Left line - always occupy space, but invisible for first point */}\n <div\n className={cn([\n \"oui-h-[6px] oui-flex-1\",\n !isFirst && getLineBackgroundClass(index - 1),\n ])}\n />\n\n {/* Point */}\n <div className=\"oui-z-10 oui-shrink-0\">\n <AxisPoint type={point.type} />\n </div>\n\n {/* Right line - always occupy space, but invisible for last point */}\n <div\n className={cn([\n \"oui-h-[6px] oui-flex-1\",\n !isLast && getLineBackgroundClass(index),\n ])}\n />\n </div>\n\n {/* Label below point */}\n <div className=\"oui-mt-4 oui-flex oui-flex-col oui-items-center oui-text-center\">\n <div className=\"oui-trading-leaderboard-title oui-mb-1 oui-whitespace-nowrap oui-text-sm oui-font-medium oui-text-base-contrast-54\">\n {point.title}\n </div>\n <div className=\"oui-whitespace-nowrap oui-text-xs oui-text-base-contrast-36\">\n {point.type !== \"active\" && point.time}\n </div>\n </div>\n </div>\n );\n })}\n </div>\n );\n};\n\nexport const CampaignsAxisMobile: FC<CampaignsAxisProps> = ({ points }) => {\n if (!points || points.length === 0) {\n return null;\n }\n\n // Find the index of the active point\n const activeIndex = points.findIndex((point) => point.type === \"active\");\n\n // Helper function to determine line background class\n const getLineBackgroundClass = (segmentIndex: number): string => {\n // If there's an active point and this segment is above it, use oui-bg-base-3\n if (activeIndex !== -1 && segmentIndex < activeIndex) {\n return \"oui-bg-base-3\";\n }\n // Otherwise use regular color\n return \"oui-bg-base-8\";\n };\n\n return (\n <div className=\"oui-flex oui-w-full oui-flex-col oui-items-center oui-gap-10\">\n {points.map((point, index) => {\n const isFirst = index === 0;\n const isLast = index === points.length - 1;\n\n return (\n <div key={index} className={cn([\"oui-relative\"])}>\n {/* Main content container */}\n <div className=\"oui-flex oui-h-10 oui-items-start oui-gap-4\">\n {/* Point with connecting line */}\n <div\n className={cn([\n \"oui-relative oui-flex oui-flex-col oui-items-center\",\n isFirst && \"oui-translate-y-[10px]\",\n ])}\n >\n <AxisPoint type={point.type} />\n\n {/* Vertical connecting line - only show if not the last point */}\n {!isLast && (\n <div\n className={cn([\n \"oui-h-[64px] oui-w-[6px]\",\n getLineBackgroundClass(index),\n ])}\n />\n )}\n </div>\n\n {/* Text content */}\n <div className=\"oui-flex oui-flex-col oui-justify-start\">\n <div className=\"oui-trading-leaderboard-title oui-mb-1 oui-text-sm oui-font-medium oui-text-base-contrast-54\">\n {point.title}\n </div>\n <div className=\"oui-min-w-[160px] oui-text-xs oui-text-base-contrast-36\">\n {point.type !== \"active\" && point.time}\n </div>\n </div>\n </div>\n </div>\n );\n })}\n </div>\n );\n};\n\nconst AxisPoint: FC<{ type: \"past\" | \"active\" | \"future\" }> = ({ type }) => {\n return (\n <div\n className={cn([\n \"oui-size-5 oui-shrink-0 oui-rounded-full\",\n type === \"past\" && \"oui-bg-base-contrast-80\",\n type === \"active\" &&\n \"oui-bg-gradient-to-r oui-from-[rgba(var(--oui-gradient-brand-start))] oui-to-[rgba(var(--oui-gradient-brand-end))]\",\n type === \"future\" &&\n \"oui-border-[2.5px] oui-border-solid oui-border-base-contrast-80 oui-bg-[#07080A]\",\n ])}\n />\n );\n};\n","import { FC, useState, useEffect } from \"react\";\nimport { useTranslation } from \"@orderly.network/i18n\";\nimport { cn } from \"@orderly.network/ui\";\nimport { CampaignConfig } from \"../type\";\n\nconst Circle = () => (\n <div className=\"oui-w-1 oui-h-1 oui-rounded-full oui-bg-white/[0.16]\" />\n);\n\ninterface TimeLeft {\n days: number;\n hours: number;\n minutes: number;\n seconds: number;\n}\n\ninterface TimeUnitProps {\n value: number;\n label: string;\n isMobile?: boolean;\n}\n\nconst TimeUnit: FC<TimeUnitProps> = ({ value, label, isMobile }) => (\n <div\n className={cn([\n \"oui-flex oui-flex-col oui-items-center oui-gap-1\",\n isMobile ? \"oui-w-[45px]\" : \"oui-w-[63px]\",\n ])}\n >\n <div\n className={cn([\n \"oui-trading-leaderboard-title oui-text-base-contrast oui-font-medium\",\n isMobile\n ? \"oui-text-[20px] oui-leading-[24px] oui-h-[24px]\"\n : \"oui-text-[36px] oui-leading-[44px] oui-h-[44px]\",\n ])}\n >\n {value.toString().padStart(2, \"0\")}\n </div>\n <div\n className={cn([\n \"oui-trading-leaderboard-title oui-text-base-contrast-80 oui-font-medium\",\n isMobile\n ? \"oui-text-[10px] oui-leading-[14px] oui-h-[14px]\"\n : \"oui-text-sm oui-leading-[20px] oui-h-[20px]\",\n ])}\n >\n {label}\n </div>\n </div>\n);\n\nexport const CampaignsCountdown: FC<{\n campaign: CampaignConfig;\n isMobile?: boolean;\n}> = ({ campaign, isMobile }) => {\n const { t } = useTranslation();\n const [timeLeft, setTimeLeft] = useState<TimeLeft>({\n days: 0,\n hours: 0,\n minutes: 0,\n seconds: 0,\n });\n const [isStarted, setIsStarted] = useState(false);\n\n useEffect(() => {\n const calculateTimeLeft = () => {\n const currentTime = new Date().getTime();\n const startTime = new Date(campaign.start_time).getTime();\n const endTime = new Date(campaign.end_time).getTime();\n\n // Determine if campaign has started\n const hasStarted = currentTime >= startTime;\n setIsStarted(hasStarted);\n\n // Calculate time difference based on campaign status\n const targetTime = hasStarted ? endTime : startTime;\n const difference = targetTime - currentTime;\n\n if (difference > 0) {\n const days = Math.floor(difference / (1000 * 60 * 60 * 24));\n const hours = Math.floor(\n (difference % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60),\n );\n const minutes = Math.floor(\n (difference % (1000 * 60 * 60)) / (1000 * 60),\n );\n const seconds = Math.floor((difference % (1000 * 60)) / 1000);\n\n setTimeLeft({ days, hours, minutes, seconds });\n } else {\n setTimeLeft({ days: 0, hours: 0, minutes: 0, seconds: 0 });\n }\n };\n\n // Calculate immediately\n calculateTimeLeft();\n\n // Set up interval to update every second\n const timer = setInterval(calculateTimeLeft, 1000);\n\n // Cleanup interval on component unmount\n return () => clearInterval(timer);\n }, [campaign.start_time, campaign.end_time]);\n\n // Check if campaign has ended\n const currentTime = new Date();\n const endTime = new Date(campaign.end_time);\n\n if (currentTime > endTime) {\n return (\n <div className=\"oui-w-full oui-flex oui-items-center oui-justify-center oui-gap-4\">\n <div\n className=\"oui-max-w-[382px] oui-w-full oui-h-[1px] oui-bg-gradient-to-r oui-from-[rgba(var(--oui-gradient-brand-end)/0)]\n oui-to-[rgba(var(--oui-gradient-brand-start))]\"\n />\n <div\n className={cn([\n \"oui-trading-leaderboard-title oui-flex oui-items-center oui-justify-center oui-font-medium oui-text-base-contrast-54\",\n isMobile\n ? \"oui-text-[14px] oui-leading-[20px] oui-h-[20px] oui-whitespace-nowrap\"\n : \"oui-p-5 oui-text-[18px] oui-leading-[26px] oui-h-[26px]\",\n ])}\n >\n {t(\"tradingLeaderboard.batteleHasEnded\")}\n </div>\n <div\n className=\"oui-max-w-[382px] oui-w-full oui-h-[1px] oui-bg-gradient-to-r oui-from-[rgba(var(--oui-gradient-brand-start))]\n oui-to-[rgba(var(--oui-gradient-brand-end)/0)]\"\n />\n </div>\n );\n }\n\n const titleText = isStarted\n ? t(\"tradingLeaderboard.battleEndsIn\")\n : t(\"tradingLeaderboard.battleStartsIn\");\n\n // Time units configuration\n const timeUnits = [\n { value: timeLeft.days, label: \"Days\" },\n { value: timeLeft.hours, label: \"Hours\" },\n { value: timeLeft.minutes, label: \"Minutes\" },\n { value: timeLeft.seconds, label: \"Seconds\" },\n ];\n\n return (\n <div className=\"oui-w-full oui-flex oui-items-center oui-justify-center oui-gap-4\">\n <div\n className=\"oui-max-w-[298px] oui-w-full oui-h-[1px] oui-bg-gradient-to-r oui-from-[rgba(var(--oui-gradient-brand-end)/0)]\n oui-to-[rgba(var(--oui-gradient-brand-start))]\"\n />\n <div\n className={cn([\n \"oui-flex oui-flex-col oui-items-center\",\n isMobile ? \"oui-p-0 oui-gap-1\" : \"oui-p-5 oui-gap-2\",\n ])}\n >\n <div\n className={cn([\n \"oui-trading-leaderboard-title oui-font-medium oui-text-base-contrast-54\",\n isMobile\n ? \"oui-text-[14px] oui-leading-[20px] oui-h-[20px]\"\n : \"oui-text-[18px] oui-leading-[26px] oui-h-[26px]\",\n ])}\n >\n {titleText}\n </div>\n <div\n className={cn([\n \"oui-flex oui-items-center\",\n isMobile ? \"oui-gap-2\" : \"oui-gap-[10px]\",\n ])}\n >\n {timeUnits.map((unit, index) => (\n <div\n key={unit.label}\n className={cn([\n \"oui-flex oui-items-center\",\n isMobile ? \"oui-gap-2\" : \"oui-gap-[10px]\",\n ])}\n >\n <TimeUnit\n value={unit.value}\n label={unit.label}\n isMobile={isMobile}\n />\n {index < timeUnits.length - 1 && <Circle />}\n </div>\n ))}\n </div>\n </div>\n <div\n className=\"oui-max-w-[298px] oui-w-full oui-h-[1px] oui-bg-gradient-to-r oui-from-[rgba(var(--oui-gradient-brand-start))]\n oui-to-[rgba(var(--oui-gradient-brand-end)/0)]\"\n />\n </div>\n );\n};\n","import { FC, useCallback, useState, useEffect } from \"react\";\nimport useEmblaCarousel from \"embla-carousel-react\";\nimport { ChevronLeftIcon, ChevronRightIcon } from \"@orderly.network/ui\";\nimport { DefaultCampaign } from \"../DefaultCampaign\";\nimport { CampaignItemUI } from \"../campaign.item.ui\";\nimport { CampaignConfig } from \"../type\";\nimport { getCampaignTag } from \"../utils\";\n\nexport const CampaignsHeaderUI: FC<{\n campaigns: CampaignConfig[];\n currentCampaignId: string;\n onCampaignChange: (campaignId: string) => void;\n backgroundSrc?: string;\n}> = ({ campaigns, currentCampaignId, onCampaignChange, backgroundSrc }) => {\n const [isLargeScreen, setIsLargeScreen] = useState(false);\n const [canScrollPrev, setCanScrollPrev] = useState(false);\n const [canScrollNext, setCanScrollNext] = useState(false);\n\n useEffect(() => {\n const checkScreenSize = () => {\n setIsLargeScreen(window.innerWidth >= 1024);\n };\n\n // Check initial size\n checkScreenSize();\n\n // Add event listener\n window.addEventListener(\"resize\", checkScreenSize);\n\n // Cleanup\n return () => window.removeEventListener(\"resize\", checkScreenSize);\n }, []);\n\n const [emblaRef, emblaApi] = useEmblaCarousel({\n loop: false,\n align: \"start\",\n containScroll: \"keepSnaps\",\n slidesToScroll: 1,\n skipSnaps: false,\n dragFree: false,\n });\n\n // Update scroll availability\n const updateScrollAvailability = useCallback(() => {\n if (!emblaApi || !campaigns?.length) return;\n\n setCanScrollPrev(emblaApi.canScrollPrev());\n\n // Check if the last slide is in view\n const slidesInView = emblaApi.slidesInView();\n const lastSlideIndex = campaigns.length - 1;\n const isLastSlideInView = slidesInView.includes(lastSlideIndex);\n\n setCanScrollNext(emblaApi.canScrollNext() && !isLastSlideInView);\n }, [emblaApi, campaigns]);\n\n useEffect(() => {\n if (!emblaApi) return;\n\n // Initial check\n updateScrollAvailability();\n\n // Listen for scroll events\n emblaApi.on(\"select\", updateScrollAvailability);\n emblaApi.on(\"reInit\", updateScrollAvailability);\n emblaApi.on(\"scroll\", updateScrollAvailability);\n\n return () => {\n emblaApi.off(\"select\", updateScrollAvailability);\n emblaApi.off(\"reInit\", updateScrollAvailability);\n emblaApi.off(\"scroll\", updateScrollAvailability);\n };\n }, [emblaApi, updateScrollAvailability]);\n\n const scrollPrev = useCallback(() => {\n if (emblaApi) emblaApi.scrollPrev();\n }, [emblaApi]);\n\n const scrollNext = useCallback(() => {\n if (emblaApi) emblaApi.scrollNext();\n }, [emblaApi]);\n\n // Calculate width considering gap (0.5rem = 8px)\n // For 2 items: (100% - 1 * gap) / 2\n // For 3 items: (100% - 2 * gap) / 3\n const slideStyle = isLargeScreen\n ? { flexBasis: \"calc((100% - 1rem) / 3)\", width: \"calc((100% - 1rem) / 3)\" }\n : {\n flexBasis: \"calc((100% - 0.5rem) / 2)\",\n width: \"calc((100% - 0.5rem) / 2)\",\n };\n\n // Check if scroll buttons should be hidden based on screen size and campaign count\n const shouldHideScrollButtons = isLargeScreen\n ? campaigns.length <= 3\n : campaigns.length <= 2;\n\n return (\n <div className=\"oui-flex oui-gap-2 oui-w-full oui-items-center oui-px-6\">\n <div className=\"oui-flex-shrink-0\">\n <DefaultCampaign\n currentCampaignId={currentCampaignId}\n onCampaignChange={onCampaignChange}\n className=\"oui-min-w-[322px]\"\n />\n </div>\n\n <div className=\"oui-w-[1px] oui-h-[78px] oui-bg-white/[0.16]\" />\n\n <button\n onClick={scrollPrev}\n disabled={!canScrollPrev}\n className={`oui-group oui-flex oui-items-center oui-justify-center oui-shrink-0 oui-w-6 oui-h-[78px] oui-rounded-lg oui-transition-colors hover:oui-bg-base-7 disabled:oui-opacity-30 disabled:oui-cursor-not-allowed disabled:hover:oui-bg-transparent ${shouldHideScrollButtons ? \"oui-hidden\" : \"\"}`}\n aria-label=\"Previous campaigns\"\n >\n <ChevronLeftIcon\n opacity={1}\n className=\"oui-text-base-contrast-54 group-hover:oui-text-base-contrast\"\n />\n </button>\n\n <div className=\"oui-flex-1 oui-min-w-0 oui-overflow-hidden\">\n <div ref={emblaRef}>\n <div className=\"oui-flex oui-gap-2\">\n {campaigns?.map((campaign) => (\n <div\n key={campaign.campaign_id}\n className=\"oui-flex-shrink-0\"\n style={slideStyle}\n >\n <CampaignItemUI\n backgroundSrc={backgroundSrc}\n campaign={campaign}\n tag={getCampaignTag(campaign)}\n active={currentCampaignId == campaign.campaign_id}\n onCampaignChange={onCampaignChange}\n classNames={{\n tag: {\n container: \"oui-h-[23px] oui-py-1 oui-px-2\",\n },\n }}\n />\n </div>\n ))}\n </div>\n </div>\n </div>\n <button\n onClick={scrollNext}\n disabled={!canScrollNext}\n className={`oui-group oui-flex oui-items-center oui-justify-center oui-shrink-0 oui-w-6 oui-h-[78px] oui-rounded-lg oui-transition-colors hover:oui-bg-base-7 disabled:oui-opacity-30 disabled:oui-cursor-not-allowed disabled:hover:oui-bg-transparent ${shouldHideScrollButtons ? \"oui-hidden\" : \"\"}`}\n aria-label=\"Next campaigns\"\n >\n <ChevronRightIcon\n opacity={1}\n className=\"oui-text-base-contrast-54 group-hover:oui-text-base-contrast\"\n />\n </button>\n </div>\n );\n};\n","import { FC } from \"react\";\nimport { useTranslation } from \"@orderly.network/i18n\";\nimport { cn } from \"@orderly.network/ui\";\n\nexport const DefaultCampaign: FC<{\n currentCampaignId: string;\n onCampaignChange: (campaignId: string) => void;\n style?: React.CSSProperties;\n className?: string;\n}> = ({ currentCampaignId, onCampaignChange, style, className }) => {\n const { t } = useTranslation();\n return (\n <div\n className={cn([\n \"oui-trading-leaderboard-title\",\n \"oui-flex oui-items-center oui-justify-center oui-cursor-pointer\",\n \"oui-bg-base-9 oui-h-[78px] oui-rounded-lg oui-border oui-border-solid\",\n currentCampaignId === \"general\"\n ? \"oui-border-[rgba(var(--oui-gradient-brand-start))]\"\n : \"oui-border-transparent\",\n className,\n ])}\n style={style}\n onClick={() => onCampaignChange(\"general\")}\n >\n {t(\"tradingLeaderboard.generalLeaderboard\")}\n </div>\n );\n};\n","import { FC } from \"react\";\nimport { cn, Text } from \"@orderly.network/ui\";\nimport { CampaignConfig, CampaignTagEnum } from \"./type\";\n\ninterface CampaignItemUIProps {\n className?: string;\n active?: boolean;\n tag: CampaignTagEnum;\n onCampaignChange: (campaignId: string) => void;\n campaign: CampaignConfig;\n backgroundSrc?: string;\n classNames?: {\n container?: string;\n content?: string;\n tag?: {\n container?: string;\n text?: string;\n };\n title?: string;\n };\n}\n\nexport const CampaignItemUI: FC<CampaignItemUIProps> = ({\n active,\n tag,\n onCampaignChange,\n campaign,\n backgroundSrc,\n classNames,\n}) => {\n return (\n <div\n className={cn([\n \"oui-w-full\",\n \"oui-relative oui-h-[78px] oui-cursor-pointer oui-overflow-hidden oui-rounded-lg oui-bg-white/[0.04]\",\n \"oui-group oui-border oui-border-solid oui-backdrop-blur-[200px]\",\n active\n ? \"oui-border-[rgba(var(--oui-gradient-brand-start))]\"\n : \"oui-border-transparent\",\n \"hover:oui-border-base-contrast\",\n classNames?.container,\n ])}\n onClick={() => onCampaignChange(campaign.campaign_id.toString())}\n >\n <CampaignTag tag={tag} active={active} classNames={classNames?.tag} />\n <div\n className={cn([\n \"oui-size-full\",\n \"oui-absolute oui-left-0 oui-top-0\",\n \"oui-bg-cover oui-bg-center oui-bg-no-repeat oui-bg-blend-luminosity\",\n active ? \"oui-bg-transparent\" : \"oui-bg-[lightgray] oui-opacity-40\",\n \"group-hover:oui-bg-transparent group-hover:oui-opacity-100\",\n ])}\n style={{\n backgroundImage: `url(${campaign?.image || backgroundSrc})`,\n }}\n />\n <div\n className={cn([\n \"oui-flex oui-size-full oui-flex-col oui-items-center oui-justify-center oui-gap-1\",\n \"oui-absolute oui-left-0 oui-top-0 oui-z-10\",\n classNames?.content,\n ])}\n >\n <Text\n weight=\"semibold\"\n className={cn([\n active ? \"oui-text-base-contrast\" : \"oui-text-base-contrast-54\",\n \"group-hover:oui-text-base-contrast\",\n \"oui-trading-leaderboard-title\",\n \"oui-w-3/5 oui-text-center oui-text-sm\",\n classNames?.title,\n ])}\n >\n {campaign.title}\n </Text>\n {campaign.referral_codes && (\n <Text\n className={cn([\n \"oui-text-base-contrast-54\",\n \"oui-text-center oui-text-[10px]\",\n ])}\n >\n {Array.isArray(campaign.referral_codes)\n ? campaign.referral_codes.join(\",\")\n : campaign.referral_codes}\n </Text>\n )}\n </div>\n </div>\n );\n};\n\nconst CampaignTag: FC<{\n tag: CampaignTagEnum;\n active?: boolean;\n classNames?: {\n container?: string;\n text?: string;\n };\n}> = ({ tag, active, classNames }) => {\n const tagText = tag.slice(0, 1).toUpperCase() + tag.slice(1);\n return (\n <div\n className={cn([\n \"oui-w-fit oui-rounded-br-lg\",\n \"oui-absolute oui-left-0 oui-top-0 oui-z-10 oui-flex oui-items-center\",\n active && tag !== CampaignTagEnum.COMING\n ? \"oui-bg-[rgba(var(--oui-gradient-brand-start))]\"\n : \"oui-bg-base-4\",\n active && tag !== CampaignTagEnum.ENDED && \"group-hover:oui-bg-base-4\",\n tag === CampaignTagEnum.ENDED &&\n \"oui-bg-base-6 group-hover:oui-bg-base-6\",\n classNames?.container,\n ])}\n >\n {tag === CampaignTagEnum.ENDED ? (\n <Text\n size=\"2xs\"\n weight=\"semibold\"\n className={cn([\"oui-text-base-contrast-54\", classNames?.text])}\n >\n {tagText}\n </Text>\n ) : (\n <Text.gradient\n size=\"2xs\"\n weight=\"semibold\"\n color=\"brand\"\n className={cn([\n active &&\n tag !== CampaignTagEnum.COMING &&\n \"oui-text-black/[0.88] group-hover:oui-text-transparent\",\n classNames?.text,\n ])}\n >\n {tagText}\n </Text.gradient>\n )}\n </div>\n );\n};\n","import { FC, useCallback, useState, useEffect, memo, useRef } from \"react\";\nimport useEmblaCarousel from \"embla-carousel-react\";\nimport { ChevronLeftIcon, ChevronRightIcon } from \"@orderly.network/ui\";\nimport { DefaultCampaign } from \"../DefaultCampaign\";\nimport { CampaignItemUI } from \"../campaign.item.ui\";\nimport { CampaignConfig } from \"../type\";\nimport { getCampaignTag } from \"../utils\";\n\nexport const CampaignsHeaderMobileUI = memo<{\n campaigns: CampaignConfig[];\n currentCampaignId: string;\n onCampaignChange: (campaignId: string) => void;\n backgroundSrc?: string;\n}>(({ campaigns, currentCampaignId, onCampaignChange, backgroundSrc }) => {\n const [canScrollPrev, setCanScrollPrev] = useState(false);\n const [canScrollNext, setCanScrollNext] = useState(false);\n const hasInitialScrolled = useRef(false);\n const isInitializing = useRef(true);\n\n const [emblaRef, emblaApi] = useEmblaCarousel({\n loop: false,\n align: \"start\",\n containScroll: \"keepSnaps\",\n slidesToScroll: 1,\n skipSnaps: false,\n dragFree: false,\n });\n\n // All campaign items including default campaign\n const allCampaignItems = [\n { campaign_id: \"general\", isDefault: true },\n ...campaigns.map((campaign) => ({ ...campaign, isDefault: false })),\n ];\n\n // Update scroll availability and handle auto campaign change on slide\n const updateScrollAvailability = useCallback(() => {\n if (!emblaApi || !campaigns?.length) return;\n\n setCanScrollPrev(emblaApi.canScrollPrev());\n setCanScrollNext(emblaApi.canScrollNext());\n\n // Skip auto campaign change during initialization or before initial scroll is completed\n if (isInitializing.current || !hasInitialScrolled.current) return;\n\n // Auto trigger onCampaignChange when slide changes (only after user interaction)\n const selectedIndex = emblaApi.selectedScrollSnap();\n const selectedCampaign = allCampaignItems[selectedIndex];\n\n if (selectedCampaign) {\n const campaignId = selectedCampaign.isDefault\n ? \"general\"\n : String(selectedCampaign.campaign_id);\n if (campaignId != currentCampaignId) {\n onCampaignChange(campaignId);\n }\n }\n }, [\n emblaApi,\n campaigns,\n currentCampaignId,\n onCampaignChange,\n allCampaignItems,\n ]);\n\n // Auto scroll to current campaign on initial load\n const scrollToCurrentCampaign = useCallback(() => {\n if (!emblaApi || !campaigns?.length) return;\n\n const targetIndex = allCampaignItems.findIndex((item) => {\n const campaignId = item.isDefault ? \"general\" : String(item.campaign_id);\n return campaignId === currentCampaignId;\n });\n\n if (targetIndex !== -1 && targetIndex !== emblaApi.selectedScrollSnap()) {\n emblaApi.scrollTo(targetIndex, false); // false to disable animation for initial scroll\n }\n\n // Mark as scrolled and initialized after the scroll operation\n hasInitialScrolled.current = true;\n // Small delay to ensure the scroll operation is completed before enabling auto change\n setTimeout(() => {\n isInitializing.current = false;\n }, 100);\n }, [emblaApi, campaigns, currentCampaignId, allCampaignItems]);\n\n useEffect(() => {\n if (!emblaApi) return;\n\n // Initial check\n updateScrollAvailability();\n\n // Auto scroll to current campaign on initial load\n scrollToCurrentCampaign();\n\n // Listen for scroll events\n emblaApi.on(\"select\", updateScrollAvailability);\n emblaApi.on(\"reInit\", updateScrollAvailability);\n\n return () => {\n emblaApi.off(\"select\", updateScrollAvailability);\n emblaApi.off(\"reInit\", updateScrollAvailability);\n };\n }, [emblaApi, updateScrollAvailability, scrollToCurrentCampaign]);\n\n // Reset scroll flag when currentCampaignId changes externally\n useEffect(() => {\n hasInitialScrolled.current = false;\n isInitializing.current = true;\n if (emblaApi) {\n scrollToCurrentCampaign();\n }\n }, [currentCampaignId, scrollToCurrentCampaign, emblaApi]);\n\n const scrollPrev = useCallback(() => {\n if (emblaApi) {\n // Enable auto campaign change after user interaction\n isInitializing.current = false;\n emblaApi.scrollPrev();\n }\n }, [emblaApi]);\n\n const scrollNext = useCallback(() => {\n if (emblaApi) {\n // Enable auto campaign change after user interaction\n isInitializing.current = false;\n emblaApi.scrollNext();\n }\n }, [emblaApi]);\n\n // Mobile shows one item at full width\n const slideStyle = { flexBasis: \"100%\", width: \"100%\", height: \"42px\" };\n\n // Hide scroll buttons when there's only one or no campaigns\n const shouldHideScrollButtons = campaigns.length < 1;\n\n return (\n <div className=\"oui-flex oui-w-full oui-items-center oui-gap-2 oui-px-3\">\n <button\n onClick={scrollPrev}\n disabled={!canScrollPrev}\n className={`oui-group oui-flex oui-h-[42px] oui-w-6 oui-shrink-0 oui-items-center oui-justify-center oui-rounded-lg oui-transition-colors hover:oui-bg-base-7 disabled:oui-cursor-not-allowed disabled:oui-opacity-30 disabled:hover:oui-bg-transparent ${shouldHideScrollButtons ? \"oui-hidden\" : \"\"}`}\n aria-label=\"Previous campaigns\"\n >\n <ChevronLeftIcon\n opacity={1}\n className=\"oui-text-base-contrast-54 group-hover:oui-text-base-contrast\"\n />\n </button>\n\n <div className=\"oui-min-w-0 oui-flex-1 oui-overflow-hidden\">\n <div ref={emblaRef}>\n <div className=\"oui-flex oui-gap-2\">\n <DefaultCampaign\n key=\"general_campaign\"\n currentCampaignId={currentCampaignId}\n onCampaignChange={onCampaignChange}\n style={slideStyle}\n className=\"oui-w-full oui-shrink-0\"\n />\n {campaigns?.map((campaign) => (\n <div\n key={campaign.campaign_id}\n className=\"oui-shrink-0\"\n style={slideStyle}\n >\n <CampaignItemUI\n backgroundSrc={backgroundSrc}\n campaign={campaign}\n tag={getCampaignTag(campaign)}\n active={currentCampaignId == campaign.campaign_id}\n onCampaignChange={onCampaignChange}\n classNames={{\n container: \"!oui-h-[42px]\",\n title: \"!oui-text-[10px]\",\n content: \"!oui-gap-[2px]\",\n tag: {\n container: \"!oui-h-[14px] !oui-px-1 !oui-py-[2px]\",\n text: \"!oui-text-[10px]\",\n },\n }}\n />\n </div>\n ))}\n </div>\n </div>\n </div>\n <button\n onClick={scrollNext}\n disabled={!canScrollNext}\n className={`oui-group oui-flex oui-h-[42px] oui-w-6 oui-shrink-0 oui-items-center oui-justify-center oui-rounded-lg oui-transition-colors hover:oui-bg-base-7 disabled:oui-cursor-not-allowed disabled:oui-opacity-30 disabled:hover:oui-bg-transparent ${shouldHideScrollButtons ? \"oui-hidden\" : \"\"}`}\n aria-label=\"Next campaigns\"\n >\n <ChevronRightIcon\n opacity={1}\n className=\"oui-text-base-contrast-54 group-hover:oui-text-base-contrast\"\n />\n </button>\n </div>\n );\n});\n","import { useScreen } from \"@orderly.network/ui\";\nimport { CampaignConfig } from \"../type\";\nimport { CampaignsHeaderUI } from \"./campaigns.header.desktop.ui\";\nimport { CampaignsHeaderMobileUI } from \"./campaigns.header.mobile.ui\";\n\nexport const CampaignsHeaderWidget = (props: {\n campaigns: CampaignConfig[];\n currentCampaignId: string;\n onCampaignChange: (campaignId: string) => void;\n backgroundSrc?: string;\n}) => {\n const { isMobile } = useScreen();\n return isMobile ? (\n <CampaignsHeaderMobileUI {...props} />\n ) : (\n <CampaignsHeaderUI {...props} />\n );\n};\n","import { useMemo } from \"react\";\nimport { useTranslation } from \"@orderly.network/i18n\";\nimport { useScreen } from \"@orderly.network/ui\";\nimport { LeaderboardTitle } from \"../../pages/leaderboard/page\";\nimport { useCampaignsScript } from \"../campaigns/campaigns.script\";\nimport { RewardsDesktopUI } from \"./rewards.desktop.ui\";\n\nexport const RewardsWidget = () => {\n const state = useCampaignsScript();\n const { t } = useTranslation();\n const { isMobile } = useScreen();\n\n const hideConfig = useMemo(() => {\n return {\n estimatedRewards: state.currentCampaign?.hide_estimated_rewards,\n };\n }, [state.currentCampaign]);\n\n if (\n state.currentCampaignId === \"general\" ||\n state.currentCampaign?.hide_rewards\n ) {\n return null;\n }\n\n return (\n <>\n <LeaderboardTitle\n title={t(\"tradingRewards.rewards\")}\n isMobile={isMobile}\n />\n <RewardsDesktopUI\n campaign={state.currentCampaign}\n userdata={state.userData}\n onLearnMore={state.onLearnMore}\n onTradeNow={state.onTradeNow}\n isMobile={isMobile}\n shouldShowJoinButton={state.shouldShowJoinButton}\n joinCampaign={state.joinCampaign}\n hideConfig={hideConfig}\n />\n </>\n );\n};\n","import { FC, useMemo, useState } from \"react\";\nimport { useTranslation, Trans } from \"@orderly.network/i18n\";\nimport { InfoCircleIcon, Tooltip, Text, Button, cn } from \"@orderly.network/ui\";\nimport { commify } from \"@orderly.network/utils\";\nimport { CampaignConfig, UserData } from \"../campaigns/type\";\nimport {\n calculateEstimatedRewards,\n calculateEstimatedTickets,\n calculateUserPoolReward,\n formatRewardAmount,\n formatTicketCount,\n calculateTicketProgress,\n} from \"./utils\";\n\ninterface RewardsDesktopUIProps {\n campaign?: CampaignConfig;\n userdata?: UserData;\n onLearnMore: () => void;\n onTradeNow: () => void;\n isMobile?: boolean;\n shouldShowJoinButton?: boolean;\n joinCampaign?: (data: { campaign_id: string | number }) => Promise<any>;\n isJoining?: boolean;\n hideConfig?: {\n estimatedRewards?: boolean;\n estimatedTickets?: boolean;\n };\n}\n\nexport const RewardsDesktopUI: FC<RewardsDesktopUIProps> = ({\n campaign,\n userdata,\n onLearnMore,\n onTradeNow,\n isMobile,\n shouldShowJoinButton,\n joinCampaign,\n isJoining,\n hideConfig,\n}) => {\n const { t } = useTranslation();\n // Use mock data for userdata if not provided\n const currentUserData = userdata;\n\n // Calculate estimated rewards\n const estimatedRewards =\n campaign && currentUserData\n ? calculateEstimatedRewards(currentUserData, campaign)\n : null;\n\n // Calculate estimated tickets\n const estimatedTickets =\n campaign?.ticket_rules && currentUserData\n ? calculateEstimatedTickets(currentUserData, campaign.ticket_rules)\n : 0;\n\n const rewardText = estimatedRewards\n ? formatRewardAmount(estimatedRewards.amount, estimatedRewards.currency)\n : \"0 USDC\";\n\n const ticketText = formatTicketCount(estimatedTickets);\n\n const canTrade = useMemo(() => {\n return (\n campaign?.start_time &&\n campaign?.end_time &&\n campaign.start_time < new Date().toISOString() &&\n campaign.end_time > new Date().toISOString()\n );\n }, [campaign]);\n\n const tooltipContent = useMemo(() => {\n // if (!campaign?.prize_pools || !currentUserData) {\n // return null;\n // }\n\n return (\n <div className=\"oui-flex oui-min-w-[240px] oui-flex-col oui-gap-1\">\n {campaign?.prize_pools?.map((pool) => {\n if (pool.tiers.length == 0) {\n return null;\n }\n const userPoolReward = currentUserData\n ? calculateUserPoolReward(currentUserData, pool)\n : 0;\n\n return (\n <div\n key={pool.pool_id}\n className=\"oui-flex oui-h-[18px] oui-items-center oui-justify-between\"\n >\n <Text\n size=\"2xs\"\n weight=\"semibold\"\n className=\"oui-text-base-contrast-54\"\n >\n {pool.label}\n </Text>\n <div className=\"oui-flex oui-items-center oui-gap-1\">\n <Text.numeral\n dp={2}\n size=\"2xs\"\n weight=\"semibold\"\n className=\"oui-text-base-contrast\"\n >\n {userPoolReward}\n </Text.numeral>\n <Text\n size=\"2xs\"\n weight=\"semibold\"\n className=\"oui-text-base-contrast\"\n >\n {pool.currency}\n </Text>\n </div>\n </div>\n );\n })}\n </div>\n );\n }, [campaign, currentUserData]);\n\n const ticketTooltipContent = useMemo(() => {\n const ticketRules = campaign?.ticket_rules;\n\n if (!ticketRules) {\n return null;\n }\n\n if (ticketRules.mode === \"linear\") {\n return (\n <div>\n {t(\"tradingLeaderboard.earnTickets\", {\n ticket: ticketRules?.linear?.tickets,\n amount: commify(ticketRules?.linear?.every || 0),\n })}\n </div>\n );\n }\n\n return (\n <div className=\"oui-flex oui-min-w-[240px] oui-flex-col oui-gap-1\">\n {ticketRules?.tiers?.map((tier) => {\n return (\n <div\n key={tier.value}\n className=\"h-[18px] oui-flex oui-items-center oui-justify-between oui-text-2xs oui-font-semibold\"\n >\n <Text.numeral\n currency=\"$\"\n suffix=\" volume\"\n dp={0}\n className=\"oui-text-base-contrast-54\"\n >\n {tier.value}\n </Text.numeral>\n <div className=\"oui-text-base-contrast\">\n {tier.tickets} tickets\n </div>\n </div>\n );\n })}\n </div>\n );\n }, [campaign]);\n\n const extraProps = useMemo(() => {\n if (\n !userdata ||\n !campaign?.ticket_rules ||\n campaign.end_time < new Date().toISOString() ||\n campaign.start_time > new Date().toISOString()\n ) {\n return {\n showExtraInfo: false,\n extraInfo: null,\n };\n }\n\n const progress = calculateTicketProgress(userdata, campaign.ticket_rules);\n\n if (!progress) {\n return {\n showExtraInfo: false,\n extraInfo: null,\n };\n }\n\n return {\n showExtraInfo: true,\n extraInfo: progress,\n };\n }, [campaign, userdata]);\n\n return (\n <div\n className={cn([\n \"oui-mx-auto oui-mb-10 oui-flex oui-max-w-[992px] oui-flex-col oui-pb-10\",\n isMobile ? \"oui-gap-3\" : \"oui-gap-6\",\n ])}\n >\n <div\n className={cn([\n \"oui-flex oui-w-full oui-items-stretch oui-gap-3\",\n isMobile ? \"oui-px-3\" : \"\",\n ])}\n >\n {!hideConfig?.estimatedRewards && (\n <RewardItem\n title={t(\"tradingLeaderboard.estimatedRewards\")}\n value={rewardText}\n showTooltip\n tooltip={tooltipContent}\n isMobile={isMobile}\n />\n )}\n <RewardItem\n showTooltip={!!campaign?.ticket_rules}\n title={t(\"tradingLeaderboard.estimatedTicketsEarned\")}\n value={ticketText}\n tooltip={ticketTooltipContent}\n {...extraProps}\n isMobile={isMobile}\n />\n </div>\n <div\n className={cn([\n \"oui-flex oui-justify-center oui-gap-3\",\n isMobile ? \"oui-px-3\" : \"\",\n ])}\n >\n {campaign?.rule_url && (\n <Button\n size={isMobile ? \"md\" : \"lg\"}\n variant=\"outlined\"\n className={cn([\n \"oui-border-[rgb(var(--oui-gradient-brand-start))] oui-text-[rgb(var(--oui-gradient-brand-start))] hover:oui-bg-[rgb(var(--oui-gradient-brand-start))]/[0.08] active:oui-bg-[rgb(var(--oui-gradient-brand-start))]/[0.08]\",\n isMobile ? \"oui-flex-1\" : \"oui-w-[140px]\",\n ])}\n onClick={onLearnMore}\n >\n {t(\"tradingLeaderboard.viewRules\")}\n </Button>\n )}\n {shouldShowJoinButton && (\n <Button\n size={isMobile ? \"md\" : \"lg\"}\n variant=\"gradient\"\n color=\"primary\"\n loading={isJoining}\n disabled={isJoining}\n className={cn([isMobile ? \"oui-flex-1\" : \"oui-w-[140px]\"])}\n onClick={() =>\n joinCampaign?.({ campaign_id: Number(campaign?.campaign_id) })\n }\n >\n {t(\"tradingLeaderboard.joinNow\")}\n </Button>\n )}\n {!shouldShowJoinButton && canTrade && (\n <Button\n size={isMobile ? \"md\" : \"lg\"}\n variant=\"gradient\"\n color=\"primary\"\n className={cn([isMobile ? \"oui-flex-1\" : \"oui-w-[140px]\"])}\n onClick={onTradeNow}\n >\n {t(\"tradingLeaderboard.tradeNow\")}\n </Button>\n )}\n </div>\n </div>\n );\n};\n\nconst RewardItem: FC<{\n title: string;\n value: string;\n showTooltip?: boolean;\n tooltip?: any;\n showExtraInfo?: boolean;\n extraInfo?: {\n percent: number;\n value: number;\n } | null;\n isMobile?: boolean;\n}> = (props) => {\n const [tooltipOpen, setTooltipOpen] = useState(false);\n\n const tooltipProps = useMemo(() => {\n if (!props.isMobile) {\n return {};\n }\n return {\n open: tooltipOpen,\n onOpenChange: setTooltipOpen,\n };\n }, [tooltipOpen, props.isMobile, setTooltipOpen]);\n\n return (\n <div className=\"oui-flex oui-flex-1 oui-flex-col oui-items-center oui-justify-center oui-rounded-2xl oui-bg-base-9 oui-px-5 oui-py-4\">\n <div\n className={cn([\n \"oui-text-base-contrast-54\",\n props.isMobile\n ? \"oui-h-[15px] oui-text-2xs oui-leading-[15px]\"\n : \"oui-text-sm oui-font-semibold\",\n ])}\n >\n {props.title}\n </div>\n <div className=\"oui-flex oui-items-center oui-gap-2\">\n <Text.gradient\n weight=\"bold\"\n color=\"brand\"\n className={cn([\n \"oui-trading-leaderboard-title\",\n props.isMobile\n ? \"oui-h-[16px] oui-text-base oui-leading-[16px]\"\n : \"oui-h-10 oui-text-[32px] oui-leading-10\",\n ])}\n >\n {props.value}\n </Text.gradient>\n {props.showTooltip && (\n <Tooltip content={props.tooltip} {...tooltipProps}>\n <div\n className=\"oui-flex oui-size-4 oui-items-center oui-justify-center\"\n onClick={() => setTooltipOpen(true)}\n >\n <InfoCircleIcon className=\"oui-cursor-pointer\" />\n </div>\n </Tooltip>\n )}\n </div>\n {props.showExtraInfo && (\n <div\n className={cn([\n \"oui-flex oui-flex-col oui-items-center oui-justify-end\",\n props.isMobile ? \"oui-mt-2\" : \"\",\n ])}\n >\n <div className=\"oui-flex oui-flex-col oui-items-center oui-gap-1 oui-text-2xs oui-font-semibold oui-text-base-contrast-36\">\n <div\n className={cn([\n \"oui-flex oui-h-[18px] oui-w-[225px] oui-items-center oui-rounded-[100px] oui-bg-base-5 oui-p-[2px]\",\n props.isMobile ? \"oui-w-full\" : \"oui-w-[225px]\",\n ])}\n >\n <div\n className={cn([\n \"oui-h-[14px] oui-rounded-[100px]\",\n \"oui-bg-[linear-gradient(270deg,rgb(var(--oui-gradient-brand-start))_0%,rgb(var(--oui-gradient-brand-end))_100%)]\",\n ])}\n style={{ width: `${props?.extraInfo?.percent}%` }}\n />\n </div>\n <div\n className={cn([\n \"oui-text-center oui-font-semibold\",\n props.isMobile ? \"oui-text-2xs oui-leading-[15px]\" : \"\",\n ])}\n >\n {/* @ts-ignore */}\n {props.extraInfo.atMax ? (\n <Trans i18nKey=\"tradingLeaderboard.maxTicketsAchieved\" />\n ) : (\n <Trans\n i18nKey=\"tradingLeaderboard.tradeForMoreTickets\"\n components={[\n <span key=\"0\" className=\"oui-text-base-contrast\">\n ${props?.extraInfo?.value?.toFixed(2)}\n </span>,\n ]}\n />\n )}\n </div>\n </div>\n </div>\n )}\n </div>\n );\n};\n","import { useScreen } from \"@orderly.network/ui\";\nimport { useCampaignsScript } from \"../campaigns/campaigns.script\";\nimport { CampaignRuleUI } from \"./rule\";\nimport { CampaignTermsUI } from \"./terms\";\n\nexport const RuleWidget = () => {\n const state = useCampaignsScript();\n const { isMobile } = useScreen();\n\n const rulesAndTerms = state.currentCampaign?.rule;\n\n if (\n state.currentCampaignId === \"general\" ||\n !state.currentCampaign?.rule_config\n ) {\n return null;\n }\n\n return (\n <>\n <CampaignRuleUI\n id={state.currentCampaign.rule_url || \"\"}\n className={isMobile ? \"oui-px-3\" : \"\"}\n rules={rulesAndTerms?.rule}\n ruleConfig={rulesAndTerms?.ruleConfig}\n isMobile={isMobile}\n />\n <CampaignTermsUI\n className={isMobile ? \"oui-px-3\" : \"\"}\n termsConfig={rulesAndTerms?.terms}\n isMobile={isMobile}\n />\n </>\n );\n};\n","import { FC } from \"react\";\nimport { useTranslation } from \"@orderly.network/i18n\";\nimport { cn } from \"@orderly.network/ui\";\nimport { LeaderboardTitle } from \"../../pages/leaderboard/page\";\nimport {\n DescriptionContent,\n DescriptionItem,\n DescriptionConfig,\n} from \"./description\";\n\ntype RuleUIProps = {\n id: string;\n className?: string;\n isMobile?: boolean;\n rules?: DescriptionItem[];\n ruleConfig?: DescriptionConfig;\n};\n\nexport const CampaignRuleUI: FC<RuleUIProps> = ({\n id,\n className,\n isMobile,\n rules,\n ruleConfig,\n}) => {\n const { t } = useTranslation();\n return (\n <div\n className={cn(\"oui-mx-auto oui-max-w-[992px] oui-py-10\", className)}\n id={id}\n >\n <LeaderboardTitle\n isMobile={isMobile}\n title={t(\"tradingLeaderboard.rules\")}\n />\n <DescriptionContent description={rules || []} config={ruleConfig} />\n </div>\n );\n};\n","import { FC } from \"react\";\nimport { cn } from \"@orderly.network/ui\";\n\n// import ReactMarkdown from \"react-markdown\";\n// import remarkGfm from \"remark-gfm\";\n\n// Enhanced type definition supporting multiple content formats\ntype ListStyle =\n | \"disc\"\n | \"decimal\"\n | \"none\"\n | \"circle\"\n | \"square\"\n | \"decimal-leading-zero\"\n | \"lower-alpha\"\n | \"upper-alpha\"\n | \"lower-roman\"\n | \"upper-roman\";\n\nexport type DescriptionItem = {\n content: string; // Support markdown syntax, plain text, or image URL\n type: \"markdown\" | \"text\" | \"image\";\n alt?: string; // For images\n className?: string; // Custom styling\n listStyle?: ListStyle; // List style for ul/ol elements\n listClassName?: string; // Custom list container class\n children?: DescriptionItem[];\n};\n\nexport type DescriptionConfig = {\n listStyle?: ListStyle; // Global list style\n listClassName?: string; // Global list container class\n};\n\n// Utility function to get list style classes\nconst getListStyleClass = (style: ListStyle): string => {\n const styleMap: Record<ListStyle, string> = {\n disc: \"oui-list-disc\",\n decimal: \"oui-list-decimal\",\n none: \"oui-list-none\",\n circle: \"oui-list-disc\", // Tailwind doesn't have circle, fallback to disc\n square: \"oui-list-disc\", // Tailwind doesn't have square, fallback to disc\n \"decimal-leading-zero\": \"oui-list-decimal\",\n \"lower-alpha\": \"oui-list-decimal\", // Fallback\n \"upper-alpha\": \"oui-list-decimal\", // Fallback\n \"lower-roman\": \"oui-list-decimal\", // Fallback\n \"upper-roman\": \"oui-list-decimal\", // Fallback\n };\n return styleMap[style] || \"oui-list-disc\";\n};\n\n// Custom rich text parser (no external dependencies)\nconst parseRichText = (text: string): JSX.Element[] => {\n const parts: JSX.Element[] = [];\n let currentIndex = 0;\n let key = 0;\n\n // Parse **bold** syntax\n const boldRegex = /\\*\\*(.*?)\\*\\*/g;\n // Parse [link text](url) syntax\n const linkRegex = /\\[([^\\]]+)\\]\\(([^)]+)\\)/g;\n // Parse  syntax\n const imageRegex = /!\\[([^\\]]*)\\]\\(([^)]+)\\)/g;\n\n const allMatches: Array<{\n type: \"bold\" | \"link\" | \"image\";\n match: RegExpMatchArray;\n index: number;\n }> = [];\n\n // Find all matches\n let match;\n while ((match = boldRegex.exec(text)) !== null) {\n allMatches.push({ type: \"bold\", match, index: match.index });\n }\n while ((match = linkRegex.exec(text)) !== null) {\n allMatches.push({ type: \"link\", match, index: match.index });\n }\n while ((match = imageRegex.exec(text)) !== null) {\n allMatches.push({ type: \"image\", match, index: match.index });\n }\n\n // Sort by index\n allMatches.sort((a, b) => a.index - b.index);\n\n for (const { type, match } of allMatches) {\n // Add text before match\n if (match.index !== undefined && match.index > currentIndex) {\n const beforeText = text.slice(currentIndex, match.index);\n if (beforeText) {\n parts.push(<span key={key++}>{beforeText}</span>);\n }\n }\n\n // Add formatted element\n switch (type) {\n case \"bold\":\n parts.push(\n <strong\n key={key++}\n className=\"oui-font-bold oui-text-base-contrast-54\"\n >\n {match[1]}\n </strong>,\n );\n break;\n case \"link\":\n parts.push(\n <a\n key={key++}\n href={match[2]}\n className=\"oui-text-base-contrast-54 oui-underline hover:oui-text-base-contrast-54\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {match[1]}\n </a>,\n );\n break;\n case \"image\":\n parts.push(\n <img\n key={key++}\n src={match[2]}\n alt={match[1]}\n className=\"oui-my-2 oui-block oui-h-auto oui-max-w-full\"\n />,\n );\n break;\n }\n\n currentIndex = (match.index ?? 0) + match[0].length;\n }\n\n // Add remaining text\n if (currentIndex < text.length) {\n const remainingText = text.slice(currentIndex);\n if (remainingText) {\n parts.push(<span key={key++}>{remainingText}</span>);\n }\n }\n\n return parts.length > 0 ? parts : [<span key={0}>{text}</span>];\n};\n\n// Custom rich text implementation (recommended for lightweight needs)\nexport const DescriptionContent: FC<{\n description: DescriptionItem[] | ReadonlyArray<DescriptionItem>;\n config?: DescriptionConfig;\n}> = ({ description, config }) => {\n const renderContent = (\n contents: DescriptionItem[] | ReadonlyArray<DescriptionItem>,\n level: number = 0,\n ) => {\n // Determine list style - item level overrides global config\n const defaultListStyle = config?.listStyle || \"disc\";\n const hasListItems = contents.some((item) => item.children?.length);\n\n if (!hasListItems && contents.length === 1) {\n // Single item without children - render without list wrapper\n const content = contents[0];\n return (\n <div className={cn(\"oui-mb-2\", content.className)}>\n {renderContentItem(content)}\n </div>\n );\n }\n\n return (\n <ul\n className={cn(\n // Use list-outside for proper alignment\n \"oui-list-outside\",\n // Add left padding for proper spacing\n level === 0 ? \"oui-pl-5\" : \"oui-pl-4\",\n // Get list style class\n getListStyleClass(defaultListStyle),\n // Custom list container class\n config?.listClassName,\n )}\n >\n {contents.map((content, index) => {\n const itemListStyle = content.listStyle || defaultListStyle;\n\n return (\n <li\n key={`${content.content}-${index}`}\n className={cn(\n \"oui-mb-1 oui-leading-relaxed\",\n // Override list style if specified on item\n content.listStyle && getListStyleClass(itemListStyle),\n content.className,\n )}\n >\n {renderContentItem(content)}\n {content?.children?.length && (\n <div className=\"oui-mt-2 oui-text-sm oui-text-base-contrast-36\">\n {renderContent(content.children, level + 1)}\n </div>\n )}\n </li>\n );\n })}\n </ul>\n );\n };\n\n const renderContentItem = (content: DescriptionItem) => {\n if (content.type === \"image\") {\n return (\n <img\n src={content.content}\n alt={content.alt || \"\"}\n className=\"oui-my-2 oui-h-auto oui-max-w-full\"\n />\n );\n }\n\n // Both markdown and text use the rich text parser\n return (\n <div className=\"rich-text-content inline\">\n {parseRichText(content.content)}\n </div>\n );\n };\n\n return (\n <div\n className={cn(\n \"oui-text-sm oui-font-semibold oui-leading-[28px] oui-text-base-contrast-54\",\n )}\n >\n {renderContent(description)}\n </div>\n );\n};\n\n// Alternative: React-markdown implementation (requires additional dependencies)\nexport const MarkdownDescriptionContent: FC<{\n description: DescriptionItem[] | ReadonlyArray<DescriptionItem>;\n}> = ({ description }) => {\n const renderContent = (\n contents: DescriptionItem[] | ReadonlyArray<DescriptionItem>,\n ) => {\n return (\n <ul className=\"oui-list-inside oui-list-disc\">\n {contents.map((content, index) => (\n <li key={`${content.content}-${index}`} className={content.className}>\n {content.type === \"image\" ? (\n <img\n src={content.content}\n alt={content.alt || \"\"}\n className=\"oui-my-2 oui-h-auto oui-max-w-full\"\n />\n ) : (\n <div>{content.content}</div>\n )}\n {Array.isArray(content?.children) &&\n content?.children.length > 0 && (\n <div className=\"oui-ml-4\">\n {renderContent(content.children)}\n </div>\n )}\n </li>\n ))}\n </ul>\n );\n };\n\n return (\n <div\n className={cn(\n \"oui-text-sm oui-font-semibold oui-leading-[28px] oui-text-base-contrast-54\",\n )}\n >\n {renderContent(description)}\n </div>\n );\n};\n","import { FC } from \"react\";\nimport { useTranslation } from \"@orderly.network/i18n\";\nimport { EMPTY_LIST } from \"@orderly.network/types\";\nimport { cn } from \"@orderly.network/ui\";\nimport { LeaderboardTitle } from \"../../pages/leaderboard/page\";\nimport { DescriptionContent, DescriptionItem } from \"./description\";\n\ntype TermsUIProps = {\n className?: string;\n isMobile?: boolean;\n termsConfig?: DescriptionItem[];\n};\n\nexport const CampaignTermsUI: FC<TermsUIProps> = ({\n className,\n isMobile,\n termsConfig,\n}) => {\n const { t } = useTranslation();\n return (\n <div className={cn(\"oui-mx-auto oui-max-w-[992px] oui-py-10\", className)}>\n <LeaderboardTitle\n isMobile={isMobile}\n title={t(\"tradingLeaderboard.termsAndConditions\")}\n />\n <DescriptionContent description={termsConfig || EMPTY_LIST} />\n </div>\n );\n};\n"]}
|