Skip to content

Commit

Permalink
Merge branch 'staging' into tr-hide-grace-period-input
Browse files Browse the repository at this point in the history
  • Loading branch information
yornaath committed Feb 6, 2024
2 parents 6684ddf + feaef12 commit d99e645
Show file tree
Hide file tree
Showing 17 changed files with 731 additions and 25 deletions.
4 changes: 4 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ NEXT_PUBLIC_OTHER_TAGS=["Coindesk"]

NEXT_PUBLIC_COIN_GECKO_API_KEY=

# sanity cms config
NEXT_PUBLIC_SANITY_PROJECT_ID="4wbnjof1"
NEXT_PUBLIC_SANITY_VERSION="2022-03-07"

# enable topics
NEXT_PUBLIC_SHOW_TOPICS=true

2 changes: 1 addition & 1 deletion components/front-page/HeroBanner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const HeroBanner = ({
const prctChange = ((latestPrice - firstPrice) / firstPrice) * 100;

return (
<div className="main-container md:mt-18 z-2 relative mb-20 mt-12">
<div className="main-container md:mt-18 z-2 relative mb-14 mt-12">
<div className="relative flex flex-col-reverse md:flex-row md:gap-8">
<div className="md:w-[890px] md:pt-8 lg:w-[690px]">
<h1 className="mb-8 text-5xl leading-tight">
Expand Down
108 changes: 108 additions & 0 deletions components/front-page/Topics.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import Carousel from "components/ui/Carousel";
import { CmsTopicHeader } from "lib/cms/topics";
import { chunk, isObject, isString } from "lodash-es";
import Image from "next/image";
import Link from "next/link";
import { useRouter } from "next/router";

export const Topics = ({
topics,
imagePlaceholders,
selectedTopic,
onClick,
}: {
topics: CmsTopicHeader[];
imagePlaceholders: string[];
selectedTopic?: CmsTopicHeader | string;
onClick?: (topic: CmsTopicHeader) => void;
}) => {
const router = useRouter();

return (
<>
<div className="hidden w-full gap-3 md:flex">
{topics.map((topic, index) => (
<Link
key={index}
href={`/topics/${topic.slug}`}
className={`
ztg-transition flex flex-1 cursor-pointer items-center gap-4 rounded-lg p-3 transition-all md:max-w-sm md:hover:scale-[1.015]
${
(isString(selectedTopic) && selectedTopic === topic.slug) ||
(isObject(selectedTopic) && selectedTopic.slug === topic.slug)
? "bg-gray-200"
: "bg-white"
}
`}
onClick={(e) => {
if (onClick) {
e.preventDefault();
onClick(topic);
} else {
router.push(`/topics/${topic.slug}`);
}
}}
>
<div className="relative h-10 w-10">
<Image
key={index}
priority
src={topic.thumbnail ?? ""}
alt={`Image for topic ${topic.title}`}
placeholder="blur"
blurDataURL={imagePlaceholders[index]}
fill
sizes="100vw"
className="rounded-lg object-cover"
style={{
objectFit: "cover",
}}
/>
</div>
<div>
<h3 className="font-base text-sm text-gray-800">{topic.title}</h3>
</div>
</Link>
))}
</div>
<div className="relative block w-full md:hidden">
<Carousel
options={{ align: "start", duration: 10 }}
slides={chunk(topics, 3).map((topics, index) => (
<div className="flex gap-2">
{topics.map((topic, index) => (
<Link
href={`/topics/${topic.slug}`}
key={index}
className="flex flex-1 cursor-pointer items-center gap-4 rounded-lg bg-white p-2 transition-all hover:bg-gray-200 hover:bg-opacity-30 md:max-w-sm"
>
<div className="relative h-10 w-10">
<Image
key={index}
priority
src={topic.thumbnail ?? ""}
alt={`Image for topic ${topic.title}`}
placeholder="blur"
blurDataURL={imagePlaceholders[index]}
fill
sizes="100vw"
className="rounded-lg object-cover"
style={{
objectFit: "cover",
}}
/>
</div>
<div>
<h3 className="font-base text-sm text-gray-800">
{topic.title}
</h3>
</div>
</Link>
))}
</div>
))}
/>
</div>
</>
);
};
17 changes: 16 additions & 1 deletion components/markets/MarketsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,13 @@ import useMarketsUrlQuery from "lib/hooks/useMarketsUrlQuery";
import { filterTypes } from "lib/constants/market-filter";
import { ZTG } from "lib/constants";
import { useMarketsStats } from "lib/hooks/queries/useMarketsStats";
import { CmsTopicHeader } from "lib/cms/topics";
import { Topics } from "components/front-page/Topics";

export type MarketsListProps = {
className?: string;
cmsTopics: CmsTopicHeader[];
cmsTopicPlaceholders: string[];
};

const useChangeQuery = (
Expand Down Expand Up @@ -55,7 +59,11 @@ const useChangeQuery = (
}, [withLiquidityOnly]);
};

const MarketsList = ({ className = "" }: MarketsListProps) => {
const MarketsList = ({
className = "",
cmsTopics,
cmsTopicPlaceholders,
}: MarketsListProps) => {
const [filters, setFilters] = useState<MarketFilter[]>();
const [orderBy, setOrderBy] = useState<MarketsOrderBy>();
const [withLiquidityOnly, setWithLiquidityOnly] = useState<boolean>();
Expand Down Expand Up @@ -96,11 +104,18 @@ const MarketsList = ({ className = "" }: MarketsListProps) => {
data-testid="marketsList"
id={"market-list"}
>
{process.env.NEXT_PUBLIC_SHOW_TOPICS === "true" && (
<div className="flex gap-2 py-8">
<Topics topics={cmsTopics} imagePlaceholders={cmsTopicPlaceholders} />
</div>
)}

<MarketFilterSelection
onFiltersChange={setFilters}
onOrderingChange={setOrderBy}
onWithLiquidityOnlyChange={setWithLiquidityOnly}
/>

<div className="grid grid-cols-1 gap-7 md:grid-cols-2 lg:grid-cols-3">
{markets?.map((market) => {
const volume = market.volume;
Expand Down
2 changes: 1 addition & 1 deletion components/markets/market-card/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ export const MarketCard = ({
<div
data-testid={`marketCard-${marketId}`}
className={`ztg-transition group relative flex min-w-full flex-col
rounded-[10px] bg-white p-5 md:min-w-[calc(50%-8px)] md:hover:scale-[1.035] lg:min-w-[calc(100%/3-9.67px)] ${className}`}
rounded-[10px] bg-white p-5 md:min-w-[calc(50%-8px)] md:hover:scale-[1.015] lg:min-w-[calc(100%/3-9.67px)] ${className}`}
>
<Link
href={`/markets/${marketId}`}
Expand Down
106 changes: 106 additions & 0 deletions components/ui/Carousel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import React, { ReactNode, useCallback, useEffect, useState } from "react";
import { EmblaCarouselType, EmblaOptionsType } from "embla-carousel";
import useEmblaCarousel from "embla-carousel-react";
import { ChevronLeft, ChevronRight } from "react-feather";

type CarouselProps = {
slides: Array<ReactNode>;
options?: EmblaOptionsType;
};

const Carousel: React.FC<CarouselProps> = (props) => {
const { slides, options } = props;
const [emblaRef, emblaApi] = useEmblaCarousel(options);

const {
prevBtnDisabled,
nextBtnDisabled,
onPrevButtonClick,
onNextButtonClick,
} = usePrevNextButtons(emblaApi);

return (
<div>
<div className="mb-2 flex items-center justify-end gap-1">
<button
onClick={onPrevButtonClick}
className={`ztg-transition ml-[12px] mr-[8px] flex h-[18px] w-[18px] items-center justify-center rounded-full ${
prevBtnDisabled ? "text-pastel-blue opacity-30" : " text-gray-700"
}`}
disabled={prevBtnDisabled}
>
<ChevronLeft className="relative right-[1px]" />
</button>
<button
onClick={onNextButtonClick}
className={`ztg-transition flex h-[18px] w-[18px] items-center justify-center rounded-full ${
nextBtnDisabled ? "text-pastel-blue opacity-30" : "text-gray-700"
}`}
disabled={nextBtnDisabled}
>
<ChevronRight className="relative left-[1px]" />
</button>
</div>

<div className="embla">
<div className="embla__viewport" ref={emblaRef}>
<div className="embla__container">
{slides.map((slide, index) => (
<div className="embla__slide" key={index}>
<div className="embla__slide__number">
<span>{slide}</span>
</div>
</div>
))}
</div>
</div>
</div>
</div>
);
};

type UsePrevNextButtonsType = {
prevBtnDisabled: boolean;
nextBtnDisabled: boolean;
onPrevButtonClick: () => void;
onNextButtonClick: () => void;
};

export const usePrevNextButtons = (
emblaApi: EmblaCarouselType | undefined,
): UsePrevNextButtonsType => {
const [prevBtnDisabled, setPrevBtnDisabled] = useState(true);
const [nextBtnDisabled, setNextBtnDisabled] = useState(true);

const onPrevButtonClick = useCallback(() => {
if (!emblaApi) return;
emblaApi.scrollPrev();
}, [emblaApi]);

const onNextButtonClick = useCallback(() => {
if (!emblaApi) return;
emblaApi.scrollNext();
}, [emblaApi]);

const onSelect = useCallback((emblaApi: EmblaCarouselType) => {
setPrevBtnDisabled(!emblaApi.canScrollPrev());
setNextBtnDisabled(!emblaApi.canScrollNext());
}, []);

useEffect(() => {
if (!emblaApi) return;

onSelect(emblaApi);
emblaApi.on("reInit", onSelect);
emblaApi.on("select", onSelect);
}, [emblaApi, onSelect]);

return {
prevBtnDisabled,
nextBtnDisabled,
onPrevButtonClick,
onNextButtonClick,
};
};

export default Carousel;
4 changes: 3 additions & 1 deletion layouts/DefaultLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const greyBackgroundPageRoutes = [
"/markets",
"/create-account",
"/deposit",
"/topics",
];

const DefaultLayout: FC<PropsWithChildren> = ({ children }) => {
Expand All @@ -47,7 +48,8 @@ const DefaultLayout: FC<PropsWithChildren> = ({ children }) => {
return (
<div
className={`relative min-h-screen justify-evenly ${
greyBackgroundPageRoutes.includes(router.pathname)
greyBackgroundPageRoutes.includes(router.pathname) ||
router.pathname.match("topics")
? "bg-light-gray"
: ""
}`}
Expand Down
4 changes: 4 additions & 0 deletions lib/cms/sanity/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,7 @@ const config: ClientConfig = {
};

export const sanity = createClient(config);

import imageUrlBuilder from "@sanity/image-url";

export const sanityImageBuilder = imageUrlBuilder(sanity);
Loading

0 comments on commit d99e645

Please sign in to comment.