Improve shipping locations table
This commit is contained in:
@@ -629,30 +629,107 @@ const ShippingDetails = ({ data }) => {
|
||||
|
||||
<div>
|
||||
<h3 className="text-lg font-medium mb-4">Shipping Locations</h3>
|
||||
<div className="max-h-[400px] overflow-y-auto pr-2">
|
||||
<div className="space-y-2">
|
||||
{locations.byState?.map((location) => (
|
||||
<div
|
||||
key={location.state}
|
||||
className="flex justify-between items-center p-3 bg-gray-50 dark:bg-gray-800 rounded-lg"
|
||||
>
|
||||
<div className="space-y-6">
|
||||
{/* Country summary cards */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
{locations.byCountry?.slice(0, 3).map((country) => (
|
||||
<Card key={country.country} className="p-4">
|
||||
<div className="flex justify-between items-start mb-2">
|
||||
<div>
|
||||
<h4 className="font-semibold">{country.country}</h4>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
{country.states.length} states/regions
|
||||
</p>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<div className="font-semibold">{country.count.toLocaleString()}</div>
|
||||
<div className="text-sm text-muted-foreground">
|
||||
{country.percentage.toFixed(1)}%
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="h-2 bg-muted rounded-full overflow-hidden">
|
||||
<div
|
||||
className="h-full bg-teal-500"
|
||||
style={{ width: `${country.percentage}%` }}
|
||||
/>
|
||||
</div>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* States grid */}
|
||||
<div className="rounded-lg border bg-card">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 divide-y md:divide-y-0 md:divide-x divide-border">
|
||||
{/* Left column */}
|
||||
<div className="p-4 space-y-3">
|
||||
<div className="flex justify-between items-center text-sm font-medium text-muted-foreground px-2">
|
||||
<span>Top States</span>
|
||||
<span>Orders</span>
|
||||
</div>
|
||||
{locations.byState?.slice(0, Math.ceil(locations.byState.length / 2)).map((location) => (
|
||||
<div
|
||||
key={`${location.state}-${location.country}`}
|
||||
className="flex justify-between items-center p-2 hover:bg-accent rounded-lg transition-colors"
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="font-medium">{location.state}</span>
|
||||
<span className="text-sm text-muted-foreground ml-2">
|
||||
<span className="text-xs text-muted-foreground">
|
||||
{location.country}
|
||||
</span>
|
||||
</div>
|
||||
<div className="text-sm">
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="font-medium">
|
||||
{location.count.toLocaleString()}
|
||||
</span>
|
||||
<span className="text-muted-foreground ml-2">
|
||||
({location.percentage.toFixed(1)}%)
|
||||
<span className="text-xs text-muted-foreground w-12 text-right">
|
||||
{location.percentage.toFixed(1)}%
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Right column */}
|
||||
<div className="p-4 space-y-3">
|
||||
<div className="flex justify-between items-center text-sm font-medium text-muted-foreground px-2">
|
||||
<span>Additional States</span>
|
||||
<span>Orders</span>
|
||||
</div>
|
||||
{locations.byState?.slice(Math.ceil(locations.byState.length / 2)).map((location) => (
|
||||
<div
|
||||
key={`${location.state}-${location.country}`}
|
||||
className="flex justify-between items-center p-2 hover:bg-accent rounded-lg transition-colors"
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="font-medium">{location.state}</span>
|
||||
<span className="text-xs text-muted-foreground">
|
||||
{location.country}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="font-medium">
|
||||
{location.count.toLocaleString()}
|
||||
</span>
|
||||
<span className="text-xs text-muted-foreground w-12 text-right">
|
||||
{location.percentage.toFixed(1)}%
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Summary footer */}
|
||||
<div className="flex justify-between items-center text-sm text-muted-foreground px-2">
|
||||
<span>
|
||||
Showing all {locations.byState?.length || 0} states across {locations.byCountry?.length || 0} countries
|
||||
</span>
|
||||
<span>
|
||||
Total Orders: {shippedCount.toLocaleString()}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1299,7 +1376,7 @@ const StatCards = ({
|
||||
} finally {
|
||||
setDetailDataLoading(prev => ({ ...prev, [metric]: false }));
|
||||
}
|
||||
}, [timeRange, startDate, endDate, shouldUseLast30Days, setCacheData, getCacheData]);
|
||||
}, [timeRange, startDate, endDate]);
|
||||
// Corrected preloadDetailData function
|
||||
const preloadDetailData = useCallback(() => {
|
||||
const metrics = [
|
||||
|
||||
Reference in New Issue
Block a user