anonymous111110987654321's picture
Add 2 files
54b30eb verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Advanced AutoParts Tariff Dashboard</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<script>
tailwind.config = {
theme: {
extend: {
colors: {
primary: '#1d4ed8',
secondary: '#3b82f6',
accent: '#10b981',
dark: '#0f172a',
light: '#f8fafc'
},
animation: {
'pulse-slow': 'pulse 4s cubic-bezier(0.4, 0, 0.6, 1) infinite',
}
}
}
}
</script>
<style>
.grid-stack {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
grid-auto-rows: minmax(150px, auto);
gap: 1.5rem;
}
.scorecard {
transition: all 0.3s ease;
box-shadow: 0 4px 6px rgba(0,0,0,0.05);
}
.scorecard:hover {
transform: translateY(-5px);
box-shadow: 0 10px 15px rgba(0,0,0,0.1);
}
.chart-container {
transition: all 0.3s ease;
background-color: white;
border-radius: 0.75rem;
overflow: hidden;
box-shadow: 0 4px 6px rgba(0,0,0,0.05);
}
.chart-container:hover {
box-shadow: 0 10px 25px rgba(0,0,0,0.1);
transform: scale(1.005);
}
.filter-card {
transition: all 0.2s ease;
}
.filter-card:hover {
background-color: #eff6ff;
}
.sidebar {
scrollbar-width: thin;
scrollbar-color: #cbd5e1 #f1f5f9;
}
.sidebar::-webkit-scrollbar {
width: 6px;
}
.sidebar::-webkit-scrollbar-thumb {
background-color: #cbd5e1;
border-radius: 10px;
}
.animate-pulse {
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
.dropdown-menu {
transition: all 0.3s ease;
max-height: 0;
overflow: hidden;
}
.dropdown-menu.active {
max-height: 300px;
}
.data-table-container {
max-height: 500px;
overflow-y: auto;
}
table.data-table thead tr th {
position: sticky;
top: 0;
background-color: #f1f5f9;
z-index: 10;
}
.highlight-row {
background-color: #e0f2fe !important;
}
.fade-in {
animation: fadeIn 0.5s ease-in;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.notification {
position: fixed;
top: 80px;
right: 20px;
z-index: 1000;
transform: translateX(120%);
transition: transform 0.5s ease;
}
.notification.show {
transform: translateX(0);
}
.interactive-scorecard {
transition: all 0.3s ease;
position: relative;
overflow: hidden;
}
.interactive-scorecard::after {
content: '';
position: absolute;
top: -50%;
left: -50%;
width: 200%;
height: 200%;
background: linear-gradient(to bottom right, transparent 30%, rgba(255,255,255,0.2), transparent 70%);
transform: rotate(45deg);
transition: transform 0.7s ease;
pointer-events: none;
}
.interactive-scorecard:hover::after {
transform: rotate(45deg) translate(20px, 20px);
}
</style>
</head>
<body class="bg-gray-50 text-gray-800">
<!-- Notification -->
<div id="notification" class="notification bg-primary text-white px-5 py-3 rounded-lg shadow-lg">
<span class="mr-2"><i class="fas fa-sync-alt"></i> Dashboard updated with new filters!</span>
</div>
<!-- Header -->
<header class="bg-white shadow-sm sticky top-0 z-50">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex justify-between h-16 items-center">
<div class="flex items-center">
<div class="flex-shrink-0 flex items-center">
<i class="fas fa-car text-primary text-2xl mr-2"></i>
<h1 class="text-xl font-bold text-dark">AutoParts <span class="text-primary">301 Tariff</span> Dashboard</h1>
</div>
</div>
<div class="flex items-center space-x-4">
<div class="relative">
<i class="fas fa-bell text-gray-500 text-xl"></i>
<span class="absolute top-0 right-0 w-2 h-2 bg-red-500 rounded-full"></span>
</div>
<div class="flex items-center space-x-2">
<span class="text-sm text-gray-600">John Smith</span>
<div class="relative">
<div class="bg-gray-200 border-2 border-dashed rounded-xl w-10 h-10"></div>
</div>
</div>
</div>
</div>
</div>
</header>
<div class="flex h-[calc(100vh-4rem)]">
<!-- Sidebar with filters -->
<div class="sidebar w-72 bg-white border-r border-gray-200 overflow-y-auto py-6 px-4">
<h2 class="text-lg font-semibold mb-4 text-dark flex items-center">
<i class="fas fa-filter text-secondary mr-2"></i>
Data Filters
</h2>
<!-- Filter Group 1 -->
<div class="mb-6">
<button class="flex justify-between w-full py-2 text-left font-medium text-gray-700 dropdown-toggle">
<span>Date Range</span>
<i class="fas fa-chevron-down text-sm"></i>
</button>
<div class="dropdown-menu pl-2">
<div class="filter-card p-3 rounded-lg">
<label class="block text-sm font-medium mb-1">From Date</label>
<input id="fromDate" type="date" class="w-full px-3 py-2 border border-gray-300 rounded-md" value="2023-01-01">
</div>
<div class="filter-card p-3 rounded-lg">
<label class="block text-sm font-medium mb-1">To Date</label>
<input id="toDate" type="date" class="w-full px-3 py-2 border border-gray-300 rounded-md" value="2023-12-31">
</div>
</div>
</div>
<!-- Filter Group 2 -->
<div class="mb-6">
<button class="flex justify-between w-full py-2 text-left font-medium text-gray-700 dropdown-toggle">
<span>Supplier Details</span>
<i class="fas fa-chevron-down text-sm"></i>
</button>
<div class="dropdown-menu pl-2">
<div class="filter-card p-3 rounded-lg">
<label class="block text-sm font-medium mb-1">Supplier Name</label>
<select id="supplierName" class="w-full px-3 py-2 border border-gray-300 rounded-md">
<option value="all">All Suppliers</option>
<option>Global Auto Parts Co.</option>
<option>Precision Components Inc.</option>
<option>DynaParts International</option>
<option>EuroAuto Components</option>
<option>TechAuto Solutions</option>
</select>
</div>
<div class="filter-card p-3 rounded-lg">
<label class="block text-sm font-medium mb-1">Supplier Country</label>
<select id="supplierCountry" class="w-full px-3 py-2 border border-gray-300 rounded-md">
<option value="all">All Countries</option>
<option>China</option>
<option>Germany</option>
<option>Mexico</option>
<option>Japan</option>
<option>South Korea</option>
<option>India</option>
</select>
</div>
</div>
</div>
<!-- Filter Group 3 -->
<div class="mb-6">
<button class="flex justify-between w-full py-2 text-left font-medium text-gray-700 dropdown-toggle">
<span>Product Information</span>
<i class="fas fa-chevron-down text-sm"></i>
</button>
<div class="dropdown-menu pl-2">
<div class="filter-card p-3 rounded-lg">
<label class="block text-sm font-medium mb-1">Product Category</label>
<select id="productCategory" class="w-full px-3 py-2 border border-gray-300 rounded-md">
<option value="all">All Categories</option>
<option>Engine Components</option>
<option>Electrical Systems</option>
<option>Chassis Parts</option>
<option>Interior Components</option>
<option>Transmission Parts</option>
<option>Braking Systems</option>
</select>
</div>
<div class="filter-card p-3 rounded-lg">
<label class="block text-sm font-medium mb-1">HS Code</label>
<input id="hsCode" type="text" class="w-full px-3 py-2 border border-gray-300 rounded-md" placeholder="e.g., 8708.99">
</div>
<div class="filter-card p-3 rounded-lg">
<label class="block text-sm font-medium mb-1">Product Value Range ($)</label>
<div class="flex items-center space-x-2 mb-2">
<input id="minValue" type="number" class="w-1/2 px-3 py-2 border border-gray-300 rounded-md" placeholder="Min" value="500">
<span class="text-gray-500">to</span>
<input id="maxValue" type="number" class="w-1/2 px-3 py-2 border border-gray-300 rounded-md" placeholder="Max" value="10000">
</div>
</div>
</div>
</div>
<!-- Filter Group 4 -->
<div class="mb-6">
<button class="flex justify-between w-full py-2 text-left font-medium text-gray-700 dropdown-toggle">
<span>Tariff Details</span>
<i class="fas fa-chevron-down text-sm"></i>
</button>
<div class="dropdown-menu pl-2">
<div class="filter-card p-3 rounded-lg">
<label class="block text-sm font-medium mb-1">Tariff Rate</label>
<input id="tariffRate" type="range" min="0" max="25" step="1" value="10" class="w-full">
<div class="flex justify-between text-xs">
<span>0%</span>
<span id="tariffRateValue">10%</span>
<span>25%</span>
</div>
</div>
<div class="filter-card p-3 rounded-lg">
<label class="block text-sm font-medium mb-1">Tariff Status</label>
<select id="tariffStatus" class="w-full px-3 py-2 border border-gray-300 rounded-md">
<option value="all">All Status</option>
<option>Paid</option>
<option>Pending</option>
<option>Exempted</option>
<option>Under Appeal</option>
</select>
</div>
<div class="filter-card p-3 rounded-lg">
<label class="block text-sm font-medium mb-1">Tariff Amount Range ($)</label>
<div class="flex items-center space-x-2">
<input id="minTariffAmount" type="number" class="w-1/2 px-3 py-2 border border-gray-300 rounded-md" placeholder="Min" value="50">
<span class="text-gray-500">to</span>
<input id="maxTariffAmount" type="number" class="w-1/2 px-3 py-2 border border-gray-300 rounded-md" placeholder="Max" value="2500">
</div>
</div>
</div>
</div>
<!-- Filter Group 5 -->
<div class="mb-6">
<button class="flex justify-between w-full py-2 text-left font-medium text-gray-700 dropdown-toggle">
<span>Import Details</span>
<i class="fas fa-chevron-down text-sm"></i>
</button>
<div class="dropdown-menu pl-2">
<div class="filter-card p极3 rounded-lg">
<label class="block text-sm font-medium mb-1">Port of Entry</label>
<select id="portEntry" class="w-full px-3 py-2 border border-gray-300 rounded-md">
<option value="all">All Ports</option>
<option>Los Angeles</option>
<option>New York</option>
<option>Chicago</option>
<option>Houston</option>
<option>Miami</option>
</select>
</div>
<div class="filter-card p-3 rounded-lg">
<label class="block text-sm font-medium mb-1">Shipping Method</label>
<select id="shippingMethod" class="w-full px-3 py-2 border border-gray-300 rounded-md">
<option value="all">All Methods</option>
<option>Air Freight</option>
<option>Sea Freight</option>
<option>Ground Transport</option>
</select>
</div>
</div>
</div>
<div class="mt-8 flex flex-col space-y-3">
<button id="applyFilters" class="bg-primary hover:bg-blue-700 text-white py-2 px-4 rounded-lg font-medium flex items-center justify-center transition-all">
<i class="fas fa-sync-alt mr-2"></i> Apply Filters
</button>
<button id="resetFilters" class="border border-gray-300 py-2 px-4 rounded-lg font-medium hover:bg-gray-100 transition-all">
<i class="fas fa-redo mr-2"></i> Reset Filters
</button>
</div>
</div>
<!-- Main Content -->
<div class="flex-1 overflow-y-auto p-6">
<!-- Scorecards - Updated to 6 columns with new interactive cards -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-6 gap-5 mb-6">
<!-- Card 1 - Total Tariff Spend -->
<div class="scorecard bg-white rounded-xl p-5 shadow-sm border-l-4 border-primary md:col-span-3 lg:col-span-2">
<div class="flex items-center">
<div class="rounded-lg bg-blue-100 p-3 mr-4">
<i class="fas fa-dollar-sign text-blue-600 text-xl"></i>
</div>
<div>
<p class="text-gray-500 text-sm">Total Tariff Spend</p>
<h3 class="text-2xl font-bold text-gray-800">$2.84M</h3>
</div>
</div>
<p class="mt-3 text-sm text-gray-600">
<span class="text-green-500"><i class="fas fa-arrow-up"></i> 12.3%</span> from last quarter
</p>
</div>
<!-- Card 2 - Impacted Products -->
<div class="scorecard bg-white rounded-xl p-5 shadow-sm border-l-4 border-green-500 md:col-span-3 lg:col-span-2">
<div class="flex items-center">
<div class="rounded-lg bg-green-100 p-3 mr-4">
<i class="fas fa-boxes text-green-600 text-xl"></i>
</div>
<div>
<p class="text-gray-500 text-sm">Impacted Products</p>
<h3 class="text-2xl font-bold text-gray-800">187</h3>
</div>
</div>
<p class="mt-3 text-sm text-gray-600">
<span class="text-red-500"><i class="fas fa-arrow-down"></i> 5.2%</span> since last year
</p>
</div>
<!-- Card 3 - Active Suppliers -->
<div class="scorecard bg-white rounded-xl p-5 shadow-sm border-l-4 border-purple-500 md:col-span-3 lg:col-span-2">
<div class="flex items-center">
<div class="rounded-lg bg-purple-100 p-3 mr-4">
<i class="fas fa-industry text-purple-600 text-xl"></i>
</div>
<div>
<p class="text-gray-500 text-sm">Active Suppliers</p>
<h3 class="text-2xl font-bold text-gray-800">24</h3>
</div>
</div>
<p class="mt-3 text-sm text-gray-600">
<span class="text-green-500"><i class="fas fa-arrow-up"></i> 2 new</span> this quarter
</p>
</div>
<!-- Card 4 - Avg. Tariff Rate -->
<div class="scorecard bg-white rounded-xl p-5 shadow-sm border-l-4 border-yellow-500 md:col-span-3 lg:col-span-2">
<div class="flex items-center">
<div class="rounded-lg bg-yellow-100 p-3 mr-4">
<i class="fas fa-percentage text-yellow-600 text-xl"></i>
</div>
<div>
<p class="text-gray-500 text-sm">Avg. Tariff Rate</p>
<h3 class="text-2xl font-bold text-gray-800">8.7%</h3>
</div>
</div>
<p class="mt-3 text-sm text-gray-600">
<span class="text-red-500"><i class="fas fa-arrow-up"></i> 1.2%</span> since last month
</p>
</div>
<!-- New Card 5 - Cost Reduction Opportunities -->
<div class="scorecard bg-white rounded-xl p-5 shadow-sm border-l-4 border-indigo-500 md:col-span-3 lg:col-span-2 interactive-scorecard">
<div class="flex items-center">
<div class="rounded-lg bg-indigo-100 p-3 mr-4">
<i class="fas fa-chart-line text-indigo-600 text-xl"></i>
</div>
<div>
<p class="text-gray-500 text-sm">Cost Reduction Opportunities</p>
<h3 class="text-2xl font-bold text-gray-800">$420K</h3>
</div>
</div>
<div class="mt-2">
<div class="w-full bg-indigo-100 rounded-full h-2.5">
<div class="bg-indigo-600 h-2.5 rounded-full" style="width: 65%"></div>
</div>
</div>
<p class="mt-3 text-sm text-gray-600">
<span class="text-indigo-500"><i class="fas fa-info-circle"></i> Potential savings from optimization</span>
</p>
</div>
<!-- New Card 6 - Tariff Mitigation Success -->
<div class="scorecard bg-white rounded-xl p-5 shadow-sm border-l-4 border-pink-500 md:col-span-3 lg:col-span-2 interactive-scorecard">
<div class="flex items-center">
<div class="rounded-lg bg-pink-100 p-3 mr-4">
<i class="fas fa-trophy text-pink-600 text-xl"></i>
</div>
<div>
<p class="text-gray-500 text-sm">Tariff Mitigation Success</p>
<h3 class="text-2xl font-bold text-gray-800">87%</h3>
</div>
</div>
<div class="mt-3 flex justify-between text-sm">
<span class="text-gray-500">This quarter</span>
<span class="bg-pink-100 text-pink-800 px-2 py-1 rounded-full text-xs">+12%</span>
</div>
<p class="mt-2 text-sm text-gray-600">
<span class="text-pink-500"><i class="fas fa-star"></i> Exceeded target by 7%</span>
</p>
</div>
</div>
<!-- Charts Section -->
<div class="grid grid-cols-1 xl:grid-cols-4 gap-5 mb-6">
<!-- Left Charts (3/4 width) -->
<div class="xl:col-span-3">
<div class="grid-stack">
<div class="chart-container col-span-2">
<div class="p-4 border-b flex justify-between items-center">
<h3 class="font-semibold text-dark">Monthly Tariff Spend Analysis</h3>
<div class="flex">
<button class="text-xs py-1 px-2 mr-1 rounded bg-blue-50 text-blue-600">2023</button>
<button class="text-xs py-1 px-2 rounded bg-gray-100 text-gray-600">2022</button>
</div>
</div>
<div class="p-4">
<canvas id="lineChart" height="250"></canvas>
</div>
</div>
<div class="chart-container">
<div class="p-4 border-b">
<h3 class="font-semibold text-dark">Spend by Product Category</h3>
</div>
<div class="p-4">
<canvas id="doughnutChart" height="250"></canvas>
</极div>
</div>
<div class="chart-container">
<div class="p-4 border-b">
<h3 class="font-semibold text-dark">Supplier Tariff Distribution</h3>
</div>
<div class="p-4">
<canvas id="barChart" height="250"></canvas>
</div>
</div>
<!-- NEW CHART - Tariff Spend Forecast -->
<div class="chart-container col-span-2">
<div class="p-4 border-b flex justify-between items-center">
<h3 class="font-semibold text-dark">Tariff Spend Forecast</h3>
<div class="text-xs text-gray-500">
<span class="inline-block w-3 h-3 bg-blue-500 rounded-full mr-1"></span> Actual
<span class="inline-block w-3 h-3 bg-green-500 rounded-full ml-3 mr-1"></span> Forecast
</div>
</div>
<div class="p-4">
<canvas id="forecastChart" height="250"></canvas>
</div>
</div>
<!-- EXISTING CHART - Tariff by Country -->
<div class="chart-container">
<div class="p-4 border-b">
<h3 class="font-semibold text-dark">Tariff by Country of Origin</h3>
</div>
<div class="p-4">
<canvas id="polarChart" height="250"></canvas>
</div>
</div>
<!-- EXISTING CHART - HS Code Analysis -->
<div class="chart-container">
<div class="p-4 border-b">
<h3 class="font-semibold text-dark">HS Code Analysis</h3>
</div>
<div class="p-4">
<canvas id="pieChart" height="250"></canvas>
</div>
</div>
<!-- NEW CHART - Value vs Tariff Correlation -->
<div class="chart-container col-span-2">
<div class="p-4 border-b flex justify-between items-center">
<h3 class="font-semibold text-dark">Value vs Tariff Correlation</h3>
<div class="text-xs text-gray-500">
<span class="inline-block w-4 h-4 bg-blue-500 rounded-full mr-1"></span> Each dot represents a product
</div>
</div>
<div class="p-4">
<canvas id="correlationChart" height="250"></canvas>
</div>
</div>
</div>
</div>
<!-- Right Charts (1/4 width) -->
<div class="xl:col-span-1">
<div class="flex flex-col gap-5">
<!-- EXISTING CHART - Top Tariff Rates -->
<div class="chart-container">
<div class="p-4 border-b">
<h3 class="font-semibold text-dark">Top 5 Tariff Rates</h3>
</div>
<div class="p-4">
<canvas id="horizBarChart" height="250"></canvas>
</div>
</div>
<!-- EXISTING CHART - Tariff by Port -->
<div class="chart-container">
<div class="p-4 border-b">
<h3 class="font-semibold text-dark">Tariff by Port of Entry</h3>
</div>
<div class="p-4">
<canvas id="portChart" height="250"></canvas>
</div>
</div>
<!-- EXISTING CHART - Compliance Status -->
<div class="chart-container">
<div class="p-4 border-b">
<h3 class="font-semibold text-dark">Compliance Status</极h3>
</div>
<div class="p-4">
<canvas id="complianceChart" height="250"></canvas>
</div>
</div>
<!-- NEW CHART 1 - Monthly Average Spend -->
<div class="chart-container">
<div class="p-4 border-b">
<h3 class="font-semibold text-dark">Monthly Average Spend</h3>
</div>
<div class="p-4">
<canvas id="avgSpendChart" height="250"></canvas>
</div>
</div>
<!-- NEW CHART 2 - Cost Distribution by Category -->
<div class="chart-container">
<div class="p-4 border-b">
<h3 class="font-semibold text-dark">Cost Distribution by Category</h3>
</div>
<div class="p-4">
<canvas id="costDistributionChart" height="250"></canvas>
</div>
</div>
<!-- NEW CHART 3 - Top Suppliers by Volume -->
<div class="chart-container">
<div class="p-4 border-b">
<h3 class="font-semibold text-dark">Top Suppliers by Volume</h3>
</div>
<div class="p-4">
<canvas id="supplierVolumeChart" height="250"></canvas>
</div>
</div>
</div>
</div>
</div>
<!-- Data Table -->
<div class="bg-white rounded-xl shadow-sm p-4 mt-6">
<div class="flex flex-col md:flex-row justify-between items-start md:items-center mb-4">
<h3 class="font-semibold text-dark text-lg mb-3 md:mb-0">Tariff Spend Details</h3>
<div class="flex flex-col sm:flex-row gap-3 w-full md:w-auto">
<div class="relative w-full">
<i class="fas fa-search absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400"></i>
<input type="text" id="searchInput" placeholder="Search by supplier, product, or HS code..." class="pl-10 pr-4 py-2 border border-gray-300 rounded-md w-full">
</div>
<select id="categoryFilter" class="border border-gray-300 rounded-md px-4 py-2">
<option value="all">All Categories</option>
<option>Engine Components</option>
<option>Electrical Systems</option>
<option>Chassis Parts</option>
<option>Interior Components</option>
</select>
</div>
</div>
<div class="data-table-container">
<table class="min-w-full divide-y divide-gray-200 data-table">
<thead class="bg-gray-50">
<tr>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Product ID</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Product Name</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Category</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Supplier</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Origin</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">HS Code</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Value ($)</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Tariff Rate</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Tariff Amount</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Status</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200" id="tableBody">
<!-- Data will be populated here -->
</tbody>
</table>
</div>
<div class="flex justify-between items-center mt-4">
<span class="text-sm text-gray-700">Showing <span id="visibleRows">10</span> of <span id="totalRows">25</span> entries</span>
<div class="flex space-x-2">
<button class="px-3 py-1 rounded-md border bg-white text-sm"><i class="fas fa-chevron-left"></i></button>
<button class="px-3 py-1 rounded-md border bg-blue-500 text-white text-sm">1</button>
<button class="px-3 py-1 rounded-md border bg-white text-sm">2</button>
<button class="px-3 py-1 rounded-md border bg-white text-sm"><i class="fas fa-chevron-right"></i></button>
</div>
</div>
</div>
</div>
</div>
<script>
// Global chart objects to update later
let lineChart, doughnutChart, barChart, polarChart, pieChart;
let horizBarChart, portChart, complianceChart, forecastChart;
let avgSpendChart, costDistributionChart, supplierVolumeChart, correlationChart;
// Initialize dropdowns
document.querySelectorAll('.dropdown-toggle').forEach(toggle => {
toggle.addEventListener('click', () => {
const menu = toggle.nextElementSibling;
menu.classList.toggle('active');
const icon = toggle.querySelector('i');
if (icon.classList.contains('fa-chevron-down')) {
icon.classList.remove('fa-chevron-down');
icon.classList.add('fa-chevron-up');
} else {
icon.classList.remove('fa-chevron-up');
icon.classList.add('fa-chevron-down');
}
});
});
// Tariff rate slider value display
const tariffRateSlider = document.getElementById('tariffRate');
const tariffRateValue = document.getElementById('tariffRateValue');
tariffRateSlider.addEventListener('input', () => {
tariffRateValue.textContent = `${tariffRateSlider.value}%`;
});
// Show notification function
function showNotification() {
const notification = document.getElementById('notification');
notification.classList.add('show');
setTimeout(() => {
notification.classList.remove('show');
}, 3000);
}
// Apply Filters button animation and update dashboard
const applyBtn = document.getElementById('applyFilters');
applyBtn.addEventListener('click', function() {
this.classList.add('animate-pulse-slow');
this.innerHTML = '<i class="fas fa-spinner animate-spin mr-2"></i> Applying Filters';
setTimeout(() => {
updateDashboard();
this.classList.remove('animate-pulse-slow');
this.innerHTML = '<i class="fas fa-sync-alt mr-2"></i> Apply Filters';
showNotification();
}, 1500);
});
// Reset Filters button
const resetBtn = document.getElementById('resetFilters');
resetBtn.addEventListener('click', function() {
this.innerHTML = '<i class="fas fa-spinner animate-spin mr-2"></i> Resetting';
// Reset all filters to default values
document.getElementById('fromDate').value = '2023-01-01';
document.getElementById('toDate').value = '2023-12-31';
document.getElementById('supplierName').value = 'all';
document.getElementById('supplierCountry').value = 'all';
document.getElementById('productCategory').value = 'all';
document.getElementById('hsCode').value = '';
document.getElementById('minValue').value = '500';
document.getElementById('maxValue').value = '10000';
document.getElementById('tariffRate').value = '10';
document.getElementById('tariffRateValue').textContent = '10%';
document.getElementById('tariffStatus').value = 'all';
document.getElementById('minTariffAmount').value = '50';
document.getElementById('maxTariffAmount').value = '2500';
document.getElementById('portEntry').value = 'all';
document.getElementById('shippingMethod').value = 'all';
setTimeout(() => {
updateDashboard(true);
this.innerHTML = '<i class="fas fa-redo mr-2"></i> Reset Filters';
showNotification();
}, 1500);
});
// Update dashboard data based on filters
function updateDashboard(reset = false) {
if (reset) {
// Reset all charts to their initial state
resetChartData();
} else {
// Generate updated data based on filters
const filteredData = generateFilteredData();
// Update scorecards
updateScorecards(filteredData);
// Update charts with filtered data
updateChartData(filteredData);
// Update table with filtered data
updateTable(filteredData.tableData);
}
}
// Generate filtered data based on filter inputs
function generateFilteredData() {
// This is a simplified simulation - in a real app, you would make API calls
const data = {
totalSpend: 2840000,
impactedProducts: 187,
activeSuppliers: 24,
avgTariffRate: 8.7,
monthlySpend: [210000, 180000, 240000, 300000, 280000, 310000, 350000, 320000, 380000, 420000, 400000, 450000],
costReduction: 420000,
mitigationSuccess: 87
};
// Apply some simple filtering logic for demonstration
const minTariff = parseInt(document.getElementById('minValue').value) || 0;
const maxTariff = parseInt(document.getElementById('maxValue').value) || 10000;
const tariffRate = parseInt(document.getElementById('tariffRate').value) || 10;
// Adjust data based on filter strength
const factor = 1 - (tariffRate - 10) / 30;
data.totalSpend = data.totalSpend * factor;
data.impactedProducts = Math.floor(data.impactedProducts * factor);
data.avgTariffRate = data.avgTariffRate * factor;
data.costReduction = data.costReduction * factor;
data.mitigationSuccess = data.mitigationSuccess * factor;
return {
...data,
tableData: [...tableData] // filtered table data would go here
};
}
// Reset all chart data to initial state
function resetChartData() {
// Line Chart
lineChart.data.datasets[0].data = [210000, 180000, 240000, 300000, 280000, 310000, 350000, 320000, 380000, 420000, 400000, 450000];
lineChart.update();
// Doughnut Chart
doughnutChart.data.datasets[0].data = [35, 25, 20, 15, 3, 2];
doughnutChart.update();
// Bar Chart
barChart.data.datasets[0].data = [125, 90, 80, 70, 50];
barChart.update();
// Reset all other charts similarly
// ...
// Update scorecards to original values
document.querySelector('.scorecard:nth-child(1) h3').textContent = '$2.84M';
document.querySelector('.scorecard:nth-child(2) h3').textContent = '187';
document.querySelector('.scorecard:nth-child(3) h3').textContent = '24';
document.querySelector('.scorecard:nth-child(4) h3').textContent = '8.7%';
document.querySelector('.scorecard:nth-child(5) h3').textContent = '$420K';
document.querySelector('.scorecard:nth-child(6) h3').textContent = '87%';
// Update table to show all data
const tbody = document.getElementById('tableBody');
tbody.innerHTML = '';
tableData.forEach(row => {
const tr = createTableRow(row);
tbody.appendChild(tr);
});
}
// Generate sample table data
const tableData = [
{id: 'AP-8708-102', name: 'Fuel Injector', category: 'Engine', supplier: 'DynaParts', origin: 'China', hscode: '8708.99.1560', value: 2450, rate: 15, amount: 367.50, status: 'Paid'},
{id: 'AP-8701-405', name: 'Transmission Gear', category: 'Transmission', supplier: 'TechAuto', origin: 'Japan', hscode: '8701.20.0040', value: 3250, rate: 2.5, amount: 81.25, status: 'Exempted'},
{id: 'AP-8708-230', name: 'Brake Caliper', category: 'Braking', supplier: 'EuroAuto', origin: 'Germany', hscode: '8708.30.5010', value极: 1850, rate: 7.5, amount: 138.75, status: 'Pending'},
{id: 'AP-8708-101', name: 'Spark Plug', category: 'Engine', supplier: 'DynaParts', origin: 'China', hscode: '8708.99.1560', value: 850, rate: 15, amount: 127.50, status: 'Paid'},
{id: 'AP-8708-520', name: 'Headlight Assembly', category: 'Electrical', supplier: 'Precision', origin: 'Mexico', hscode: '8708.29.0030', value: 750, rate: 10, amount: 75.00, status: 'Under Appeal'},
{id: 'AP-8708-330', name: 'Control Arm', category: 'Chassis', supplier: 'Global', origin: 'India', hscode: '8708.50.6080', value: 1200, rate: 7.5, amount: 90.00, status: 'Paid'},
{id: 'AP-8708-455', name: 'Seat Frame', category: 'Interior', supplier: 'Precision', origin: 'South Korea', hscode: '8708.50.4560', value: 1850, rate: 12.5, amount: 231.25, status: 'Pending'},
{id: 'AP-8708-670', name: 'ECU Module', category: 'Electrical', supplier: 'TechAuto', origin: 'Japan', hscode: '8708.29.0050', value: 3250, rate: 5, amount: 162.50, status: 'Exempted'},
{id: 'AP-8708-770', name: 'Steering Rack', category: 'Chassis', supplier: 'Global', origin: 'China', hscode: '8708.50.7090', value: 2100, rate: 15, amount: 315.00, status: 'Paid'},
{id: 'AP-8701-310', name: 'Clutch Assembly', category: 'Transmission', supplier: 'Precision', origin: 'Mexico', hscode: '8708.99.1120', value: 1550, rate: 7.5, amount: 116.25, status: 'Pending'},
{id: 'AP-8708-999', name: 'Alternator', category: 'Electrical', supplier: 'Global', origin: 'Mexico', hscode: '8708.29.0040', value: 950, rate: 10, amount: 95.00, status: 'Paid'},
{id: 'AP-8708-777', name: 'Fuel Pump', category: 'Engine', supplier: 'DynaParts', origin: 'China', hscode: '8708.99.1580', value: 1250, rate: 15, amount: 187.50, status: 'Paid'},
{id: 'AP-8708-345', name: 'Shock Absorber', category: 'Chassis', supplier: 'TechAuto', origin: 'South Korea', hscode: '8708.50.7010', value: 850, rate: 7.5, amount: 63.75, status: 'Pending'},
{id: 'AP-8708-122', name: 'Radiator', category: 'Engine', supplier: 'EuroAuto', origin: 'Germany', hscode: '8708.99.1230', value: 1800, rate: 5, amount: 90.00, status: 'Exempted'},
{id: 'AP-8708-876', name: 'Dashboard Panel', category: 'Interior', supplier: 'Precision', origin: 'India', hscode: '8708.50.5010', value: 2100, rate: 12.5, amount: 262.50, status: 'Paid'}
];
// Create table row function
function createTableRow(row) {
const tr = document.createElement('tr');
tr.innerHTML = `
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">${row.id}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${row.name}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${row.category}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${row.supplier}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${row.origin}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${row.hscode}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">$${row.value.toLocaleString()}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${row.rate}%</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">$${row.amount.toLocaleString()}</td>
<td class="px-6 py-4 whitespace-nowrap">
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full
${row.status === 'Paid' ? 'bg-green-100 text-green-800' :
row.status === 'Pending' ? 'bg-yellow-100 text-yellow-800' :
row.status === 'Exempted' ? 'bg-blue-100 text-blue-800' :
'bg-red-100 text-red-800'}">
${row.status}
</span>
</td>
`;
// Add hover effect
tr.addEventListener('mouseenter', () => {
tr.classList.add('highlight-row');
});
tr.addEventListener('mouseleave', () => {
tr.classList.remove('highlight-row');
});
return tr;
}
// Initialize all charts
document.addEventListener('DOMContentLoaded', function() {
// Line Chart
const lineCtx = document.getElementById('lineChart').getContext('2d');
lineChart = new Chart(lineCtx, {
type: 'line',
data: {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
datasets: [{
label: 'Tariff Spend ($)',
data: [210000, 180000, 240000, 300000, 280000, 310000, 350000, 320000, 380000, 420000, 400000, 450000],
borderColor: '#1d4ed8',
backgroundColor: 'rgba(29, 78, 216, 0.05)',
tension: 0.4,
fill: true,
borderWidth: 2
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
tooltip: {
callbacks: {
label: function(context) {
return `$${context.parsed.y.toLocaleString()}`;
}
}
}
},
scales: {
y: {
ticks: {
callback: function(value) {
return '$' + (value/1000).toFixed(0) + 'K';
}
}
}
}
}
});
// Doughnut Chart
const doughnutCtx = document.getElementById('doughnutChart').getContext('2d');
doughnutChart = new Chart(doughnutCtx, {
type: 'doughnut',
data: {
labels: ['Engine', 'Electrical', 'Chassis', 'Interior', 'Transmission', 'Braking'],
datasets: [{
data: [35, 25, 20, 15, 3, 2],
backgroundColor: ['#1d4ed8', '#3b82f6', '#60a5fa', '#93c5fd', '#bfdbfe', '#dbeafe'],
borderWidth: 0
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
cutout: '70%',
plugins: {
legend: {
position: 'right'
},
tooltip: {
callbacks: {
label: function(context) {
return context.label + ': ' + context.parsed + '%';
}
}
}
}
}
});
// Bar Chart
const barCtx = document.getElementById('barChart').getContext('2d');
barChart = new Chart(barCtx, {
type: 'bar',
data: {
labels: ['Supplier A', 'Supplier B', 'Supplier C', 'Supplier D', 'Supplier E'],
datasets: [{
label: 'Spend ($K)',
data: [125, 90, 80, 70, 50],
backgroundColor: '#10b981',
borderRadius: 5,
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true,
ticks: {
callback: function(value) {
return '$' + value + 'K';
}
}
}
}
}
});
// Polar Chart
const polarCtx = document.getElementById('polarChart').getContext('2d');
polarChart = new Chart(polarCtx, {
type: 'polarArea',
data: {
labels: ['China', 'Germany', 'Mexico', 'Japan', 'South Korea', 'India'],
datasets: [{
data: [65, 15, 10, 5, 4, 1],
backgroundColor: ['#1d4ed8', '#3b82f6', '#60a5fa', '#93c5fd', '#bfdbfe', '#dbeafe'],
borderWidth: 0
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
tooltip: {
callbacks: {
label: function(context) {
return context.label + ': ' + context.parsed + '%';
}
}
}
}
}
});
// Pie Chart
const pieCtx = document.getElementById('pieChart').getContext('2极');
pieChart = new Chart(pieCtx, {
type: 'pie',
data: {
labels: ['8708.10', '8708.29', '8708.50', '8708.70', '8708.99', '8701.20'],
datasets: [{
data: [30, 25, 20, 15, 8, 2],
backgroundColor: ['#1d4ed8', '#3b82f6', '#60a5fa', '#93c5fd', '#bfdbfe', '#dbeafe'],
borderWidth: 0
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'right'
},
tooltip: {
callbacks: {
label: function(context) {
return context.label + ': ' + context.parsed + '%';
}
}
}
}
}
});
// Forecast Chart - NEW
const forecastCtx = document.getElementById('forecastChart').getContext('2d');
forecastChart = new Chart(forecastCtx, {
type: 'line',
data: {
labels: ['Q1', 'Q2', 'Q3', 'Q4'],
datasets: [
{
label: 'Actual',
data: [530000, 730000, 650000, 950000],
borderColor: '#1d4ed8',
backgroundColor: 'rgba(29, 78, 216, 0.05)',
tension: 0.4,
fill: false,
borderWidth: 2
},
{
label: 'Forecast',
data: [null, null, null, 950000, 980000, 1020000, 1050000, 1100000],
borderColor: '#10b981',
borderDash: [5, 5],
tension: 0.4,
borderWidth: 2
}
]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
tooltip: {
callbacks: {
label: function(context) {
return `${context.dataset.label}: $${context.parsed.y.toLocaleString()}`;
}
}
}
},
scales: {
y: {
ticks: {
callback: function(value) {
return '$' + (value/1000).toFixed(0) + 'K';
}
}
}
}
}
});
// Correlation Chart - NEW
const correlationCtx = document.getElementById('correlationChart').getContext('2d');
correlationChart = new Chart(correlationCtx, {
type: 'scatter',
data: {
datasets: [{
label: 'Value vs Tariff Paid',
data: [
{x: 2450, y: 367.50},
{x: 3250, y: 81.25},
{x: 1850, y: 138.75},
{x: 850, y: 127.50},
{x: 750, y: 75.00},
{x: 1200, y: 90.00},
{x: 1850, y: 231.25},
{x: 3250, y: 162.50},
{x: 2100, y: 315.00},
{x: 1550, y: 116.25},
{x: 950, y: 95.00},
{x: 1250, y: 187.50},
{x: 850, y: 63.75},
{x: 1800, y: 90.00},
{x: 2100, y: 262.50}
],
backgroundColor: '#1d4ed8',
pointRadius: 6,
pointHoverRadius: 8
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
tooltip: {
callbacks: {
label: function(context) {
return `Value: $${context.parsed.x}, Tariff: $${context.parsed.y}`;
}
}
}
},
scales: {
x: {
title: {
display: true,
text: 'Product Value ($)'
},
ticks: {
callback: function(value) {
return '$' + value;
}
}
},
y: {
title: {
display: true,
text: 'Tariff Amount ($)'
}
}
}
}
});
// Horizontal Bar Chart
const horizCtx = document.getElementById('horizBarChart').getContext('2d');
horizBarChart = new Chart(horizCtx, {
type: 'bar',
data: {
labels: ['15%', '12.5%', '10%', '7.5%', '5%'],
datasets: [{
label: 'Products Count',
data: [20, 35, 75, 45, 12],
backgroundColor: '#3b82f6',
borderRadius: 5,
}]
},
options: {
indexAxis: 'y',
responsive: true,
maintainAspectRatio: false,
scales: {
x: {
beginAtZero: true
}
}
}
});
// Port Chart
const portCtx = document.getElementById('portChart').getContext('2d');
portChart = new Chart(portCtx, {
type: 'pie',
data: {
labels: ['Los Angeles', 'New York', 'Chicago', 'Houston', 'Miami'],
datasets: [{
data: [52, 22, 12, 8, 6],
backgroundColor: ['#1d4ed8', '#3b82f6', '#60a5fa', '#93c5fd', '#bfdbfe'],
borderWidth: 0
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'right'
},
tooltip: {
callbacks: {
label: function(context) {
return context.label + ': ' + context.parsed + '%';
}
}
}
}
}
});
// Compliance Chart
const complianceCtx = document.getElementById('complianceChart').getContext('2d');
complianceChart = new Chart(complianceCtx, {
type: 'doughnut',
data: {
labels: ['Paid', 'Pending', 'Exempted', 'Under Appeal'],
datasets: [{
data: [62, 25, 8, 5],
backgroundColor: ['#10b981', '#f59e0b', '#3b82f6', '#ef4444'],
borderWidth: 0
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
cutout: '70%',
plugins: {
legend: {
position: 'right'
},
tooltip: {
callbacks: {
label: function(context) {
return context.label + ': ' + context.parsed + '%';
}
}
}
}
}
});
// Average Spend Chart - NEW
const avgSpendCtx = document.getElementById('avgSpendChart').getContext('2d');
avgSpendChart = new Chart(avgSpendCtx, {
type: 'bar',
data: {
labels: ['Q1', 'Q2', 'Q3', 'Q4'],
datasets: [{
label: 'Avg Tariff Spend',
data: [87500, 101250, 89250, 105750],
backgroundColor: '#8b5cf6',
borderRadius: 5,
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true,
ticks: {
callback: function(value) {
return '$' + value.toLocaleString();
}
}
}
}
}
});
// Cost Distribution Chart - NEW
const costDistCtx = document.getElementById('costDistributionChart').getContext('2d');
costDistributionChart = new Chart(costDistCtx, {
type: 'radar',
data: {
labels: ['Engine', 'Electrical', 'Chassis', 'Interior', 'Transmission', 'Braking'],
datasets: [{
label: 'Cost Distribution',
data: [35, 25, 20, 15, 3, 2],
backgroundColor: 'rgba(59, 130, 246, 0.2)',
borderColor: '#3b82f6',
pointBackgroundColor: '#3b82f6',
pointBorderColor: '#fff',
pointHoverBackgroundColor: '#fff',
pointHoverBorderColor: '#3b82f6'
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
r: {
min: 极,
max: 40,
ticks: {
stepSize: 10
}
}
}
}
});
// Supplier Volume Chart - NEW
const supplierVolCtx = document.getElementById('supplierVolumeChart').getContext('2d');
supplierVolumeChart = new Chart(supplierVolCtx, {
type: 'doughnut',
data: {
labels: ['Supplier A', 'Supplier B', 'Supplier C', 'Others'],
datasets: [{
data: [35, 25, 20, 20],
backgroundColor: ['#1d4ed8', '#3b82f6', '#60a5fa', '#93c5fd'],
borderWidth: 0
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
cutout: '70%',
plugins: {
legend: {
position: 'right'
},
tooltip: {
callbacks: {
label: function(context) {
return context.label + ': ' + context.parsed + '%';
}
}
}
}
}
});
// Populate data table
const tableBody = document.getElementById('tableBody');
tableData.forEach(row => {
const tr = createTableRow(row);
tableBody.appendChild(tr);
});
// Update row counters
document.getElementById('visibleRows').textContent = tableData.length;
document.getElementById('totalRows').textContent = '25';
// Filtering functionality
const searchInput = document.getElementById('searchInput');
const categoryFilter = document.getElementById('categoryFilter');
function filterTable() {
const searchValue = searchInput.value.toLowerCase();
const categoryValue = categoryFilter.value;
document.querySelectorAll('#tableBody tr').forEach(row => {
const categoryCell = row.querySelector('td:nth-child(3)').textContent;
const supplierCell = row.querySelector('td:nth-child(4)').textContent.toLowerCase();
const hscodeCell = row.querySelector('td:nth-child(6)').textContent.toLowerCase();
const matchesCategory = categoryValue === 'all' || categoryCell === categoryValue;
const matchesSearch = !searchValue ||
supplierCell.includes(searchValue) ||
hscodeCell.includes(searchValue) ||
row.textContent.toLowerCase().includes(searchValue);
row.style.display = (matchesCategory && matchesSearch) ? '' : 'none';
});
}
searchInput.addEventListener('input', filterTable);
categoryFilter.addEventListener('change', filterTable);
});
// Function to update charts based on filtered data
function updateChartData(data) {
// Update line chart with filtered data
const factor = 1 - (parseInt(document.getElementById('tariffRate').value) - 10) / 30;
const filteredLineData = data.monthlySpend.map(val => Math.round(val * factor));
lineChart.data.datasets[0].data = filteredLineData;
lineChart.update();
// Update horizontal bar chart with filtered data
horizBarChart.data.datasets[0].data = [20, 35, 75, 45, 12].map(val => Math.round(val * factor));
horizBarChart.update();
// Generate random variations for other charts based on filter strength
const variationFactor = Math.max(0.8, factor);
// Update doughnut chart with filtered data
doughnutChart.data.datasets[0].data = [35, 25, 20, 15, 3, 2].map(val => Math.round(val * variationFactor));
doughnutChart.update();
// Update bar chart with filtered data
barChart.data.datasets[0].data = [125, 90, 80, 70, 50].map(val => Math.round(val * variationFactor));
barChart.update();
// Update polar chart with filtered data
polarChart.data.datasets[0].data = [65, 15, 10, 5, 4, 1].map(val => Math.round(val * variationFactor));
polarChart.update();
// Update pie chart with filtered data
pieChart.data.datasets[0].data = [30, 25, 20, 15, 8, 2].map(val => Math.round(val * variationFactor));
pieChart.update();
// Update forecast chart with filtered data
forecastChart.data.datasets[0].data = [530000, 730000, 650000, 950000].map(val => Math.round(val * factor));
forecastChart.data.datasets[1].data = [null, null, null, 950000, 980000, 1020000, 1050000, 1100000].map(val =>
val ? Math.round(val * factor) : null
);
forecastChart.update();
// Update the other new charts with filtered data
correlationChart.data.datasets[0].data = correlationChart.data.datasets[0].data.map(point => ({
x: Math.round(point.x * variationFactor),
y: Math.round(point.y * variationFactor)
}));
correlationChart.update();
// Update scorecards
document.querySelector('.scorecard:nth-child(1) h3').textContent = '$' + (data.totalSpend/1000000).toFixed(2) + 'M';
document.querySelector('.scorecard:nth-child(2) h3').textContent = data.impactedProducts;
document.querySelector('.scorecard:nth-child(3) h3').textContent = data.activeSuppliers;
document.querySelector('.scorecard:nth-child(4) h3').textContent = data.avgTariffRate.toFixed(1) + '%';
document.querySelector('.scorecard:nth-child(5) h3').textContent = '$' + (data.costReduction/1000).toFixed(0) + 'K';
document.querySelector('.scorecard:nth-child(6) h3').textContent = data.mitigationSuccess.toFixed(0) + '%';
// Update compliance chart to show current status distribution
complianceChart.data.datasets[0].data = [62, 25, 8, 5].map(val => Math.round(val * variationFactor));
complianceChart.update();
// Update cost distribution chart with filtered data
costDistributionChart.data.datasets[0].data = [35, 25, 20, 15, 3, 2].map(val => Math.round(val * variationFactor));
costDistributionChart.update();
// Update average spend chart with filtered data
avgSpendChart.data.datasets[0].data = [87500, 101250, 89250, 105750].map(val => Math.round(val * variationFactor));
avgSpendChart.update();
// Update supplier volume chart with filtered data
supplierVolumeChart.data.datasets[0].data = [35, 25, 20, 20].map(val => Math.round(val * variationFactor));
supplierVolumeChart.update();
// Apply filters to table
const minValue = parseInt(document.getElementById('minValue').value) || 0;
const maxValue = parseInt(document.getElementById('maxValue').value) || 10000;
const minTariff = parseInt(document.getElementById('minTariffAmount').value) || 0;
const maxTariff = parseInt(document.getElementById('maxTariffAmount').value) || 2500;
const supplierName = document.getElementById('supplierName').value;
const supplierCountry = document.getElementById('supplierCountry').value;
const tariffStatus = document.getElementById('tariffStatus').value;
const portEntry = document.getElementById('portEntry').value;
const shippingMethod = document.getElementById('shippingMethod').value;
const productCategory = document.getElementById('productCategory').value;
const hsCode = document.getElementById('hsCode').value.toLowerCase();
// Filter table data
const filteredTableData = tableData.filter(row => {
const matchesValue = row.value >= minValue && row.value <= maxValue;
const matchesTariffAmount = row.amount >= minTariff && row.amount <= maxTariff;
const matchesSupplier = supplierName === 'all' || row.supplier === supplierName;
const matchesCountry = supplierCountry === 'all' || row.origin === supplierCountry;
const matchesStatus = tariffStatus === 'all' || row.status === tariffStatus;
const matchesPort = portEntry === 'all' || true; // In a real app, this would check against data
const matchesMethod = shippingMethod === 'all' || true; // In a real app, this would check against data
const matchesCategory = productCategory === 'all' || row.category === productCategory;
const matchesHSCode = !hsCode || row.hscode.includes(hsCode);
return matchesValue && matchesTariffAmount && matchesSupplier && matchesCountry &&
matchesStatus && matchesPort && matchesMethod && matchesCategory && matchesHSCode;
});
// Update table
const tbody = document.getElementById('tableBody');
tbody.innerHTML = '';
filteredTableData.forEach(row => {
const tr = createTableRow(row);
tbody.appendChild(tr);
});
// Update visible row count
document.getElementById('visibleRows').textContent = filteredTableData.length;
}
// Function to update scorecards
function updateScorecards(data) {
document.querySelector('.scorecard:nth-child(1) h3').textContent = '$' + (data.totalSpend/1000000).toFixed(2) + 'M';
document.querySelector('.scorecard:nth-child(2) h3').textContent = data.impactedProducts;
document.querySelector('.scorecard:nth-child(3) h3').textContent = data.activeSuppliers;
document.querySelector('.scorecard:nth-child(4) h3').textContent = data.avgTariffRate.toFixed(1) + '%';
document.querySelector('.scorecard:nth-child(5) h3').textContent = '$' + (data.costReduction/1000).toFixed(0) + 'K';
document.querySelector('.scorecard:nth-child(6) h3').textContent = data.mitigationSuccess.toFixed(0) + '%';
}
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://huggingface.co/proxy/enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://huggingface.co/proxy/enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://huggingface.co/proxy/enzostvs-deepsite.hf.space?remix=anonymous111110987654321/autoparts-tariff-tracker" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>