diff --git a/components/waves/drop/MemesSingleWaveDropInfoPanel.tsx b/components/waves/drop/MemesSingleWaveDropInfoPanel.tsx index 4b015cb25a..b4e2d7682f 100644 --- a/components/waves/drop/MemesSingleWaveDropInfoPanel.tsx +++ b/components/waves/drop/MemesSingleWaveDropInfoPanel.tsx @@ -18,44 +18,17 @@ import WaveDropDeleteButton from "@/components/utils/button/WaveDropDeleteButton import { ImageScale } from "@/helpers/image.helpers"; import Download from "@/components/download/Download"; import { getFileInfoFromUrl } from "@/helpers/file.helpers"; -import { ApiWaveOutcomeCredit } from "@/generated/models/ApiWaveOutcomeCredit"; -import { ApiWaveOutcomeType } from "@/generated/models/ApiWaveOutcomeType"; import { VotingModal, MobileVotingModal } from "@/components/voting"; import useIsMobileScreen from "@/hooks/isMobileScreen"; import { WaveDropVoteSummary } from "./WaveDropVoteSummary"; import { WaveDropMetaRow } from "./WaveDropMetaRow"; +import { useWaveRankReward } from "@/hooks/waves/useWaveRankReward"; interface MemesSingleWaveDropInfoPanelProps { readonly drop: ExtendedDrop; readonly wave: ApiWave | null; } -const calculateOutcomes = (drop: ExtendedDrop, wave: ApiWave | null) => { - if (!wave || !drop.rank) - return { nicTotal: 0, repTotal: 0, manualOutcomes: [] as string[] }; - - const rank = drop.rank; - const outcomes = wave.outcomes; - - const nicTotal = outcomes - .filter((o) => o.credit === ApiWaveOutcomeCredit.Cic) - .reduce((acc, o) => acc + (o.distribution?.[rank - 1]?.amount ?? 0), 0); - - const repTotal = outcomes - .filter((o) => o.credit === ApiWaveOutcomeCredit.Rep) - .reduce((acc, o) => acc + (o.distribution?.[rank - 1]?.amount ?? 0), 0); - - const manualOutcomes = outcomes - .filter( - (o) => - o.type === ApiWaveOutcomeType.Manual && - o.distribution?.[rank - 1]?.amount - ) - .map((o) => o.distribution?.[rank - 1]?.description ?? ""); - - return { nicTotal, repTotal, manualOutcomes }; -}; - export const MemesSingleWaveDropInfoPanel = ({ drop, wave, @@ -63,12 +36,14 @@ export const MemesSingleWaveDropInfoPanel = ({ const [isFullscreen, setIsFullscreen] = useState(false); const [isVotingOpen, setIsVotingOpen] = useState(false); const isMobileScreen = useIsMobileScreen(); - const { isWinner, canDelete, canShowVote, isVotingEnded } = useDropInteractionRules(drop); + const { isWinner, canDelete, canShowVote, isVotingEnded } = + useDropInteractionRules(drop); - const { nicTotal, repTotal, manualOutcomes } = useMemo( - () => calculateOutcomes(drop, wave), - [drop, wave] - ); + const { nicTotal, repTotal, manualOutcomes } = useWaveRankReward({ + waveId: drop.wave.id, + rank: drop.rank, + enabled: true, + }); const title = useMemo( () => @@ -115,11 +90,11 @@ export const MemesSingleWaveDropInfoPanel = ({ return ( <>
-
-
+
+
{artworkMedia && ( -
-
+
+
-
-
-
+
+
+
-

+

{title}

{description && ( -

+

{description}

)} @@ -174,7 +149,7 @@ export const MemesSingleWaveDropInfoPanel = ({ · {nicTotal} NIC @@ -186,7 +161,7 @@ export const MemesSingleWaveDropInfoPanel = ({ · {repTotal} Rep @@ -198,16 +173,16 @@ export const MemesSingleWaveDropInfoPanel = ({
-
+
-
-
+
+
{artworkMedia && fileInfo && ( -
+
Media Type:{" "} @@ -238,9 +213,9 @@ export const MemesSingleWaveDropInfoPanel = ({ animate={{ opacity: 1 }} exit={{ opacity: 0 }} transition={{ duration: 0.3 }} - className="tw-fixed tw-inset-0 tw-z-50 tw-bg-iron-950/90 tw-flex tw-flex-col tw-items-center tw-justify-center tw-p-4" + className="tw-fixed tw-inset-0 tw-z-50 tw-flex tw-flex-col tw-items-center tw-justify-center tw-bg-iron-950/90 tw-p-4" > -
+
@@ -249,7 +224,7 @@ export const MemesSingleWaveDropInfoPanel = ({
{description && ( -

+

{description}

)} @@ -261,20 +236,18 @@ export const MemesSingleWaveDropInfoPanel = ({
-
+
{title}
diff --git a/components/waves/winners/DefaultWaveWinnerDropSmall.tsx b/components/waves/winners/DefaultWaveWinnerDropSmall.tsx index f04a98465b..ba54b1e195 100644 --- a/components/waves/winners/DefaultWaveWinnerDropSmall.tsx +++ b/components/waves/winners/DefaultWaveWinnerDropSmall.tsx @@ -2,7 +2,6 @@ import { memo, useCallback } from "react"; import { ExtendedDrop } from "@/helpers/waves/drop.helpers"; -import { ApiWave } from "@/generated/models/ApiWave"; import Link from "next/link"; import { formatNumberWithCommas } from "@/helpers/Helpers"; import { getScaledImageUri, ImageScale } from "@/helpers/image.helpers"; @@ -17,12 +16,11 @@ import { ApiWaveCreditType } from "@/generated/models/ApiWaveCreditType"; interface DefaultWaveWinnerDropSmallProps { readonly drop: ExtendedDrop; readonly onDropClick: (drop: ExtendedDrop) => void; - readonly wave: ApiWave; readonly rank?: number | undefined; // For explicitly setting rank from decision winners } export const DefaultWaveWinnerDropSmall = memo( - ({ drop, onDropClick, wave, rank }) => { + ({ drop, onDropClick, rank }) => { // Use provided rank or fall back to drop.rank const effectiveRank = rank ?? drop.rank; @@ -63,10 +61,10 @@ export const DefaultWaveWinnerDropSmall = memo( return (
-
-
+
+
{effectiveRank && ( @@ -80,7 +78,7 @@ export const DefaultWaveWinnerDropSmall = memo( )}
-
+
( {hasUserVoted && (
- You: + You: @@ -114,11 +112,11 @@ export const DefaultWaveWinnerDropSmall = memo(
-
+
e.stopPropagation()} - className="tw-block tw-flex-shrink-0 desktop-hover:group-hover:tw-opacity-90 tw-transition-opacity" + className="tw-block tw-flex-shrink-0 tw-transition-opacity desktop-hover:group-hover:tw-opacity-90" > {drop.author.pfp ? ( ( ImageScale.W_AUTO_H_50 )} alt={`${drop.author.handle}'s profile`} - className="tw-size-7 tw-rounded-lg tw-ring-1 tw-ring-white/10 tw-object-cover" + className="tw-size-7 tw-rounded-lg tw-object-cover tw-ring-1 tw-ring-white/10" /> ) : ( -
+
)} @@ -141,15 +139,15 @@ export const DefaultWaveWinnerDropSmall = memo( e.stopPropagation()} - className="tw-no-underline tw-truncate desktop-hover:hover:tw-underline" + className="tw-truncate tw-no-underline desktop-hover:hover:tw-underline" > - + {drop.author.handle} - - + + {Time.millis(drop.created_at).toLocaleDropDateAndTimeString()}
@@ -157,8 +155,8 @@ export const DefaultWaveWinnerDropSmall = memo(
-
- +
+
diff --git a/components/waves/winners/MemesWaveWinnerDropSmall.tsx b/components/waves/winners/MemesWaveWinnerDropSmall.tsx index ebb3484fc2..e4ab87b391 100644 --- a/components/waves/winners/MemesWaveWinnerDropSmall.tsx +++ b/components/waves/winners/MemesWaveWinnerDropSmall.tsx @@ -2,7 +2,6 @@ import { memo, useCallback } from "react"; import { ExtendedDrop } from "@/helpers/waves/drop.helpers"; -import { ApiWave } from "@/generated/models/ApiWave"; import Link from "next/link"; import { formatNumberWithCommas } from "@/helpers/Helpers"; import { getScaledImageUri, ImageScale } from "@/helpers/image.helpers"; @@ -17,12 +16,11 @@ import { ApiWaveCreditType } from "@/generated/models/ApiWaveCreditType"; interface MemesWaveWinnerDropSmallProps { readonly drop: ExtendedDrop; readonly onDropClick: (drop: ExtendedDrop) => void; - readonly wave: ApiWave; readonly rank?: number | undefined; // For explicitly setting rank from decision winners } export const MemesWaveWinnerDropSmall = memo( - ({ drop, onDropClick, wave, rank }) => { + ({ drop, onDropClick, rank }) => { // Use provided rank or fall back to drop.rank const effectiveRank = rank ?? drop.rank; @@ -65,10 +63,10 @@ export const MemesWaveWinnerDropSmall = memo( return (
-
-
+
+
{effectiveRank && ( @@ -82,7 +80,7 @@ export const MemesWaveWinnerDropSmall = memo( )}
-
+
( {hasUserVoted && (
- You: + You: @@ -116,11 +114,11 @@ export const MemesWaveWinnerDropSmall = memo(
-
+
e.stopPropagation()} - className="tw-block tw-flex-shrink-0 desktop-hover:group-hover:tw-opacity-90 tw-transition-opacity" + className="tw-block tw-flex-shrink-0 tw-transition-opacity desktop-hover:group-hover:tw-opacity-90" > {drop.author.pfp ? ( ( ImageScale.W_AUTO_H_50 )} alt={`${drop.author.handle}'s profile`} - className="tw-size-7 tw-rounded-lg tw-ring-1 tw-ring-white/10 tw-object-cover" + className="tw-size-7 tw-rounded-lg tw-object-cover tw-ring-1 tw-ring-white/10" /> ) : ( -
+
)} @@ -143,22 +141,22 @@ export const MemesWaveWinnerDropSmall = memo( e.stopPropagation()} - className="tw-no-underline tw-truncate desktop-hover:hover:tw-underline" + className="tw-truncate tw-no-underline desktop-hover:hover:tw-underline" > - + {drop.author.handle} - +
-
- +
+
diff --git a/components/waves/winners/WaveWinnerItemSmall.tsx b/components/waves/winners/WaveWinnerItemSmall.tsx index ccb48b7fb9..8500033716 100644 --- a/components/waves/winners/WaveWinnerItemSmall.tsx +++ b/components/waves/winners/WaveWinnerItemSmall.tsx @@ -21,7 +21,6 @@ export const WaveWinnerItemSmall = memo( ); @@ -30,7 +29,6 @@ export const WaveWinnerItemSmall = memo( ); diff --git a/components/waves/winners/WaveWinnersSmallOutcome.tsx b/components/waves/winners/WaveWinnersSmallOutcome.tsx index feac02ba60..9493cb18af 100644 --- a/components/waves/winners/WaveWinnersSmallOutcome.tsx +++ b/components/waves/winners/WaveWinnersSmallOutcome.tsx @@ -2,19 +2,17 @@ import React, { useState, useEffect } from "react"; import { Tooltip } from "react-tooltip"; -import { ApiWave } from "@/generated/models/ApiWave"; import { ExtendedDrop } from "@/helpers/waves/drop.helpers"; -import { useDropOutcomes } from "@/hooks/drops/useDropOutcomes"; import { formatNumberWithCommas } from "@/helpers/Helpers"; +import { useWaveRankReward } from "@/hooks/waves/useWaveRankReward"; interface WaveWinnersSmallOutcomeProps { readonly drop: ExtendedDrop; - readonly wave: ApiWave; } export const WaveWinnersSmallOutcome: React.FC< WaveWinnersSmallOutcomeProps -> = ({ drop, wave }) => { +> = ({ drop }) => { const [isTouch, setIsTouch] = useState(false); const [isOpen, setIsOpen] = useState(false); @@ -29,92 +27,81 @@ export const WaveWinnersSmallOutcome: React.FC< } }; - const { - outcomes: { nicOutcomes, repOutcomes, manualOutcomes }, - haveOutcomes, - } = useDropOutcomes({ - drop, - wave, + const { nicTotal, repTotal, manualOutcomes } = useWaveRankReward({ + waveId: drop.wave.id, + rank: drop.rank, }); - if (!haveOutcomes) { + if (!(nicTotal || repTotal || manualOutcomes.length)) { return null; } const tooltipContent = ( -
+
Outcome Details
- {nicOutcomes.map((nicOutcome) => ( -
+
+
+ + + NIC + +
+ + {formatNumberWithCommas(nicTotal)} + +
+ +
+
- NIC - -
- - {formatNumberWithCommas(nicOutcome.value)} - -
- ))} - {repOutcomes.map((repOutcome) => ( -
-
-
- - - Rep - -
- - {formatNumberWithCommas(repOutcome.value)} + Rep
- {repOutcome.category} + {formatNumberWithCommas(repTotal)}
- ))} +
+ {manualOutcomes.map((outcome) => ( -
+
- {outcome.description} + {outcome}
@@ -141,19 +128,20 @@ export const WaveWinnersSmallOutcome: React.FC< e.stopPropagation(); handleClick(e); }} - className="tw-border-0 tw-rounded-lg tw-flex tw-items-center tw-gap-2 tw-min-w-6 tw-py-1.5 tw-px-2 tw-bg-iron-800 tw-ring-1 tw-ring-iron-700" + className="tw-flex tw-min-w-6 tw-items-center tw-gap-2 tw-rounded-lg tw-border-0 tw-bg-iron-800 tw-px-2 tw-py-1.5 tw-ring-1 tw-ring-iron-700" data-tooltip-id={`outcome-small-${drop.id}`} > Outcome:
- {!!nicOutcomes.length && ( + {!!nicTotal && ( )} - {!!repOutcomes.length && ( + {!!repTotal && (
+
Outcome Details @@ -87,13 +86,15 @@ export const WavePodiumItemContentOutcomes: React.FC< {nicOutcomes.map((nicOutcome) => (
+ className="tw-flex tw-items-center tw-justify-between tw-rounded-lg tw-bg-iron-800/40 tw-p-2" + >
+ className="tw-flex tw-flex-col tw-gap-y-1 tw-rounded-lg tw-bg-iron-800/40 tw-p-2" + >
+ className="tw-flex tw-items-center tw-justify-between tw-rounded-lg tw-bg-iron-800/40 tw-p-2" + >
+ Outcome
{!!nicOutcomes.length && ( -
+
+
+