-
-
+
+
+
+
+
{formatPrice(price, 7)}
+
+
+
+ {formatPercentage(priceChangePercentage24h)}
+ {isTrendingUp ? : }
+
+
- {/* Price */}
- <>
-
-
{formatPrice(price, 7)}
- {/* 24h Change */}
-
-
- {formatPercentage(priceChangePercentage24h)}
- {isTrendingUp ? : }
-
-
-
+
+
+ Market Cap Rank
+ #{rank}
+
- {/* Market Stats */}
-
-
- Market Cap Rank
- #{rank}
-
-
- Volume 24h:
- {formatPrice(volume24)}
-
-
- >
+
+ Volume 24h:
+ {formatPrice(volume24)}
+
);
diff --git a/components/CoinDetailCard.tsx b/components/CoinDetailCard.tsx
deleted file mode 100644
index 9c16771..0000000
--- a/components/CoinDetailCard.tsx
+++ /dev/null
@@ -1,32 +0,0 @@
-import { ArrowUpRight } from 'lucide-react';
-import Link from 'next/link';
-
-interface CoinDetailCardProps {
- label: string;
- value: string | number;
- link?: string;
- linkText?: string;
-}
-
-export default function CoinDetailCard({
- label,
- value,
- link,
- linkText,
-}: CoinDetailCardProps) {
- return (
-
-
{label}
- {link ? (
-
-
- {linkText || label}
-
-
-
- ) : (
-
{value}
- )}
-
- );
-}
diff --git a/components/CoinDetailsSection.tsx b/components/CoinDetailsSection.tsx
deleted file mode 100644
index dbd221e..0000000
--- a/components/CoinDetailsSection.tsx
+++ /dev/null
@@ -1,58 +0,0 @@
-import CoinDetailCard from './CoinDetailCard';
-import { formatPrice } from '@/lib/utils';
-
-export const CoinDetailsSection = ({
- coinData,
-}: {
- coinData: CoinDetailsData;
-}) => {
- const coinDetails = [
- {
- label: 'Market Cap',
- value: formatPrice(coinData.market_data.market_cap.usd),
- },
- {
- label: 'Market Cap Rank',
- value: `# ${coinData.market_cap_rank}`,
- },
- {
- label: 'Total Volume',
- value: formatPrice(coinData.market_data.total_volume.usd),
- },
- {
- label: 'Website',
- value: '-',
- link: coinData.links.homepage[0],
- linkText: 'Website',
- },
- {
- label: 'Explorer',
- value: '-',
- link: coinData.links.blockchain_site[0],
- linkText: 'Explorer',
- },
- {
- label: 'Community Link',
- value: '-',
- link: coinData.links.subreddit_url,
- linkText: 'Community',
- },
- ];
-
- return (
-
-
Coin Details
-
- {coinDetails.map((detail, index) => (
-
- ))}
-
-
- );
-};
diff --git a/components/CoinHeader.tsx b/components/CoinHeader.tsx
index 783e3ab..cea1688 100644
--- a/components/CoinHeader.tsx
+++ b/components/CoinHeader.tsx
@@ -1,9 +1,10 @@
'use client';
-import { cn, formatPercentage, formatPrice } from '@/lib/utils';
-import { TrendingDown, TrendingUp } from 'lucide-react';
import Image from 'next/image';
+import { TrendingDown, TrendingUp } from 'lucide-react';
+
import { Badge } from './ui/badge';
+import { cn, formatPercentage, formatPrice } from '@/lib/utils';
export default function CoinHeader({
livePriceChangePercentage24h,
@@ -14,83 +15,74 @@ export default function CoinHeader({
priceChange24h,
}: LiveCoinHeaderProps) {
const isTrendingUp = livePriceChangePercentage24h > 0;
+ const isThirtyDayUp = priceChangePercentage30d > 0;
+ const isPriceChangeUp = priceChange24h > 0;
+
+ const stats = [
+ {
+ label: 'Today',
+ value: livePriceChangePercentage24h,
+ isUp: isTrendingUp,
+ formatter: formatPercentage,
+ showIcon: true,
+ },
+ {
+ label: '30 Days',
+ value: priceChangePercentage30d,
+ isUp: isThirtyDayUp,
+ formatter: formatPercentage,
+ showIcon: true,
+ },
+ {
+ label: 'Price Change (24h)',
+ value: priceChange24h,
+ isUp: isPriceChangeUp,
+ formatter: formatPrice,
+ showIcon: false,
+ },
+ ];
return (
-
-
-
{name}
-
-
-
-
{formatPrice(livePrice)}
-
- {formatPercentage(livePriceChangePercentage24h)}
- {isTrendingUp ? : }
- (24h)
-
-
+
+
+ ))}
+
);
}
diff --git a/components/CoinsPagination.tsx b/components/CoinsPagination.tsx
index f23847b..78065c3 100644
--- a/components/CoinsPagination.tsx
+++ b/components/CoinsPagination.tsx
@@ -9,91 +9,48 @@ import {
PaginationNext,
PaginationPrevious,
} from '@/components/ui/pagination';
-import { cn } from '@/lib/utils';
+import { buildPageNumbers, cn, ELLIPSIS } from '@/lib/utils';
export default function CoinsPagination({
currentPage,
totalPages,
hasMorePages,
-}: {
- currentPage: number;
- totalPages: number;
- hasMorePages: boolean;
-}) {
+}: Pagination) {
const router = useRouter();
const handlePageChange = (page: number) => {
router.push(`/coins?page=${page}`);
};
- // Generate page numbers to display
- const getPageNumbers = () => {
- const pages: (number | string)[] = [];
- const showPages = 5; // Number of page buttons to show
-
- if (totalPages <= showPages) {
- // Show all pages if total is less than or equal to showPages
- for (let i = 1; i <= totalPages; i++) {
- pages.push(i);
- }
- } else {
- pages.push(1);
-
- // Calculate start and end of middle pages
- const start = Math.max(2, currentPage - 1);
- const end = Math.min(totalPages - 1, currentPage + 1);
-
- // Add ellipsis after first page if needed
- if (start > 2) {
- pages.push('...');
- }
-
- // Add middle pages
- for (let i = start; i <= end; i++) {
- pages.push(i);
- }
-
- // Add ellipsis before last page if needed
- if (end < totalPages - 1) {
- pages.push('...');
- }
-
- pages.push(totalPages);
- }
-
- return pages;
- };
-
- const pageNumbers = getPageNumbers();
+ const pageNumbers = buildPageNumbers(currentPage, totalPages);
const isLastPage = !hasMorePages || currentPage === totalPages;
return (
-
-
-
+