diff --git a/frontend/app/(sidebar)/layout.tsx b/frontend/app/(sidebar)/layout.tsx
index 3e79b13..98a524b 100644
--- a/frontend/app/(sidebar)/layout.tsx
+++ b/frontend/app/(sidebar)/layout.tsx
@@ -7,6 +7,7 @@ import { SidebarInset, SidebarProvider, SidebarTrigger } from "@/components/ui/s
import DynamicBreadcrumb from "./dynamic-breadcrumb";
import { extractRoute } from "@/lib/utils";
import { usePathname } from "next/navigation";
+import { Toaster } from "@/components/ui/sonner";
export default function AppLayout({
children,
@@ -29,6 +30,7 @@ export default function AppLayout({
{children}
+
);
diff --git a/frontend/app/(sidebar)/marketplace/CustomTooltip.tsx b/frontend/app/(sidebar)/marketplace/CustomTooltip.tsx
new file mode 100644
index 0000000..60fdec8
--- /dev/null
+++ b/frontend/app/(sidebar)/marketplace/CustomTooltip.tsx
@@ -0,0 +1,22 @@
+"use client";
+
+import { Card } from "@/components/ui/card";
+
+interface CustomTooltipProps {
+ active?: boolean;
+ payload?: { value: number }[];
+ label?: string;
+}
+
+export default function CustomTooltip({ active, payload, label }: CustomTooltipProps) {
+ if (active && payload && payload.length) {
+ return (
+
+ {label}
+ Price: ${payload[0].value}
+ {payload[1] && Volume: {payload[1].value} units
}
+
+ );
+ }
+ return null;
+}
diff --git a/frontend/app/(sidebar)/marketplace/DemandAnalysis.tsx b/frontend/app/(sidebar)/marketplace/DemandAnalysis.tsx
new file mode 100644
index 0000000..41cfd0d
--- /dev/null
+++ b/frontend/app/(sidebar)/marketplace/DemandAnalysis.tsx
@@ -0,0 +1,38 @@
+"use client";
+
+import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
+import { Progress } from "@/components/ui/progress";
+import MarketOpportunity from "./MarketOpportunity";
+import { IMarketComparison } from "@/lib/marketData";
+
+interface DemandAnalysisProps {
+ selectedCrop: string;
+ marketComparison: IMarketComparison[];
+}
+
+export default function DemandAnalysis({ selectedCrop, marketComparison }: DemandAnalysisProps) {
+ return (
+
+
+
+ Demand Forecast
+ Projected demand for {selectedCrop} over the next 30 days
+
+
+
+ {marketComparison.map((market) => (
+
+
+ {market.name}
+ {market.demand}%
+
+
+
+ ))}
+
+
+
+
+
+ );
+}
diff --git a/frontend/app/(sidebar)/marketplace/MarketComparisonTab.tsx b/frontend/app/(sidebar)/marketplace/MarketComparisonTab.tsx
new file mode 100644
index 0000000..95bfcb8
--- /dev/null
+++ b/frontend/app/(sidebar)/marketplace/MarketComparisonTab.tsx
@@ -0,0 +1,95 @@
+"use client";
+
+import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer, Cell } from "recharts";
+import { Table, TableBody, TableCaption, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
+import { Button } from "@/components/ui/button";
+import { ArrowUpRight, ArrowDownRight, ChevronRight } from "lucide-react";
+import { Progress } from "@/components/ui/progress";
+import { IMarketComparison } from "@/lib/marketData";
+
+interface MarketComparisonTabProps {
+ marketComparison: IMarketComparison[];
+ selectedCrop: string;
+ onSelectCrop: (crop: string) => void;
+}
+
+export default function MarketComparisonTab({
+ marketComparison,
+ selectedCrop,
+ onSelectCrop,
+}: MarketComparisonTabProps) {
+ return (
+ <>
+
+
+
+
+
+ `$${value}`} />
+
+
+
+ {marketComparison.map((entry, index) => (
+ | item.price)) ? "#15803d" : "#16a34a"}
+ />
+ ))}
+ |
+
+
+
+
+
+
+
+ Market comparison for {selectedCrop} as of {new Date().toLocaleDateString()}
+
+
+
+ Market
+ Price
+ Demand
+ Price Difference
+ Action
+
+
+
+ {marketComparison.map((market) => {
+ const avgPrice = marketComparison.reduce((sum, m) => sum + m.price, 0) / marketComparison.length;
+ const priceDiff = (((market.price - avgPrice) / avgPrice) * 100).toFixed(1);
+ const isPriceHigh = Number.parseFloat(priceDiff) > 0;
+
+ return (
+ onSelectCrop(market.name)}>
+ {market.name}
+ ${market.price.toFixed(2)}
+
+
+
+
+
+ {isPriceHigh ?
:
}
+ {priceDiff}%
+
+
+
+
+
+
+ );
+ })}
+
+
+
+ >
+ );
+}
diff --git a/frontend/app/(sidebar)/marketplace/MarketOpportunity.tsx b/frontend/app/(sidebar)/marketplace/MarketOpportunity.tsx
new file mode 100644
index 0000000..045f017
--- /dev/null
+++ b/frontend/app/(sidebar)/marketplace/MarketOpportunity.tsx
@@ -0,0 +1,76 @@
+"use client";
+
+import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
+import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
+import { Badge } from "@/components/ui/badge";
+import { Button } from "@/components/ui/button";
+import { Progress } from "@/components/ui/progress";
+import { Separator } from "@/components/ui/separator";
+import { ArrowUpRight, ArrowDownRight, TrendingUp, MapPin, AlertCircle } from "lucide-react";
+import { IMarketComparison } from "@/lib/marketData";
+
+interface MarketOpportunityProps {
+ crop: string;
+ data: IMarketComparison[];
+}
+
+export default function MarketOpportunity({ crop, data }: MarketOpportunityProps) {
+ const highestPrice = Math.max(...data.map((item) => item.price));
+ const bestMarket = data.find((item) => item.price === highestPrice);
+ const highestDemand = Math.max(...data.map((item) => item.demand));
+ const highDemandMarket = data.find((item) => item.demand === highestDemand);
+
+ return (
+
+
+
+
+ Sales Opportunity for {crop}
+
+ Based on current market conditions
+
+
+
+
+
Best Price Opportunity
+
+
+
${bestMarket?.price}
+
{bestMarket?.name}
+
+
+ {Math.round((bestMarket!.price / (highestPrice - 1)) * 100)}% above average
+
+
+
+
+
+
+
+
Highest Demand
+
+
+
{highDemandMarket?.name}
+
+
+
{highDemandMarket?.demand}% demand
+
+
+
+
+
+
+
+
+ Recommendation
+
+ Consider selling your {crop} at {bestMarket?.name} within the next 7 days to maximize profit.
+
+
+
+
+
+ );
+}
diff --git a/frontend/app/(sidebar)/marketplace/MarketPriceTable.tsx b/frontend/app/(sidebar)/marketplace/MarketPriceTable.tsx
new file mode 100644
index 0000000..593b8d3
--- /dev/null
+++ b/frontend/app/(sidebar)/marketplace/MarketPriceTable.tsx
@@ -0,0 +1,88 @@
+"use client";
+
+import { Table, TableBody, TableHeader, TableRow, TableHead, TableCell } from "@/components/ui/table";
+import { Card, CardHeader, CardTitle, CardDescription, CardContent } from "@/components/ui/card";
+import { Skeleton } from "@/components/ui/skeleton";
+import { ArrowUpRight, ArrowDownRight } from "lucide-react";
+import { IMarketData, ITrend } from "@/lib/marketData";
+
+interface MarketPriceTableProps {
+ marketData: IMarketData[];
+ isLoading: boolean;
+ onSelectCrop: (crop: string) => void;
+}
+
+const getTrendColor = (trend: ITrend) => (trend.direction === "up" ? "text-green-600" : "text-red-600");
+
+const getTrendIcon = (trend: ITrend) =>
+ trend.direction === "up" ? (
+
+ ) : (
+
+ );
+
+export default function MarketPriceTable({ marketData, isLoading, onSelectCrop }: MarketPriceTableProps) {
+ if (isLoading) {
+ return (
+
+
+ Market Price Table
+ Comprehensive price data across all markets and crops
+
+
+
+
+
+
+
+
+
+
+ );
+ }
+
+ return (
+
+
+ Market Price Table
+ Comprehensive price data across all markets and crops
+
+
+
+
+
+
+ Crop
+ {marketData[0]?.marketPrices.map((market) => (
+ {market.market}
+ ))}
+ Average
+ Recommended
+
+
+
+ {marketData.map((crop) => (
+ onSelectCrop(crop.name)}>
+ {crop.name}
+ {crop.marketPrices.map((market) => (
+
+
+ ${market.price.toFixed(2)}
+ {getTrendIcon(market.trend)}
+
+
+ ))}
+ ${crop.averagePrice.toFixed(2)}
+ ${crop.recommendedPrice.toFixed(2)}
+
+ ))}
+
+
+
+
+
+ );
+}
diff --git a/frontend/app/(sidebar)/marketplace/MarketSummary.tsx b/frontend/app/(sidebar)/marketplace/MarketSummary.tsx
new file mode 100644
index 0000000..a558a28
--- /dev/null
+++ b/frontend/app/(sidebar)/marketplace/MarketSummary.tsx
@@ -0,0 +1,64 @@
+// components/MarketSummary.tsx
+"use client";
+
+import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
+import { ScrollArea } from "@/components/ui/scroll-area";
+import { Skeleton } from "@/components/ui/skeleton";
+import { ArrowUpRight, ArrowDownRight } from "lucide-react";
+import { Button } from "@/components/ui/button";
+import { IMarketData } from "@/lib/marketData";
+
+interface MarketSummaryProps {
+ marketData: IMarketData[];
+ isLoading: boolean;
+ onSelectCrop: (crop: string) => void;
+}
+
+export default function MarketSummary({ marketData, isLoading, onSelectCrop }: MarketSummaryProps) {
+ return (
+
+
+ Market Summary
+ Today's market overview
+
+
+ {isLoading ? (
+
+
+
+
+
+ ) : (
+
+
+ {marketData.slice(0, 5).map((crop) => (
+
+
+
{crop.name}
+
+
${crop.averagePrice.toFixed(2)}
+ {crop.marketPrices[0].trend.direction === "up" ? (
+
+
+ {crop.marketPrices[0].trend.value}%
+
+ ) : (
+
+
+ {crop.marketPrices[0].trend.value}%
+
+ )}
+
+
+
+
+ ))}
+
+
+ )}
+
+
+ );
+}
diff --git a/frontend/app/(sidebar)/marketplace/PriceAnalytics.tsx b/frontend/app/(sidebar)/marketplace/PriceAnalytics.tsx
new file mode 100644
index 0000000..9027c80
--- /dev/null
+++ b/frontend/app/(sidebar)/marketplace/PriceAnalytics.tsx
@@ -0,0 +1,130 @@
+"use client";
+
+import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from "recharts";
+import { Card, CardContent } from "@/components/ui/card";
+import { RefreshCw, Leaf, Calendar } from "lucide-react";
+import CustomTooltip from "./CustomTooltip";
+import { Badge } from "@/components/ui/badge";
+import { Progress } from "@/components/ui/progress";
+import { IHistoricalData } from "@/lib/marketData";
+
+interface PriceAnalyticsProps {
+ historicalData: IHistoricalData[];
+ isLoading: boolean;
+ selectedCrop: string;
+}
+
+export default function PriceAnalytics({ historicalData, isLoading, selectedCrop }: PriceAnalyticsProps) {
+ if (isLoading) {
+ return (
+
+
+
+
Loading market data...
+
+
+ );
+ }
+
+ const currentPrice = historicalData[historicalData.length - 1]?.price ?? 0;
+ const averagePrice = historicalData.reduce((sum, item) => sum + item.price, 0) / historicalData.length;
+ const recommendedPrice = currentPrice * 1.05;
+
+ return (
+ <>
+
+
+
+
+ {
+ const date = new Date(value);
+ return `${date.getMonth() + 1}/${date.getDate()}`;
+ }}
+ />
+ `$${value}`}
+ domain={["dataMin - 0.5", "dataMax + 0.5"]}
+ />
+
+ } />
+
+
+
+
+
+
+
+
+
+
+
+
+
Current Price
+
${currentPrice.toFixed(2)}
+
+
+
+
+
+
+
+
+
+
+
+
+
30-Day Average
+
${averagePrice.toFixed(2)}
+
+
+
+
+
+
+
+
+
+
+
+
+
Recommended Price
+
${recommendedPrice.toFixed(2)}
+
+
+ +5% margin
+
+
+
+
+
+ >
+ );
+}
diff --git a/frontend/app/(sidebar)/marketplace/PriceAnalyticsCard.tsx b/frontend/app/(sidebar)/marketplace/PriceAnalyticsCard.tsx
new file mode 100644
index 0000000..d6e1efd
--- /dev/null
+++ b/frontend/app/(sidebar)/marketplace/PriceAnalyticsCard.tsx
@@ -0,0 +1,114 @@
+// components/PriceAnalyticsCard.tsx
+"use client";
+
+import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
+import { Button } from "@/components/ui/button";
+import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
+import { RefreshCw } from "lucide-react";
+import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
+import PriceAnalytics from "./PriceAnalytics";
+import MarketComparisonTab from "./MarketComparisonTab";
+import DemandAnalysis from "./DemandAnalysis";
+
+interface PriceAnalyticsCardProps {
+ isLoading: boolean;
+ selectedCrop: string;
+ timeRange: string;
+ lastUpdated: Date;
+ onSelectCrop: (crop: string) => void;
+ onTimeRangeChange: (value: string) => void;
+ onRefresh: () => void;
+ historicalData: any;
+ marketComparison: any;
+}
+
+export default function PriceAnalyticsCard({
+ isLoading,
+ selectedCrop,
+ timeRange,
+ lastUpdated,
+ onSelectCrop,
+ onTimeRangeChange,
+ onRefresh,
+ historicalData,
+ marketComparison,
+}: PriceAnalyticsCardProps) {
+ return (
+
+
+
+
+ Price Analytics
+ Track price trends and market movements
+
+
+
+
+
+
+
+
+
+ {isLoading ? (
+
+
+
+
Loading market data...
+
+
+ ) : (
+
+
+
+ Price Trend
+
+
+ Market Comparison
+
+
+ Demand Analysis
+
+
+
+
+
+
+
+
+
+
+
+
+ )}
+
+
+ );
+}
diff --git a/frontend/app/(sidebar)/marketplace/TopOpportunities.tsx b/frontend/app/(sidebar)/marketplace/TopOpportunities.tsx
new file mode 100644
index 0000000..dcd2711
--- /dev/null
+++ b/frontend/app/(sidebar)/marketplace/TopOpportunities.tsx
@@ -0,0 +1,78 @@
+"use client";
+
+import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
+import { Skeleton } from "@/components/ui/skeleton";
+import { Badge } from "@/components/ui/badge";
+import { Button } from "@/components/ui/button";
+import { TrendingUp } from "lucide-react";
+import { IMarketData } from "@/lib/marketData";
+
+interface TopOpportunitiesProps {
+ marketData: IMarketData[];
+ isLoading: boolean;
+ onSelectCrop: (crop: string) => void;
+}
+
+export default function TopOpportunities({ marketData, isLoading, onSelectCrop }: TopOpportunitiesProps) {
+ if (isLoading) {
+ return (
+
+
+ Top Opportunities
+ Best selling opportunities today
+
+
+
+
+
+
+
+
+
+ );
+ }
+
+ return (
+
+
+ Top Opportunities
+ Best selling opportunities today
+
+
+
+ {marketData
+ .filter((crop) => crop.opportunity)
+ .slice(0, 3)
+ .map((crop) => {
+ const bestMarket = crop.marketPrices.reduce(
+ (best, current) => (current.price > best.price ? current : best),
+ crop.marketPrices[0]
+ );
+ return (
+
+
+
+
{crop.name}
+
+ {bestMarket.market} - ${bestMarket.price.toFixed(2)}
+
+
+
High Demand
+
+
+
+
+ Recommended
+
+
+
+
+ );
+ })}
+
+
+
+ );
+}
diff --git a/frontend/app/(sidebar)/marketplace/page.tsx b/frontend/app/(sidebar)/marketplace/page.tsx
index 33b21f0..f72e42e 100644
--- a/frontend/app/(sidebar)/marketplace/page.tsx
+++ b/frontend/app/(sidebar)/marketplace/page.tsx
@@ -2,26 +2,9 @@
import { useState, useEffect } from "react";
import { useSearchParams } from "next/navigation";
-import {
- Card,
- CardContent,
- CardDescription,
- CardHeader,
- CardTitle
-} from "@/components/ui/card";
-import {
- Tabs,
- TabsContent,
- TabsList,
- TabsTrigger
-} from "@/components/ui/tabs";
-import {
- Select,
- SelectContent,
- SelectItem,
- SelectTrigger,
- SelectValue
-} from "@/components/ui/select";
+import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
+import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
+import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import {
@@ -35,7 +18,7 @@ import {
ResponsiveContainer,
BarChart,
Bar,
- Cell
+ Cell,
} from "recharts";
import {
ArrowUpRight,
@@ -49,26 +32,14 @@ import {
Leaf,
BarChart3,
LineChartIcon,
- PieChart
+ PieChart,
} from "lucide-react";
import { Skeleton } from "@/components/ui/skeleton";
-import {
- Table,
- TableBody,
- TableCaption,
- TableCell,
- TableHead,
- TableHeader,
- TableRow
-} from "@/components/ui/table";
+import { Table, TableBody, TableCaption, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { Progress } from "@/components/ui/progress";
import { ScrollArea } from "@/components/ui/scroll-area";
import { Separator } from "@/components/ui/separator";
-import {
- Alert,
- AlertDescription,
- AlertTitle
-} from "@/components/ui/alert";
+import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
// Define types for market data
@@ -121,26 +92,10 @@ interface MarketOpportunityProps {
// Mock data for market prices
const generateMarketData = (): IMarketData[] => {
- const crops = [
- "Corn",
- "Wheat",
- "Soybeans",
- "Rice",
- "Potatoes",
- "Tomatoes",
- "Apples",
- "Oranges"
- ];
- const markets = [
- "National Market",
- "Regional Hub",
- "Local Market",
- "Export Market",
- "Wholesale Market"
- ];
+ const crops = ["Corn", "Wheat", "Soybeans", "Rice", "Potatoes", "Tomatoes", "Apples", "Oranges"];
+ const markets = ["National Market", "Regional Hub", "Local Market", "Export Market", "Wholesale Market"];
- const getRandomPrice = (base: number) =>
- Number((base + Math.random() * 2).toFixed(2));
+ const getRandomPrice = (base: number) => Number((base + Math.random() * 2).toFixed(2));
const getRandomDemand = () => Math.floor(Math.random() * 100);
const getRandomTrend = (): ITrend =>
Math.random() > 0.5
@@ -172,21 +127,18 @@ const generateMarketData = (): IMarketData[] => {
market,
price: getRandomPrice(basePrice),
demand: getRandomDemand(),
- trend: getRandomTrend()
+ trend: getRandomTrend(),
})),
averagePrice: getRandomPrice(basePrice - 0.5),
recommendedPrice: getRandomPrice(basePrice + 0.2),
demandScore: getRandomDemand(),
- opportunity: Math.random() > 0.7
+ opportunity: Math.random() > 0.7,
};
});
};
// Generate historical price data for a specific crop
-const generateHistoricalData = (
- crop: string,
- days = 30
-): IHistoricalData[] => {
+const generateHistoricalData = (crop: string, days = 30): IHistoricalData[] => {
const basePrice =
crop === "Corn"
? 4
@@ -216,7 +168,7 @@ const generateHistoricalData = (
data.push({
date: date.toISOString().split("T")[0],
price: Number(currentPrice.toFixed(2)),
- volume: Math.floor(Math.random() * 1000) + 200
+ volume: Math.floor(Math.random() * 1000) + 200,
});
}
@@ -224,16 +176,8 @@ const generateHistoricalData = (
};
// Generate market comparison data
-const generateMarketComparisonData = (
- crop: string
-): IMarketComparison[] => {
- const markets = [
- "National Market",
- "Regional Hub",
- "Local Market",
- "Export Market",
- "Wholesale Market"
- ];
+const generateMarketComparisonData = (crop: string): IMarketComparison[] => {
+ const markets = ["National Market", "Regional Hub", "Local Market", "Export Market", "Wholesale Market"];
const basePrice =
crop === "Corn"
? 4
@@ -254,26 +198,18 @@ const generateMarketComparisonData = (
return markets.map((market) => ({
name: market,
price: Number((basePrice + (Math.random() - 0.5) * 2).toFixed(2)),
- demand: Math.floor(Math.random() * 100)
+ demand: Math.floor(Math.random() * 100),
}));
};
// Custom tooltip for the price chart
-const CustomTooltip = ({
- active,
- payload,
- label
-}: CustomTooltipProps) => {
+const CustomTooltip = ({ active, payload, label }: CustomTooltipProps) => {
if (active && payload && payload.length) {
return (
{label}
Price: ${payload[0].value}
- {payload[1] && (
-
- Volume: {payload[1].value} units
-
- )}
+ {payload[1] && Volume: {payload[1].value} units
}
);
}
@@ -285,9 +221,7 @@ const MarketOpportunity = ({ crop, data }: MarketOpportunityProps) => {
const highestPrice = Math.max(...data.map((item) => item.price));
const bestMarket = data.find((item) => item.price === highestPrice);
const highestDemand = Math.max(...data.map((item) => item.demand));
- const highDemandMarket = data.find(
- (item) => item.demand === highestDemand
- );
+ const highDemandMarket = data.find((item) => item.demand === highestDemand);
return (
@@ -296,28 +230,19 @@ const MarketOpportunity = ({ crop, data }: MarketOpportunityProps) => {
Sales Opportunity for {crop}
-
- Based on current market conditions
-
+ Based on current market conditions
-
- Best Price Opportunity
-
+
Best Price Opportunity
-
- ${bestMarket?.price}
-
-
- {bestMarket?.name}
-
+
${bestMarket?.price}
+
{bestMarket?.name}
- {Math.round((bestMarket!.price / (highestPrice - 1)) * 100)}%
- above average
+ {Math.round((bestMarket!.price / (highestPrice - 1)) * 100)}% above average
@@ -325,22 +250,13 @@ const MarketOpportunity = ({ crop, data }: MarketOpportunityProps) => {
-
- Highest Demand
-
+
Highest Demand
-
- {highDemandMarket?.name}
-
+
{highDemandMarket?.name}
-
-
- {highDemandMarket?.demand}% demand
-
+
+
{highDemandMarket?.demand}% demand
@@ -374,17 +287,14 @@ export default function MarketplacePage() {
const [isLoading, setIsLoading] = useState(true);
const [marketData, setMarketData] = useState
([]);
const [historicalData, setHistoricalData] = useState([]);
- const [marketComparison, setMarketComparison] =
- useState([]);
+ const [marketComparison, setMarketComparison] = useState([]);
const [lastUpdated, setLastUpdated] = useState(new Date());
useEffect(() => {
setIsLoading(true);
const timer = setTimeout(() => {
setMarketData(generateMarketData());
- setHistoricalData(
- generateHistoricalData(selectedCrop, Number.parseInt(timeRange))
- );
+ setHistoricalData(generateHistoricalData(selectedCrop, Number.parseInt(timeRange)));
setMarketComparison(generateMarketComparisonData(selectedCrop));
setLastUpdated(new Date());
setIsLoading(false);
@@ -397,9 +307,7 @@ export default function MarketplacePage() {
setIsLoading(true);
setTimeout(() => {
setMarketData(generateMarketData());
- setHistoricalData(
- generateHistoricalData(selectedCrop, Number.parseInt(timeRange))
- );
+ setHistoricalData(generateHistoricalData(selectedCrop, Number.parseInt(timeRange)));
setMarketComparison(generateMarketComparisonData(selectedCrop));
setLastUpdated(new Date());
setIsLoading(false);
@@ -424,33 +332,18 @@ export default function MarketplacePage() {
-
- Marketplace Information
-
+
Marketplace Information
- Make informed decisions with real-time market data and price
- analytics
+ Make informed decisions with real-time market data and price analytics
-
@@ -460,9 +353,7 @@ export default function MarketplacePage() {
Price Analytics
-
- Track price trends and market movements
-
+ Track price trends and market movements