Mujahid1111 commited on
Commit
ceb3cf5
·
verified ·
1 Parent(s): a719d97

1. Global Principles & Core Technologies

Browse files

1.1. Core Philosophy
Real-time: The application must feel alive. Data is the lifeblood, and it should be presented to the user with minimal delay.

Clarity over Clutter: Despite the density of information, the design must prioritize scannability and intuitive understanding through strong visual hierarchy.

Performance is a Feature: Every interaction, from page load to data filtering, must be fast and responsive.

1.2. Non-Functional Requirements
Responsiveness: All components are built mobile-first and must provide a seamless experience on all screen sizes.

Performance:

API Response Time: All endpoints must respond in < 300ms.

Frontend Page Load (LCP): Initial page load should be < 2 seconds.

Interaction Latency: UI reactions to user input (e.g., filtering, sorting) should feel instantaneous (<100ms).

Animation: All animations are handled by Framer Motion and must be smooth (targeting 60fps). They will be used to provide visual feedback, guide the user's attention, and manage state transitions gracefully (e.g., loading states, modal pop-ups).

2. End-to-End Feature Specifications: Core Dashboard
2.1. Feature: Countdown Banner
User Goal: To instantly see and prepare for the next major market-moving economic event.

Frontend - UI & Design:

A full-width banner at the top of the page with a slate-800 background.

Layout: A 3-column flex container. Left: Icon and Timer. Center: Event Details. Right: Calendar Button.

States:

Default: White timer text.

Imminent (T-10 mins): Timer text turns orange.

Live (T+10 mins): Timer is replaced with a red, pulsing "LIVE NOW" text element.

Frontend - Interaction & Animation:

The HH:MM:SS timer is a state variable that updates every second, causing a re-render of only the timer text, not the whole banner.

The transition to the "LIVE NOW" state is a smooth fade-in/fade-out. The pulse animation is a subtle, continuous scale and opacity change.

Data Flow:

On initial page load, the frontend calls GET /events/next.

A background polling mechanism re-calls this endpoint every 60 seconds to ensure the data is current.

Backend - Working:

The GET /events/next endpoint executes a targeted Supabase query: SELECT * FROM events WHERE importance = 'High' AND time >= NOW() ORDER BY time ASC LIMIT 1.

It returns a single JSON object for the event, or null if none are scheduled.

2.2. Feature: Dual News Carousels & Filtering
User Goal: To passively consume a broad range of breaking news and filter it down to topics of interest.

Frontend - UI & Design:

Two rows of horizontally scrolling news cards.

Cards have a clean layout with a bold headline, a multi-line summary, and a timestamp.

A row of filter buttons ("All", "Crypto", etc.) sits above the carousels. The active filter has a distinct blue-600 background.

Frontend - Interaction & Animation:

The carousels are powered by a seamless, linear animate property in Framer Motion for an infinite loop.

Hovering a card animates its scale (scale: 1.05) and shows a blue border.

Clicking a filter button updates the parent component's state, which smoothly re-renders the carousels with the new list of items using an animated layout.

Clicking a card opens the NewsModal. The modal itself animates in with a scale and fade transition, while the background darkens. The specific carousel's animation is paused.

Data Flow:

On load, the frontend calls GET /news/latest to fetch the master list of 50 news items.

The data is stored in a state variable. Filtering happens on the client-side for maximum speed.

The news is re-fetched every 2-3 minutes.

Backend - Working:

The GET /news/latest endpoint queries Supabase: SELECT * FROM news ORDER BY published_at DESC LIMIT 50.

The backend's scheduled jobs (fetch_and_store_news_from_feeds, fetch_forexfactory_news) are constantly populating the news table in the background.

3. End-to-End Feature Specifications: Advanced Pages
3.1. Feature: Crypto Screener
User Goal: To efficiently find and analyze cryptocurrencies based on real-time market data.

Frontend - UI & Design:

A full-page, responsive data table.

Controls at the top include a search bar and filter dropdowns/sliders for Market Cap and Volume.

Table columns are sortable. Price cells are monospaced for clarity.

Frontend - Interaction & Animation:

As the user types in the search bar, the table filters instantly with a smooth, animated re-ordering of rows.

Price updates are the key animation: the cell background briefly flashes green for an increase or red for a decrease before fading back to the default.

Sorting by clicking a column header triggers an animated re-shuffle of the table rows.

Data Flow:

On page load, a call is made to the backend proxy GET /crypto/all.

For live prices, a WebSocket connection is preferred. As a fallback, the frontend will poll the endpoint every 30-60 seconds.

Backend - Working:

The GET /crypto/all endpoint is a secure proxy. It receives the request from the frontend.

It makes a server-to-server call to the CoinGecko API, injecting a secret API key.

It implements a 60-second cache to prevent hitting API rate limits on high-frequency requests.

It forwards the JSON response from CoinGecko to the client.

3.2. Feature: Liquidation Heatmap
User Goal: To visually identify high-liquidity price zones that could act as magnets or support/resistance.

Frontend - UI & Design:

A large chart area is the main focus.

Buttons at the top allow users to switch between assets (BTCUSDT, ETHUSDT).

The chart displays the price on the Y-axis. Horizontal bands are drawn at key price levels, with their color intensity (yellow -> orange -> red) indicating the magnitude of liquidations.

Frontend - Interaction & Animation:

Switching assets triggers a loading state (e.g., a skeleton loader or spinner) and then smoothly fades the new chart and heatmap data into view.

Hovering over a liquidation band displays a tooltip that follows the cursor, providing detailed information without clicks.

Data Flow:

On load, the frontend calls GET /liquidations/BTCUSDT.

When the user clicks "ETHUSDT", a new call is made to GET /liquidations/ETHUSDT.

The data is refreshed automatically every 5 minutes.

Backend - Working:

A scheduled job, fetch_liquidation_data, runs every 15 minutes. It calls an external API (e.g., CoinGlass), processes the data, and stores it in the liquidation_levels table in Supabase.

The GET /liquidations/{asset} endpoint simply performs a SELECT * FROM liquidation_levels WHERE asset_ticker = {asset} to serve the pre-processed data to the frontend.

3.3. Feature: User Accounts & Watchlists
User Goal: To save and track a personalized list of assets and preferences.

Frontend - UI & Design:

Login/Signup is handled in a clean, centered modal.

Once logged in, a "My Watchlist" widget appears on the dashboard, showing a compact table of the user's assets with live-ticking prices.

Frontend - Interaction & Animation:

Adding an asset to the watchlist provides instant feedback, with the item smoothly animating into the list.

Price ticks in the watchlist widget use the same green/red flash animation as the screener.

Data Flow:

Authentication is handled client-side using the supabase-js library, which securely manages JWTs.

Once logged in, the frontend makes authenticated requests to POST /watchlist or DELETE /watchlist to manage the list.

Backend - Working:

The backend endpoints for /watchlist are protected. They require a valid JWT.

The logic uses the user_id from the decoded token to interact with the watchlists table.

All security is enforced by Supabase's Row Level Security policies, ensuring a user can only ever modify their own data. The backend code is simple and acts as a passthrough to the secure database

Files changed (4) hide show
  1. crypto.html +118 -0
  2. dashboard.html +161 -0
  3. heatmap.html +208 -0
  4. index.html +9 -9
crypto.html ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Crypto Screener | CodeWizard</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <script src="https://unpkg.com/feather-icons"></script>
9
+ <script src="https://cdn.jsdelivr.net/npm/framer-motion@10.16.4/dist/framer-motion.min.js"></script>
10
+ <style>
11
+ .monospace { font-family: monospace; }
12
+ .price-up { color: #10b981; }
13
+ .price-down { color: #ef4444; }
14
+ .price-flash-up { animation: flashGreen 1s; }
15
+ .price-flash-down { animation: flashRed 1s; }
16
+ @keyframes flashGreen {
17
+ 0% { background-color: rgba(16, 185, 129, 0.3); }
18
+ 100% { background-color: transparent; }
19
+ }
20
+ @keyframes flashRed {
21
+ 0% { background-color: rgba(239, 68, 68, 0.3); }
22
+ 100% { background-color: transparent; }
23
+ }
24
+ .table-row:hover { background-color: #f9fafb; }
25
+ </style>
26
+ </head>
27
+ <body class="bg-gray-100">
28
+ <header class="bg-white shadow-sm">
29
+ <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
30
+ <div class="flex justify-between h-16 items-center">
31
+ <a href="index.html" class="flex items-center">
32
+ <i data-feather="code" class="text-purple-600 mr-2"></i>
33
+ <span class="text-xl font-bold text-gray-900">CodeWizard</span>
34
+ </a>
35
+ <nav class="hidden md:flex space-x-8">
36
+ <a href="dashboard.html" class="text-gray-600 hover:text-purple-600">Dashboard</a>
37
+ <a href="crypto.html" class="text-purple-600 font-medium">Crypto</a>
38
+ <a href="heatmap.html" class="text-gray-600 hover:text-purple-600">Liquidation Heatmap</a>
39
+ <a href="#" class="text-gray-600 hover:text-purple-600" id="login-btn">Login</a>
40
+ </nav>
41
+ <button class="md:hidden text-gray-600">
42
+ <i data-feather="menu"></i>
43
+ </button>
44
+ </div>
45
+ </div>
46
+ </header>
47
+
48
+ <main class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
49
+ <div class="flex justify-between items-center mb-6">
50
+ <h1 class="text-2xl font-bold">Crypto Screener</h1>
51
+ <div class="flex space-x-4">
52
+ <div class="relative">
53
+ <input type="text" placeholder="Search..." class="pl-10 pr-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-600">
54
+ <i data-feather="search" class="absolute left-3 top-2.5 text-gray-400"></i>
55
+ </div>
56
+ <button class="flex items-center bg-purple-600 hover:bg-purple-700 text-white px-4 py-2 rounded-lg">
57
+ <i data-feather="plus" class="mr-2"></i>
58
+ Add to Watchlist
59
+ </button>
60
+ </div>
61
+ </div>
62
+
63
+ <div class="bg-white rounded-lg shadow overflow-x-auto">
64
+ <table class="min-w-full divide-y divide-gray-200">
65
+ <thead class="bg-gray-50">
66
+ <tr>
67
+ <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider cursor-pointer">Asset</th>
68
+ <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider cursor-pointer">Price</th>
69
+ <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider cursor-pointer">24h Change</th>
70
+ <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider cursor-pointer">24h Volume</th>
71
+ <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider cursor-pointer">Market Cap</th>
72
+ <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Actions</th>
73
+ </tr>
74
+ </thead>
75
+ <tbody id="crypto-table-body" class="bg-white divide-y divide-gray-200">
76
+ <!-- Example row - would be populated by JavaScript -->
77
+ <tr class="table-row">
78
+ <td class="px-6 py-4 whitespace-nowrap">
79
+ <div class="flex items-center">
80
+ <img src="https://cryptologos.cc/logos/bitcoin-btc-logo.png" alt="BTC" class="w-6 h-6 mr-2">
81
+ <div>
82
+ <div class="font-medium">Bitcoin</div>
83
+ <div class="text-gray-500 text-sm">BTC</div>
84
+ </div>
85
+ </div>
86
+ </td>
87
+ <td class="px-6 py-4 whitespace-nowrap monospace">$42,123.45</td>
88
+ <td class="px-6 py-4 whitespace-nowrap price-up">+2.34%</td>
89
+ <td class="px-6 py-4 whitespace-nowrap">$24.5B</td>
90
+ <td class="px-6 py-4 whitespace-nowrap">$820.3B</td>
91
+ <td class="px-6 py-4 whitespace-nowrap">
92
+ <button class="text-purple-600 hover:text-purple-800">
93
+ <i data-feather="eye" class="w-4 h-4"></i>
94
+ </button>
95
+ </td>
96
+ </tr>
97
+ </tbody>
98
+ </table>
99
+ </div>
100
+ </main>
101
+
102
+ <script>
103
+ feather.replace();
104
+
105
+ // This would be replaced with actual API calls
106
+ function fetchCryptoData() {
107
+ // Simulating API call with setTimeout
108
+ setTimeout(() => {
109
+ // This would update the table with real data
110
+ console.log('Updating crypto data...');
111
+ }, 30000); // Update every 30 seconds
112
+ }
113
+
114
+ // Initial fetch
115
+ fetchCryptoData();
116
+ </script>
117
+ </body>
118
+ </html>
dashboard.html ADDED
@@ -0,0 +1,161 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Market Dashboard | CodeWizard</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <script src="https://unpkg.com/feather-icons"></script>
9
+ <script src="https://cdn.jsdelivr.net/npm/framer-motion@10.16.4/dist/framer-motion.min.js"></script>
10
+ <style>
11
+ .countdown-imminent { color: #f97316; }
12
+ .countdown-live {
13
+ color: #ef4444;
14
+ animation: pulse 1.5s infinite;
15
+ }
16
+ @keyframes pulse {
17
+ 0% { opacity: 1; }
18
+ 50% { opacity: 0.5; }
19
+ 100% { opacity: 1; }
20
+ }
21
+ .news-card:hover {
22
+ transform: scale(1.05);
23
+ border-color: #2563eb;
24
+ }
25
+ .price-up { animation: flashGreen 1s; }
26
+ .price-down { animation: flashRed 1s; }
27
+ @keyframes flashGreen {
28
+ 0% { background-color: rgba(34, 197, 94, 0.3); }
29
+ 100% { background-color: transparent; }
30
+ }
31
+ @keyframes flashRed {
32
+ 0% { background-color: rgba(239, 68, 68, 0.3); }
33
+ 100% { background-color: transparent; }
34
+ }
35
+ </style>
36
+ </head>
37
+ <body class="bg-gray-100">
38
+ <header class="bg-white shadow-sm">
39
+ <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
40
+ <div class="flex justify-between h-16 items-center">
41
+ <a href="index.html" class="flex items-center">
42
+ <i data-feather="code" class="text-purple-600 mr-2"></i>
43
+ <span class="text-xl font-bold text-gray-900">CodeWizard</span>
44
+ </a>
45
+ <nav class="hidden md:flex space-x-8">
46
+ <a href="dashboard.html" class="text-purple-600 font-medium">Dashboard</a>
47
+ <a href="crypto.html" class="text-gray-600 hover:text-purple-600">Crypto</a>
48
+ <a href="heatmap.html" class="text-gray-600 hover:text-purple-600">Liquidation Heatmap</a>
49
+ <a href="#" class="text-gray-600 hover:text-purple-600" id="login-btn">Login</a>
50
+ </nav>
51
+ <button class="md:hidden text-gray-600">
52
+ <i data-feather="menu"></i>
53
+ </button>
54
+ </div>
55
+ </div>
56
+ </header>
57
+
58
+ <main class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
59
+ <!-- Countdown Banner -->
60
+ <section class="bg-slate-800 text-white rounded-lg mb-8 p-4" id="countdown-banner">
61
+ <div class="flex flex-col md:flex-row justify-between items-center">
62
+ <div class="flex items-center mb-4 md:mb-0">
63
+ <i data-feather="alert-circle" class="mr-3 w-6 h-6"></i>
64
+ <div id="countdown-timer" class="text-2xl font-mono">00:30:15</div>
65
+ </div>
66
+ <div class="text-center mb-4 md:mb-0">
67
+ <h3 class="font-bold" id="event-title">FOMC Rate Decision</h3>
68
+ <p class="text-sm text-slate-300" id="event-time">Today at 14:00 ET</p>
69
+ </div>
70
+ <button class="flex items-center bg-slate-700 hover:bg-slate-600 px-4 py-2 rounded-lg">
71
+ <i data-feather="calendar" class="mr-2"></i>
72
+ Add to Calendar
73
+ </button>
74
+ </div>
75
+ </section>
76
+
77
+ <!-- News Carousels -->
78
+ <section class="mb-12">
79
+ <div class="flex space-x-4 mb-4 overflow-x-auto pb-2">
80
+ <button class="filter-btn active px-4 py-2 bg-blue-600 text-white rounded-full" data-filter="all">All</button>
81
+ <button class="filter-btn px-4 py-2 bg-gray-200 hover:bg-gray-300 rounded-full" data-filter="crypto">Crypto</button>
82
+ <button class="filter-btn px-4 py-2 bg-gray-200 hover:bg-gray-300 rounded-full" data-filter="forex">Forex</button>
83
+ <button class="filter-btn px-4 py-2 bg-gray-200 hover:bg-gray-300 rounded-full" data-filter="stocks">Stocks</button>
84
+ </div>
85
+
86
+ <div class="bg-white rounded-lg shadow overflow-hidden">
87
+ <div class="relative h-64 overflow-hidden">
88
+ <div class="absolute inset-0 flex items-center" id="news-carousel-1">
89
+ <!-- News cards will be inserted here by JavaScript -->
90
+ </div>
91
+ </div>
92
+ </div>
93
+ </section>
94
+
95
+ <!-- Watchlist (shown when logged in) -->
96
+ <section id="watchlist-section" class="hidden mb-12">
97
+ <h2 class="text-2xl font-bold mb-4">My Watchlist</h2>
98
+ <div class="bg-white rounded-lg shadow overflow-x-auto">
99
+ <table class="min-w-full divide-y divide-gray-200">
100
+ <thead class="bg-gray-50">
101
+ <tr>
102
+ <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Asset</th>
103
+ <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Price</th>
104
+ <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">24h Change</th>
105
+ <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Actions</th>
106
+ </tr>
107
+ </thead>
108
+ <tbody id="watchlist-body" class="bg-white divide-y divide-gray-200">
109
+ <!-- Watchlist items will be inserted here by JavaScript -->
110
+ </tbody>
111
+ </table>
112
+ </div>
113
+ </section>
114
+ </main>
115
+
116
+ <script>
117
+ // Countdown timer functionality
118
+ function updateCountdown() {
119
+ const eventTime = new Date(Date.now() + 30 * 60 * 1000); // Example: 30 minutes from now
120
+ const now = new Date();
121
+ const diff = eventTime - now;
122
+
123
+ if (diff <= 0) {
124
+ document.getElementById('countdown-timer').textContent = 'LIVE NOW';
125
+ document.getElementById('countdown-timer').classList.add('countdown-live');
126
+ document.getElementById('countdown-timer').classList.remove('countdown-imminent');
127
+ return;
128
+ }
129
+
130
+ const hours = Math.floor(diff / (1000 * 60 * 60));
131
+ const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
132
+ const seconds = Math.floor((diff % (1000 * 60)) / 1000);
133
+
134
+ const timer = document.getElementById('countdown-timer');
135
+ timer.textContent = `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
136
+
137
+ if (diff < 10 * 60 * 1000) { // Less than 10 minutes
138
+ timer.classList.add('countdown-imminent');
139
+ } else {
140
+ timer.classList.remove('countdown-imminent');
141
+ timer.classList.remove('countdown-live');
142
+ }
143
+ }
144
+
145
+ // Initialize and update countdown every second
146
+ updateCountdown();
147
+ setInterval(updateCountdown, 1000);
148
+
149
+ // News carousel filtering
150
+ document.querySelectorAll('.filter-btn').forEach(btn => {
151
+ btn.addEventListener('click', function() {
152
+ document.querySelectorAll('.filter-btn').forEach(b => b.classList.remove('active', 'bg-blue-600', 'text-white'));
153
+ this.classList.add('active', 'bg-blue-600', 'text-white');
154
+ // Filter logic would go here
155
+ });
156
+ });
157
+
158
+ feather.replace();
159
+ </script>
160
+ </body>
161
+ </html>
heatmap.html ADDED
@@ -0,0 +1,208 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Liquidation Heatmap | CodeWizard</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <script src="https://unpkg.com/feather-icons"></script>
9
+ <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
10
+ <style>
11
+ .heatmap-gradient {
12
+ background: linear-gradient(90deg, #fef08a 0%, #f59e0b 50%, #ef4444 100%);
13
+ }
14
+ .tooltip {
15
+ position: absolute;
16
+ pointer-events: none;
17
+ background: rgba(0, 0, 0, 0.8);
18
+ color: white;
19
+ padding: 8px;
20
+ border-radius: 4px;
21
+ font-size: 12px;
22
+ opacity: 0;
23
+ transition: opacity 0.2s;
24
+ }
25
+ </style>
26
+ </head>
27
+ <body class="bg-gray-100">
28
+ <header class="bg-white shadow-sm">
29
+ <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
30
+ <div class="flex justify-between h-16 items-center">
31
+ <a href="index.html" class="flex items-center">
32
+ <i data-feather="code" class="text-purple-600 mr-2"></i>
33
+ <span class="text-xl font-bold text-gray-900">CodeWizard</span>
34
+ </a>
35
+ <nav class="hidden md:flex space-x-8">
36
+ <a href="dashboard.html" class="text-gray-600 hover:text-purple-600">Dashboard</a>
37
+ <a href="crypto.html" class="text-gray-600 hover:text-purple-600">Crypto</a>
38
+ <a href="heatmap.html" class="text-purple-600 font-medium">Liquidation Heatmap</a>
39
+ <a href="#" class="text-gray-600 hover:text-purple-600" id="login-btn">Login</a>
40
+ </nav>
41
+ <button class="md:hidden text-gray-600">
42
+ <i data-feather="menu"></i>
43
+ </button>
44
+ </div>
45
+ </div>
46
+ </header>
47
+
48
+ <main class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
49
+ <div class="flex justify-between items-center mb-6">
50
+ <h1 class="text-2xl font-bold">Liquidation Heatmap</h1>
51
+ <div class="flex space-x-2">
52
+ <button class="asset-btn active px-4 py-2 bg-purple-600 text-white rounded-lg" data-asset="BTCUSDT">BTC/USDT</button>
53
+ <button class="asset-btn px-4 py-2 bg-gray-200 hover:bg-gray-300 rounded-lg" data-asset="ETHUSDT">ETH/USDT</button>
54
+ </div>
55
+ </div>
56
+
57
+ <div class="bg-white rounded-lg shadow p-6">
58
+ <div class="flex justify-between items-center mb-4">
59
+ <div class="flex items-center">
60
+ <div class="mr-2 text-sm">Legend:</div>
61
+ <div class="heatmap-gradient w-32 h-4 rounded"></div>
62
+ <div class="ml-2 text-sm">Low to High Liquidity</div>
63
+ </div>
64
+ <div class="text-sm text-gray-500">Updated: <span id="update-time">Just now</span></div>
65
+ </div>
66
+
67
+ <div class="relative h-96">
68
+ <canvas id="heatmap-chart"></canvas>
69
+ <div class="tooltip" id="heatmap-tooltip"></div>
70
+ </div>
71
+ </div>
72
+ </main>
73
+
74
+ <script>
75
+ feather.replace();
76
+
77
+ // Sample data - would be replaced with real API data
78
+ const heatmapData = {
79
+ BTCUSDT: {
80
+ levels: [
81
+ { price: 42000, liquidity: 10000000, type: 'long' },
82
+ { price: 41500, liquidity: 8000000, type: 'long' },
83
+ { price: 41000, liquidity: 12000000, type: 'long' },
84
+ { price: 42500, liquidity: 9000000, type: 'short' },
85
+ { price: 43000, liquidity: 15000000, type: 'short' },
86
+ ],
87
+ currentPrice: 42356.78
88
+ },
89
+ ETHUSDT: {
90
+ levels: [
91
+ { price: 2500, liquidity: 5000000, type: 'long' },
92
+ { price: 2450, liquidity: 4000000, type: 'long' },
93
+ { price: 2550, liquidity: 6000000, type: 'short' },
94
+ { price: 2600, liquidity: 7000000, type: 'short' },
95
+ ],
96
+ currentPrice: 2532.45
97
+ }
98
+ };
99
+
100
+ let currentAsset = 'BTCUSDT';
101
+ let chart;
102
+
103
+ function initChart() {
104
+ const ctx = document.getElementById('heatmap-chart').getContext('2d');
105
+ const data = heatmapData[currentAsset];
106
+
107
+ chart = new Chart(ctx, {
108
+ type: 'bar',
109
+ data: {
110
+ labels: data.levels.map(level => `$${level.price.toLocaleString()}`),
111
+ datasets: [{
112
+ data: data.levels.map(level => level.liquidity / 1000000), // Convert to millions
113
+ backgroundColor: data.levels.map(level =>
114
+ level.type === 'long' ? 'rgba(16, 185, 129, 0.7)' : 'rgba(239, 68, 68, 0.7)'
115
+ ),
116
+ borderWidth: 1
117
+ }]
118
+ },
119
+ options: {
120
+ responsive: true,
121
+ maintainAspectRatio: false,
122
+ scales: {
123
+ x: {
124
+ title: {
125
+ display: true,
126
+ text: 'Price Levels'
127
+ }
128
+ },
129
+ y: {
130
+ title: {
131
+ display: true,
132
+ text: 'Liquidation Volume (millions)'
133
+ }
134
+ }
135
+ },
136
+ plugins: {
137
+ legend: {
138
+ display: false
139
+ },
140
+ tooltip: {
141
+ enabled: false
142
+ }
143
+ },
144
+ onClick: (e) => {
145
+ // Handle click events if needed
146
+ }
147
+ }
148
+ });
149
+
150
+ // Add event listeners for hover tooltips
151
+ const canvas = document.getElementById('heatmap-chart');
152
+ const tooltip = document.getElementById('heatmap-tooltip');
153
+
154
+ canvas.addEventListener('mousemove', (e) => {
155
+ const points = chart.getElementsAtEventForMode(e, 'nearest', { intersect: true }, false);
156
+ if (points.length) {
157
+ const point = points[0];
158
+ const level = data.levels[point.index];
159
+
160
+ tooltip.innerHTML = `
161
+ <div>Price: $${level.price.toLocaleString()}</div>
162
+ <div>Liquidity: $${(level.liquidity / 1000000).toFixed(2)}M</div>
163
+ <div>Type: ${level.type === 'long' ? 'Long' : 'Short'} liquidations</div>
164
+ `;
165
+ tooltip.style.left = `${e.offsetX + 10}px`;
166
+ tooltip.style.top = `${e.offsetY + 10}px`;
167
+ tooltip.style.opacity = '1';
168
+ } else {
169
+ tooltip.style.opacity = '0';
170
+ }
171
+ });
172
+
173
+ canvas.addEventListener('mouseout', () => {
174
+ tooltip.style.opacity = '0';
175
+ });
176
+ }
177
+
178
+ // Initialize chart on page load
179
+ initChart();
180
+
181
+ // Handle asset switching
182
+ document.querySelectorAll('.asset-btn').forEach(btn => {
183
+ btn.addEventListener('click', function() {
184
+ if (this.classList.contains('active')) return;
185
+
186
+ document.querySelectorAll('.asset-btn').forEach(b => b.classList.remove('active', 'bg-purple-600', 'text-white'));
187
+ this.classList.add('active', 'bg-purple-600', 'text-white');
188
+ currentAsset = this.dataset.asset;
189
+
190
+ // Show loading state
191
+ document.getElementById('update-time').textContent = 'Loading...';
192
+
193
+ // Simulate API call
194
+ setTimeout(() => {
195
+ chart.destroy();
196
+ initChart();
197
+ document.getElementById('update-time').textContent = 'Just now';
198
+ }, 500);
199
+ });
200
+ });
201
+
202
+ // Simulate data updates
203
+ setInterval(() => {
204
+ document.getElementById('update-time').textContent = new Date().toLocaleTimeString();
205
+ }, 300000); // 5 minutes
206
+ </script>
207
+ </body>
208
+ </html>
index.html CHANGED
@@ -34,11 +34,11 @@
34
  <span class="text-xl font-bold text-gray-900">CodeWizard</span>
35
  </div>
36
  <div class="hidden md:flex items-center space-x-8">
37
- <a href="#" class="text-purple-600 font-medium">Home</a>
38
- <a href="#" class="text-gray-600 hover:text-purple-600">Services</a>
39
- <a href="#" class="text-gray-600 hover:text-purple-600">Portfolio</a>
40
- <a href="#" class="text-gray-600 hover:text-purple-600">About</a>
41
- <a href="#" class="text-gray-600 hover:text-purple-600">Contact</a>
42
  </div>
43
  <button class="md:hidden text-gray-600">
44
  <i data-feather="menu"></i>
@@ -182,10 +182,10 @@
182
  <div>
183
  <h4 class="font-bold mb-4">Quick Links</h4>
184
  <ul class="space-y-2">
185
- <li><a href="#" class="text-gray-400 hover:text-white transition">Home</a></li>
186
- <li><a href="#" class="text-gray-400 hover:text-white transition">Services</a></li>
187
- <li><a href="#" class="text-gray-400 hover:text-white transition">Portfolio</a></li>
188
- <li><a href="#" class="text-gray-400 hover:text-white transition">Contact</a></li>
189
  </ul>
190
  </div>
191
  <div>
 
34
  <span class="text-xl font-bold text-gray-900">CodeWizard</span>
35
  </div>
36
  <div class="hidden md:flex items-center space-x-8">
37
+ <a href="index.html" class="text-purple-600 font-medium">Home</a>
38
+ <a href="dashboard.html" class="text-gray-600 hover:text-purple-600">Dashboard</a>
39
+ <a href="crypto.html" class="text-gray-600 hover:text-purple-600">Crypto</a>
40
+ <a href="heatmap.html" class="text-gray-600 hover:text-purple-600">Heatmap</a>
41
+ <a href="#" class="text-gray-600 hover:text-purple-600" id="login-btn">Login</a>
42
  </div>
43
  <button class="md:hidden text-gray-600">
44
  <i data-feather="menu"></i>
 
182
  <div>
183
  <h4 class="font-bold mb-4">Quick Links</h4>
184
  <ul class="space-y-2">
185
+ <li><a href="index.html" class="text-gray-400 hover:text-white transition">Home</a></li>
186
+ <li><a href="dashboard.html" class="text-gray-400 hover:text-white transition">Dashboard</a></li>
187
+ <li><a href="crypto.html" class="text-gray-400 hover:text-white transition">Crypto</a></li>
188
+ <li><a href="heatmap.html" class="text-gray-400 hover:text-white transition">Heatmap</a></li>
189
  </ul>
190
  </div>
191
  <div>