Skip to content

Commit

Permalink
Merge pull request #2248 from zeitgeistpm/staging
Browse files Browse the repository at this point in the history
  • Loading branch information
github-actions[bot] authored Feb 8, 2024
2 parents fcae5b1 + f65e9f7 commit 93d2fd6
Show file tree
Hide file tree
Showing 9 changed files with 372 additions and 41 deletions.
88 changes: 88 additions & 0 deletions components/markets/FavoriteMarketsList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { ScalarRangeType } from "@zeitgeistpm/sdk";
import Decimal from "decimal.js";
import { ZTG } from "lib/constants";
import { useFavoriteMarkets } from "lib/hooks/queries/useFavoriteMarkets";
import { useMarketsStats } from "lib/hooks/queries/useMarketsStats";
import Loader from "react-spinners/PulseLoader";
import MarketCard from "./market-card/index";
import { MdFavorite, MdFavoriteBorder } from "react-icons/md";

export type FavoriteMarketsListProps = {
className?: string;
};

const FavoriteMarketsList = ({ className = "" }: FavoriteMarketsListProps) => {
const {
data: markets,
isFetching: isFetchingMarkets,
isLoading,
} = useFavoriteMarkets();

const count = markets?.length ?? 0;

const { data: stats } = useMarketsStats(
markets?.map((m) => m.marketId) ?? [],
);

return (
<div
className={"mb-[38px] scroll-mt-[40px] " + className}
data-testid="marketsList"
id={"market-list"}
>
<div className="mb-8 mt-8 flex items-center gap-3">
<MdFavorite className=" text-red-600" size={28} />
<h3 className="text-2xl">Favorite Markets</h3>
</div>
<div className="grid grid-cols-1 gap-7 md:grid-cols-2 lg:grid-cols-3">
{markets?.map((market) => {
const volume = market.volume;
const scalarType = market.scalarType as ScalarRangeType;
const stat = stats?.find((s) => s.marketId === market.marketId);
const question = market.question ?? "";
const image = market.img ?? "";
//check if market is categorical or scalar
let { categorical, scalar } = market.marketType ?? {};
if (categorical === null) {
categorical = "";
}
const filteredScalar =
scalar?.filter((item): item is string => item !== null) ?? [];
const marketType = { categorical, scalar: filteredScalar };
const pool = market.pool ?? null;
const tags =
market.tags?.filter((tag): tag is string => tag !== null) ?? [];

return (
<MarketCard
marketId={market.marketId}
outcomes={market.outcomes}
question={question}
creation={market.creation}
creator={market.creator}
img={image}
prediction={market.prediction}
endDate={market.period.end}
marketType={marketType}
scalarType={scalarType}
pool={pool}
neoPool={market.neoPool}
status={market.status}
baseAsset={market.baseAsset}
volume={new Decimal(volume).div(ZTG).toNumber()}
tags={tags}
numParticipants={stat?.participants}
liquidity={stat?.liquidity}
key={`market-${market.marketId}`}
/>
);
})}
</div>
{!(isFetchingMarkets || isLoading) && count === 0 && (
<div className="text-center">You have no favorite markets.</div>
)}
</div>
);
};

export default FavoriteMarketsList;
31 changes: 31 additions & 0 deletions components/markets/MarketFavoriteToggle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { useFavoriteMarketsStorage } from "lib/state/favorites";
import { MdFavorite, MdFavoriteBorder } from "react-icons/md";

export const MarketFavoriteToggle = ({
marketId,
size,
}: {
marketId: number;
size?: number;
}) => {
const { add, remove, isFavorite } = useFavoriteMarketsStorage();

return (
<div
className="ztg-transition relative inline-block transition-transform duration-200 active:scale-150"
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
isFavorite(marketId) ? remove(marketId) : add(marketId);
}}
>
{isFavorite(marketId) ? (
<MdFavorite className="text-red-600" size={size ?? 16} />
) : (
<MdFavoriteBorder size={size ?? 16} />
)}
</div>
);
};

export default MarketFavoriteToggle;
65 changes: 38 additions & 27 deletions components/markets/MarketHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Dialog } from "@headlessui/react";
import { OutcomeReport } from "@zeitgeistpm/indexer";
import {
IOBaseAssetId,
IOForeignAssetId,
Expand All @@ -6,46 +8,44 @@ import {
ScalarRangeType,
parseAssetId,
} from "@zeitgeistpm/sdk";
import CourtStageTimer from "components/court/CourtStageTimer";
import Avatar from "components/ui/Avatar";
import Modal from "components/ui/Modal";
import Skeleton from "components/ui/Skeleton";
import Decimal from "decimal.js";
import { PromotedMarket } from "lib/cms/get-promoted-markets";
import { BLOCK_TIME_SECONDS, ZTG } from "lib/constants";
import { X } from "react-feather";
import { lookupAssetImagePath } from "lib/constants/foreign-asset";
import { MarketPageIndexedData } from "lib/gql/markets";
import { useMarketCaseId } from "lib/hooks/queries/court/useMarketCaseId";
import { useIdentity } from "lib/hooks/queries/useIdentity";
import { shortenAddress } from "lib/util";
import { formatNumberCompact } from "lib/util/format-compact";
import { hasDatePassed } from "lib/util/hasDatePassed";
import { FC, PropsWithChildren, useState } from "react";
import { MarketTimer } from "./MarketTimer";
import { MarketTimerSkeleton } from "./MarketTimer";
import { OutcomeReport } from "@zeitgeistpm/indexer";
import {
MarketEventHistory,
useMarketEventHistory,
} from "lib/hooks/queries/useMarketEventHistory";
import Modal from "components/ui/Modal";
import { getMarketStatusDetails } from "lib/util/market-status-details";
import { formatScalarOutcome } from "lib/util/format-scalar-outcome";
import { Dialog } from "@headlessui/react";
import { usePoolLiquidity } from "lib/hooks/queries/usePoolLiquidity";
import { estimateMarketResolutionDate } from "lib/util/estimate-market-resolution";
import { MarketReport } from "lib/types";
import { AddressDetails } from "./MarketAddresses";
import Image from "next/image";
import {
FOREIGN_ASSET_METADATA,
lookupAssetImagePath,
} from "lib/constants/foreign-asset";
import { useMarketsStats } from "lib/hooks/queries/useMarketsStats";
import { MarketPromotionCallout } from "./PromotionCallout";
import { PromotedMarket } from "lib/cms/get-promoted-markets";
import { MarketDispute } from "lib/types/markets";
import { useMarketCaseId } from "lib/hooks/queries/court/useMarketCaseId";
import CourtStageTimer from "components/court/CourtStageTimer";
import { useMarketImage } from "lib/hooks/useMarketImage";
import { isAbsoluteUrl } from "next/dist/shared/lib/utils";
import { MarketReport } from "lib/types";
import { isMarketImageBase64Encoded } from "lib/types/create-market";
import { MarketDispute } from "lib/types/markets";
import { shortenAddress } from "lib/util";
import { estimateMarketResolutionDate } from "lib/util/estimate-market-resolution";
import { formatNumberCompact } from "lib/util/format-compact";
import { formatScalarOutcome } from "lib/util/format-scalar-outcome";
import { hasDatePassed } from "lib/util/hasDatePassed";
import { getMarketStatusDetails } from "lib/util/market-status-details";
import { isAbsoluteUrl } from "next/dist/shared/lib/utils";
import dynamic from "next/dynamic";
import Image from "next/image";
import { FC, PropsWithChildren, useState } from "react";
import { X } from "react-feather";
import { AddressDetails } from "./MarketAddresses";
import { MarketTimer, MarketTimerSkeleton } from "./MarketTimer";
import { MarketPromotionCallout } from "./PromotionCallout";

const MarketFavoriteToggle = dynamic(() => import("./MarketFavoriteToggle"), {
ssr: false,
});

export const UserIdentity: FC<
PropsWithChildren<{
Expand Down Expand Up @@ -523,6 +523,17 @@ const MarketHeader: FC<{
</div>
</div>

<div className="group relative flex items-center">
<div className="pt-1">
<MarketFavoriteToggle size={24} marketId={market.marketId} />
</div>
<div className="absolute bottom-0 right-0 z-10 translate-x-[50%] translate-y-[115%] whitespace-nowrap opacity-0 transition-opacity group-hover:opacity-100">
<div className="rounded-lg bg-pink-300 px-2 py-1 text-sm">
Toggle Favorited
</div>
</div>
</div>

{promotionData && (
<MarketPromotionCallout market={market} promotion={promotionData} />
)}
Expand Down
36 changes: 23 additions & 13 deletions components/markets/market-card/index.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,31 @@
import { FullMarketFragment } from "@zeitgeistpm/indexer";
import type { ScalarRangeType } from "@zeitgeistpm/sdk";
import {
IOBaseAssetId,
IOForeignAssetId,
parseAssetId,
} from "@zeitgeistpm/sdk";
import Skeleton from "components/ui/Skeleton";
import Decimal from "decimal.js";
import { ZTG } from "lib/constants";
import { lookupAssetImagePath } from "lib/constants/foreign-asset";
import { useMarketCmsMetadata } from "lib/hooks/queries/cms/useMarketCmsMetadata";
import { useMarketImage } from "lib/hooks/useMarketImage";
import { isMarketImageBase64Encoded } from "lib/types/create-market";
import { MarketOutcomes } from "lib/types/markets";
import { formatNumberCompact } from "lib/util/format-compact";
import { hasDatePassed } from "lib/util/hasDatePassed";
import { isAbsoluteUrl } from "next/dist/shared/lib/utils";
import dynamic from "next/dynamic";
import Image from "next/image";
import Link from "next/link";
import { BarChart2, Droplet, Users } from "react-feather";
import ScalarPriceRange from "../ScalarPriceRange";
import MarketCardContext from "./context";

import { FullMarketFragment } from "@zeitgeistpm/indexer";
import {
IOBaseAssetId,
IOForeignAssetId,
parseAssetId,
} from "@zeitgeistpm/sdk";
import { lookupAssetImagePath } from "lib/constants/foreign-asset";
import { useMarketImage } from "lib/hooks/useMarketImage";
import { isMarketImageBase64Encoded } from "lib/types/create-market";
import { isAbsoluteUrl } from "next/dist/shared/lib/utils";
import Image from "next/image";
import { useMarketCmsMetadata } from "lib/hooks/queries/cms/useMarketCmsMetadata";
const MarketFavoriteToggle = dynamic(() => import("../MarketFavoriteToggle"), {
ssr: false,
});

export interface IndexedMarketCardData {
marketId: number;
Expand Down Expand Up @@ -311,7 +315,13 @@ export const MarketCard = ({
</>
)}
</div>
<MarketCardDetails rows={infoRows} />
<div className="flex flex-1 gap-2">
<div className="flex-1">
<MarketCardDetails rows={infoRows} />
</div>

<MarketFavoriteToggle marketId={marketId} />
</div>
</Link>
</div>
</MarketCardContext.Provider>
Expand Down
21 changes: 20 additions & 1 deletion components/top-bar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import Skeleton from "components/ui/Skeleton";
import { delay } from "lib/util/delay";
import { useWallet } from "lib/state/wallet";
import { useZtgBalance } from "lib/hooks/queries/useZtgBalance";
import { MdFavoriteBorder } from "react-icons/md";

const AccountButton = dynamic(
async () => {
Expand Down Expand Up @@ -113,7 +114,7 @@ const TopBar = () => {
onClick={close}
>
<button
className={`group mb-4 flex w-full items-center gap-3 border-b-1 border-gray-300 px-2 py-2 pb-5 text-sm`}
className={`group mb-4 flex w-full items-center gap-3 border-gray-300 px-2 py-2 text-sm`}
>
<div className="relative h-6 w-6">
<FiStar size={"100%"} />
Expand All @@ -127,6 +128,24 @@ const TopBar = () => {
)}
</Menu.Item>

<Menu.Item>
{({ active, close }) => (
<Link href="/markets/favorites" onClick={close}>
<button
className={`group mb-4 flex w-full items-center gap-3 border-b-1 px-2 py-2 pb-5 text-sm`}
>
<div className="relative h-6 w-6">
<MdFavoriteBorder size={"100%"} />
</div>

<h3 className="text-sm font-semibold">
Favorites
</h3>
</button>
</Link>
)}
</Menu.Item>

<div className="block md:hidden">
<Menu.Item>
{({ active }) => (
Expand Down
1 change: 1 addition & 0 deletions layouts/DefaultLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const Onboarding = dynamic(
const greyBackgroundPageRoutes = [
"/",
"/markets",
"/markets/favorites",
"/create-account",
"/deposit",
"/topics",
Expand Down
Loading

0 comments on commit 93d2fd6

Please sign in to comment.