Skip to content

Commit

Permalink
Merge pull request #5 from bonz88/feat/carousel-coins
Browse files Browse the repository at this point in the history
Feat/carousel-coins
  • Loading branch information
bonz88 committed Feb 26, 2024
2 parents b5583d1 + 63862ad commit 92f1e7b
Show file tree
Hide file tree
Showing 8 changed files with 462 additions and 2 deletions.
13 changes: 12 additions & 1 deletion next.config.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
/** @type {import('next').NextConfig} */
const nextConfig = {};
const nextConfig = {
images: {
remotePatterns: [
{
protocol: "https",
hostname: "assets.coingecko.com",
port: "",
pathname: "/coins/**",
},
],
},
};

export default nextConfig;
26 changes: 26 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.0",
"cmdk": "^0.2.1",
"embla-carousel-react": "^8.0.0",
"lucide-react": "^0.323.0",
"next": "14.1.0",
"next-themes": "^0.2.1",
Expand Down
88 changes: 88 additions & 0 deletions src/app/components/CarouselCoins.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
"use client";
import * as React from "react";
import { useEffect } from "react";
import { useDispatch } from "react-redux";
import Image from "next/image";
import { AppDispatch, useAppSelector } from "../../redux/store";
import { getCoinData } from "../../redux/features/coinInfoSlice";
import { ChevronUpIcon } from "../icons/ChevronUpIcon";
import { ChevronDownIcon } from "../icons/ChevronDownIcon";
import {
Carousel,
CarouselContent,
CarouselItem,
CarouselNext,
CarouselPrevious,
} from "../components/ui/carousel";

export default function CarouselCoins() {
const dispatch: AppDispatch = useDispatch();
const { data, isLoading, hasError } = useAppSelector(
(state) => state.coinData
);
const currencyCode = useAppSelector(
(state) => state.currency.currentCurrency.code
);

useEffect(() => {
dispatch(getCoinData(currencyCode));
}, [dispatch, currencyCode]);

if (isLoading) return <div>Loading...</div>;
if (hasError) return <div>Error loading the data.</div>;

return (
<Carousel
opts={{
align: "start",
}}
className="w-full"
>
<CarouselContent>
{data.map((coin) => (
<CarouselItem
key={coin.id}
className="sm:basis-1/2 md:basis-1/3 lg:basis-1/4 xl:basis-1/5"
>
<div className="h-[88px] dark:bg-[#191925] bg-[#FFFFFF] flex items-center rounded-lg cursor-pointer">
<div className="px-4">
<Image
src={coin.image}
alt={coin.name}
width={32}
height={32}
/>
</div>
<div className="flex flex-col pr-4">
<h2 className="text-[16px] dark:text-white text-[#181825] font-medium leading-6">
{coin.name} ({coin.symbol.toUpperCase()})
</h2>
<div className="flex items-center gap-2">
<span className="dark:text-[#D1D1D1] text-[#424286] text-sm font-normal leading-4">
{coin.current_price} {currencyCode.toUpperCase()}
</span>
{coin.price_change_percentage_24h > 0 ? (
<ChevronUpIcon />
) : (
<ChevronDownIcon />
)}
<span
className={`text-sm font-normal ${
coin.price_change_percentage_24h < 0
? "text-[#FD2263]"
: "text-[#00F0E2]"
}`}
>
{Math.abs(coin.price_change_percentage_24h).toFixed(2)}%
</span>
</div>
</div>
</div>
</CarouselItem>
))}
</CarouselContent>
<CarouselPrevious className="dark:bg-[#6161D6] dark:bg-opacity-50 bg-[#6161D6] bg-opacity-50 dark:hover:bg-[#6161D6] hover:bg-[#6161D6] hover:bg-opacity-70" />
<CarouselNext className="dark:bg-[#6161D6] dark:bg-opacity-50 bg-[#6161D6] bg-opacity-50 dark:hover:bg-[#6161D6] hover:bg-[#6161D6] hover:bg-opacity-70" />
</Carousel>
);
}

0 comments on commit 92f1e7b

Please sign in to comment.