kawish14 commited on
Commit
bd692f7
Β·
verified Β·
1 Parent(s): 3f1355b

<!DOCTYPE html>

Browse files

<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Database Sync Manager</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 20px;
}

.container {
max-width: 1200px;
margin: 0 auto;
background: rgba(255, 255, 255, 0.95);
border-radius: 20px;
padding: 30px;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
backdrop-filter: blur(10px);
}

.header {
text-align: center;
margin-bottom: 40px;
}

.header h1 {
color: #2c3e50;
font-size: 2.5rem;
margin-bottom: 10px;
}

.header p {
color: #7f8c8d;
font-size: 1.1rem;
}

.connection-status {
display: flex;
justify-content: center;
gap: 15px;
margin-bottom: 30px;
flex-wrap: wrap;
}

.status-badge {
padding: 8px 16px;
border-radius: 20px;
font-size: 0.9rem;
font-weight: 600;
display: flex;
align-items: center;
gap: 8px;
}

.status-badge.connected {
background: rgba(46, 204, 113, 0.2);
color: #27ae60;
}

.status-badge.disconnected {
background: rgba(231, 76, 60, 0.2);
color: #e74c3c;
}

.status-badge.checking {
background: rgba(52, 152, 219, 0.2);
color: #3498db;
}

.sync-controls {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 30px;
margin-bottom: 40px;
}

.control-section {
background: white;
padding: 25px;
border-radius: 15px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
border: 2px solid transparent;
transition: all 0.3s ease;
}

.control-section:hover {
border-color: #667eea;
transform: translateY(-5px);
}

.section-title {
font-size: 1.3rem;
font-weight: 600;
color: #2c3e50;
margin-bottom: 20px;
padding-bottom: 10px;
border-bottom: 2px solid #ecf0f1;
}

.region-card {
margin-bottom: 15px;
}

.region-header {
background: linear-gradient(45deg, #667eea, #764ba2);
color: white;
padding: 15px;
border-radius: 10px;
cursor: pointer;
transition: all 0.3s ease;
display: flex;
justify-content: space-between;
align-items: center;
}

.region-header:hover {
transform: scale(1.02);
}

.region-header.active {
background: linear-gradient(45deg, #2ecc71, #27ae60);
}

.tables-list {
background: #f8f9fa;
padding: 15px;
border-radius: 0 0 10px 10px;
display: none;
}

.tables-list.active {
display: block;
}

.table-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
margin: 5px 0;
background: white;
border-radius: 8px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}

.table-checkbox {
margin-right: 10px;
}

.column-mapping {
background: white;
padding: 20px;
border-radius: 15px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
margin-top: 20px;
display: none;
}

.column-mapping.active {
display: block;
}

.mapping-row {
display: grid;
grid-template-columns: 1fr auto 1fr auto;
gap: 15px;
align-items: center;
padding: 15px;
margin: 10px 0;
background: #f8f9fa;
border-radius: 10px;
border: 2px solid transparent;
}

.mapping-row.mapped {
border-color: #2ecc71;
background: rgba(46, 204, 113, 0.1);
}

.column-select {
padding: 10px;
border: 2px solid #ddd;
border-radius: 8px;
font-size: 1rem;
}

.column-select:focus {
outline: none;
border-color: #667eea;
}

.map-arrow {
font-size: 1.2rem;
color: #667eea;
font-weight: bold;
}

.action-buttons {
display: flex;
gap: 15px;
justify-content: center;
margin-top: 30px;
}

.btn {
padding: 15px 30px;
border: none;
border-radius: 10px;
font-size: 1.1rem;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
min-width: 150px;
}

.btn:disabled {
opacity: 0.6;
cursor: not-allowed;
}

.btn-primary {
background: linear-gradient(45deg, #667eea, #764ba2);
color: white;
}

.btn-primary:hover:not(:disabled) {
transform: translateY(-3px);
box-shadow: 0 10px 20px rgba(102, 126, 234, 0.4);
}

.btn-secondary {
background: linear-gradient(45deg, #95a5a6, #7f8c8d);
color: white;
}

.btn-secondary:hover:not(:disabled) {
transform: translateY(-3px);
box-shadow: 0 10px 20px rgba(149, 165, 166, 0.4);
}

.btn-success {
background: linear-gradient(45deg, #2ecc71, #27ae60);
color: white;
}

.btn-success:hover:not(:disabled) {
transform: translateY(-3px);
box-shadow: 0 10px 20px rgba(46, 204, 113, 0.4);
}

.progress-container {
margin-top: 30px;
display: none;
}

.progress-container.active {
display: block;
}

.progress-bar {
width: 100%;
height: 20px;
background: #ecf0f1;
border-radius: 10px;
overflow: hidden;
margin: 10px 0;
}

.progress-fill {
height: 100%;
background: linear-gradient(45deg, #2ecc71, #27ae60);
width: 0%;
transition: width 0.5s ease;
}

.log-container {
background: #2c3e50;
color: #ecf0f1;
padding: 20px;
border-radius: 10px;
font-family: 'Courier New', monospace;
height: 200px;
overflow-y: auto;
margin-top: 20px;
}

.status-indicator {
width: 12px;
height: 12px;
border-radius: 50%;
display: inline-block;
margin-right: 8px;
}

.status-pending { background: #f39c12; }
.status-syncing { background: #3498db; animation: pulse 1s infinite; }
.status-success { background: #2ecc71; }
.status-error { background: #e74c3c; }

@keyframes pulse {
0% { transform: scale(1); opacity: 1; }
50% { transform: scale(1.2); opacity: 0.7; }
100% { transform: scale(1); opacity: 1; }
}

.toggle-icon {
transition: transform 0.3s ease;
}

.toggle-icon.rotated {
transform: rotate(180deg);
}

.loading-spinner {
border: 3px solid #f3f3f3;
border-top: 3px solid #3498db;
border-radius: 50%;
width: 20px;
height: 20px;
animation: spin 1s linear infinite;
display: inline-block;
}

@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}

.error-message {
background: rgba(231, 76, 60, 0.1);
color: #e74c3c;
padding: 15px;
border-radius: 10px;
margin: 15px 0;
border-left: 4px solid #e74c3c;
}

.modal {
display: none;
position: fixed;
z-index: 1000;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
backdrop-filter: blur(5px);
}

.modal-content {
background-color: white;
margin: 15% auto;
padding: 30px;
border-radius: 15px;
width: 400px;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
text-align: center;
}

.modal-content h3 {
color: #2c3e50;
margin-bottom: 20px;
}

.modal-input {
width: 100%;
padding: 12px;
border: 2px solid #ddd;
border-radius: 8px;
font-size: 1rem;
margin: 15px 0;
}

.modal-input:focus {
outline: none;
border-color: #667eea;
}

.modal-buttons {
display: flex;
gap: 15px;
justify-content: center;
margin-top: 20px;
}

.btn-modal {
padding: 10px 20px;
border: none;
border-radius: 8px;
cursor: pointer;
font-weight: 600;
}

.btn-modal-primary {
background: linear-gradient(45deg, #667eea, #764ba2);
color: white;

Files changed (2) hide show
  1. README.md +8 -5
  2. index.html +391 -19
README.md CHANGED
@@ -1,10 +1,13 @@
1
  ---
2
- title: Syncflow Pro Database Harmony Orchestrator
3
- emoji: 😻
4
- colorFrom: red
5
- colorTo: green
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
1
  ---
2
+ title: SyncFlow Pro - Database Harmony Orchestrator πŸš€
3
+ colorFrom: pink
4
+ colorTo: pink
5
+ emoji: 🐳
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite-v3
10
  ---
11
 
12
+ # Welcome to your new DeepSite project!
13
+ This project was created with [DeepSite](https://deepsite.hf.co).
index.html CHANGED
@@ -1,19 +1,391 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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>SyncFlow Pro - Database Harmony Orchestrator</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/vanta@latest/dist/vanta.globe.min.js"></script>
10
+ <script>
11
+ tailwind.config = {
12
+ theme: {
13
+ extend: {
14
+ colors: {
15
+ primary: '#667eea',
16
+ secondary: '#764ba2',
17
+ success: '#2ecc71',
18
+ warning: '#f39c12',
19
+ danger: '#e74c3c',
20
+ dark: '#2c3e50',
21
+ light: '#ecf0f1'
22
+ },
23
+ animation: {
24
+ 'pulse-slow': 'pulse 3s cubic-bezier(0.4, 0, 0.6, 1) infinite',
25
+ 'bounce-slow': 'bounce 2s infinite',
26
+ 'float': 'float 6s ease-in-out infinite',
27
+ },
28
+ keyframes: {
29
+ float: {
30
+ '0%, 100%': { transform: 'translateY(0px)' },
31
+ '50%': { transform: 'translateY(-20px)' },
32
+ }
33
+ }
34
+ }
35
+ }
36
+ }
37
+ </script>
38
+ <style>
39
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
40
+
41
+ * {
42
+ margin: 0;
43
+ padding: 0;
44
+ box-sizing: border-box;
45
+ }
46
+
47
+ body {
48
+ font-family: 'Inter', sans-serif;
49
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
50
+ min-height: 100vh;
51
+ }
52
+
53
+ .glass-effect {
54
+ background: rgba(255, 255, 255, 0.95);
55
+ backdrop-filter: blur(20px);
56
+ border: 1px solid rgba(255, 255, 255, 0.2);
57
+ }
58
+
59
+ .gradient-text {
60
+ background: linear-gradient(45deg, #667eea, #764ba2);
61
+ -webkit-background-clip: text;
62
+ -webkit-text-fill-color: transparent;
63
+ background-clip: text;
64
+ }
65
+
66
+ .status-glow {
67
+ box-shadow: 0 0 20px rgba(46, 204, 113, 0.4);
68
+ }
69
+
70
+ .sync-pulse {
71
+ animation: pulse 2s infinite;
72
+ }
73
+
74
+ @keyframes pulse {
75
+ 0% { transform: scale(1); }
76
+ 50% { transform: scale(1.05); }
77
+ 100% { transform: scale(1); }
78
+ }
79
+
80
+ .progress-gradient {
81
+ background: linear-gradient(90deg, #2ecc71, #3498db, #9b59b6);
82
+ background-size: 200% 100%;
83
+ animation: gradientShift 3s ease infinite;
84
+ }
85
+
86
+ @keyframes gradientShift {
87
+ 0% { background-position: 0% 50%; }
88
+ 50% { background-position: 100% 50%; }
89
+ 100% { background-position: 0% 50%; }
90
+ }
91
+
92
+ .log-entry {
93
+ border-left: 3px solid;
94
+ padding-left: 10px;
95
+ margin: 5px 0;
96
+ transition: all 0.3s ease;
97
+ }
98
+
99
+ .log-entry:hover {
100
+ transform: translateX(5px);
101
+ background: rgba(255, 255, 255, 0.1);
102
+ }
103
+
104
+ .floating-card {
105
+ animation: float 6s ease-in-out infinite;
106
+ }
107
+
108
+ .holographic-effect {
109
+ background: linear-gradient(45deg,
110
+ rgba(102, 126, 234, 0.1),
111
+ rgba(118, 75, 162, 0.1),
112
+ rgba(46, 204, 113, 0.1));
113
+ position: relative;
114
+ overflow: hidden;
115
+ }
116
+
117
+ .holographic-effect::before {
118
+ content: '';
119
+ position: absolute;
120
+ top: -50%;
121
+ left: -50%;
122
+ width: 200%;
123
+ height: 200%;
124
+ background: linear-gradient(45deg,
125
+ transparent,
126
+ rgba(255, 255, 255, 0.1),
127
+ transparent);
128
+ transform: rotate(45deg);
129
+ animation: shine 3s infinite;
130
+ }
131
+
132
+ @keyframes shine {
133
+ 0% { transform: translateX(-100%) translateY(-100%) rotate(45deg); }
134
+ 100% { transform: translateX(100%) translateY(100%) rotate(45deg); }
135
+ }
136
+ </style>
137
+ </head>
138
+ <body class="min-h-screen relative overflow-x-hidden">
139
+ <!-- Animated Background -->
140
+ <div id="vanta-bg" class="absolute inset-0 z-0"></div>
141
+
142
+ <!-- Main Container -->
143
+ <div class="relative z-10 min-h-screen flex items-center justify-center p-4">
144
+ <div class="w-full max-w-7xl mx-auto">
145
+ <!-- Header Section -->
146
+ <div class="text-center mb-12 floating-card">
147
+ <div class="glass-effect rounded-2xl p-8 shadow-2xl border border-white/20">
148
+ <h1 class="text-5xl md:text-6xl font-bold gradient-text mb-4">
149
+ πŸ”„ SyncFlow Pro
150
+ </h1>
151
+ <p class="text-xl text-gray-600 mb-6">Database Harmony Orchestrator</p>
152
+ <div class="flex justify-center space-x-4">
153
+ <span class="px-4 py-2 bg-green-100 text-green-800 rounded-full text-sm font-medium flex items-center">
154
+ <span class="w-2 h-2 bg-green-500 rounded-full mr-2 animate-pulse"></span>
155
+ Real-time Monitoring
156
+ </span>
157
+ <span class="px-4 py-2 bg-blue-100 text-blue-800 rounded-full text-sm font-medium flex items-center">
158
+ <span class="w-2 h-2 bg-blue-500 rounded-full mr-2"></span>
159
+ AI-Powered Mapping
160
+ </span>
161
+ <span class="px-4 py-2 bg-purple-100 text-purple-800 rounded-full text-sm font-medium flex items-center">
162
+ <span class="w-2 h-2 bg-purple-500 rounded-full mr-2"></span>
163
+ Enterprise Ready
164
+ </span>
165
+ </div>
166
+ </div>
167
+ </div>
168
+
169
+ <!-- Connection Status Dashboard -->
170
+ <div class="glass-effect rounded-2xl p-6 shadow-2xl border border-white/20 mb-8">
171
+ <h2 class="text-2xl font-bold text-gray-800 mb-6 flex items-center">
172
+ <i data-feather="activity" class="mr-3"></i>
173
+ Connection Dashboard
174
+ </h2>
175
+ <div id="connection-status" class="grid grid-cols-1 md:grid-cols-4 gap-4">
176
+ <!-- Status cards will be populated here -->
177
+ </div>
178
+ </div>
179
+
180
+ <!-- Main Sync Interface -->
181
+ <div class="grid grid-cols-1 lg:grid-cols-3 gap-8 mb-8">
182
+ <!-- Regions Panel -->
183
+ <div class="glass-effect rounded-2xl p-6 shadow-2xl border border-white/20">
184
+ <h3 class="text-xl font-bold text-gray-800 mb-4 flex items-center">
185
+ <i data-feather="map-pin" class="mr-2"></i>
186
+ πŸ“ Regions & Tables
187
+ </h3>
188
+ <div id="regions-list" class="space-y-4">
189
+ <div class="flex items-center justify-center py-8">
190
+ <div class="animate-spin rounded-full h-8 w-8 border-b-2 border-primary"></div>
191
+ <span class="ml-3 text-gray-600">Loading configuration...</span>
192
+ </div>
193
+ </div>
194
+ </div>
195
+
196
+ <!-- Tables Selection -->
197
+ <div class="glass-effect rounded-2xl p-6 shadow-2xl border border-white/20">
198
+ <h3 class="text-xl font-bold text-gray-800 mb-4 flex items-center">
199
+ <i data-feather="database" class="mr-2"></i>
200
+ πŸ“Š Tables to Sync
201
+ </h3>
202
+ <div id="tables-list" class="h-64 overflow-y-auto">
203
+ <div class="text-center py-8 text-gray-500">
204
+ <i data-feather="database" class="w-12 h-12 mx-auto mb-4 text-gray-300"></i>
205
+ <p>Select a region to see available tables</p>
206
+ </div>
207
+ </div>
208
+ <div class="mt-4 p-4 bg-blue-50 rounded-lg">
209
+ <div class="flex justify-between items-center">
210
+ <span class="font-medium text-blue-800">Selected Tables:</span>
211
+ <span id="selected-count" class="text-2xl font-bold text-blue-600">0</span>
212
+ </div>
213
+ </div>
214
+ </div>
215
+
216
+ <!-- Configuration Summary -->
217
+ <div class="glass-effect rounded-2xl p-6 shadow-2xl border border-white/20">
218
+ <h3 class="text-xl font-bold text-gray-800 mb-4 flex items-center">
219
+ <i data-feather="settings" class="mr-2"></i>
220
+ βš™οΈ Sync Configuration
221
+ </h3>
222
+ <div class="space-y-4">
223
+ <div class="holographic-effect rounded-lg p-4 text-center">
224
+ <div class="text-3xl font-bold text-gray-800 mb-2" id="mapping-percentage">0%</div>
225
+ <div class="text-sm text-gray-600">Auto-Mapping Complete</div>
226
+ <div class="w-full bg-gray-200 rounded-full h-2 mt-2">
227
+ <div id="mapping-progress" class="progress-gradient h-2 rounded-full transition-all duration-500" style="width: 0%"></div>
228
+ </div>
229
+ </div>
230
+
231
+ <div class="grid grid-cols-2 gap-4">
232
+ <div class="bg-green-50 p-3 rounded-lg text-center">
233
+ <div class="text-2xl font-bold text-green-600" id="mapped-count">0</div>
234
+ <div class="text-sm text-green-800">Mapped Columns</div>
235
+ </div>
236
+ <div class="bg-orange-50 p-3 rounded-lg text-center">
237
+ <div class="text-2xl font-bold text-orange-600" id="unmapped-count">0</div>
238
+ <div class="text-sm text-orange-800">Needs Review</div>
239
+ </div>
240
+ </div>
241
+ </div>
242
+ </div>
243
+ </div>
244
+
245
+ <!-- Column Mapping Section -->
246
+ <div id="column-mapping" class="glass-effect rounded-2xl p-6 shadow-2xl border border-white/20 mb-8 hidden">
247
+ <h3 class="text-xl font-bold text-gray-800 mb-4 flex items-center">
248
+ <i data-feather="link" class="mr-2"></i>
249
+ πŸ”— Intelligent Column Mapping
250
+ </h3>
251
+ <div id="mapping-container" class="space-y-4">
252
+ <!-- Mapping content will be populated here -->
253
+ </div>
254
+ </div>
255
+
256
+ <!-- Action Buttons -->
257
+ <div class="glass-effect rounded-2xl p-6 shadow-2xl border border-white/20 mb-8">
258
+ <div class="flex flex-wrap gap-4 justify-center">
259
+ <button onclick="loadConfiguration()" class="px-6 py-3 bg-gray-600 text-white rounded-lg font-medium hover:bg-gray-700 transition-all duration-300 transform hover:scale-105 flex items-center">
260
+ <i data-feather="folder" class="mr-2"></i>
261
+ πŸ“ Load Config
262
+ </button>
263
+ <button onclick="saveConfigurationWithName()" class="px-6 py-3 bg-purple-600 text-white rounded-lg font-medium hover:bg-purple-700 transition-all duration-300 transform hover:scale-105 flex items-center">
264
+ <i data-feather="save" class="mr-2"></i>
265
+ πŸ’Ύ Save Config
266
+ </button>
267
+ <button onclick="selectAllTables()" class="px-6 py-3 bg-blue-600 text-white rounded-lg font-medium hover:bg-blue-700 transition-all duration-300 transform hover:scale-105 flex items-center">
268
+ <i data-feather="check-square" class="mr-2"></i>
269
+ πŸ“‹ Select All Tables
270
+ </button>
271
+ <button onclick="startSync()" id="sync-button" class="px-8 py-3 bg-gradient-to-r from-green-500 to-blue-500 text-white rounded-lg font-bold hover:from-green-600 hover:to-blue-600 transition-all duration-300 transform hover:scale-105 sync-pulse flex items-center">
272
+ <i data-feather="play" class="mr-2"></i>
273
+ πŸš€ Start Sync
274
+ </button>
275
+ </div>
276
+ </div>
277
+
278
+ <!-- Progress and Logs -->
279
+ <div id="progress-container" class="glass-effect rounded-2xl p-6 shadow-2xl border border-white/20 hidden">
280
+ <h3 class="text-xl font-bold text-gray-800 mb-4 flex items-center">
281
+ <i data-feather="bar-chart-2" class="mr-2"></i>
282
+ πŸ“ˆ Sync Progress
283
+ </h3>
284
+
285
+ <div class="mb-6">
286
+ <div class="flex justify-between mb-2">
287
+ <span class="font-medium text-gray-700">Sync Progress</span>
288
+ <span id="progress-percentage" class="font-bold text-blue-600">0%</span>
289
+ </div>
290
+ <div class="w-full bg-gray-200 rounded-full h-4">
291
+ <div id="progress-fill" class="progress-gradient h-4 rounded-full transition-all duration-500" style="width: 0%"></div>
292
+ </div>
293
+ </div>
294
+
295
+ <div class="bg-gray-900 rounded-lg p-4">
296
+ <div class="flex justify-between items-center mb-3">
297
+ <span class="text-white font-medium">Sync Logs</span>
298
+ <button onclick="clearLogs()" class="text-gray-400 hover:text-white text-sm">
299
+ <i data-feather="trash-2" class="w-4 h-4"></i>
300
+ </button>
301
+ </div>
302
+ <div id="sync-log" class="h-48 overflow-y-auto font-mono text-sm text-green-400 bg-black/30 rounded p-3">
303
+ <div class="log-entry border-l-green-500">Ready to start synchronization...</div>
304
+ </div>
305
+ </div>
306
+ </div>
307
+ </div>
308
+ </div>
309
+
310
+ <!-- Save Config Modal -->
311
+ <div id="saveConfigModal" class="fixed inset-0 bg-black/50 flex items-center justify-center z-50 hidden">
312
+ <div class="glass-effect rounded-2xl p-8 max-w-md w-full mx-4 shadow-2xl border border-white/20">
313
+ <h3 class="text-2xl font-bold text-gray-800 mb-4 flex items-center">
314
+ <i data-feather="save" class="mr-3"></i>
315
+ πŸ’Ύ Save Configuration
316
+ </h3>
317
+ <p class="text-gray-600 mb-4">Enter a name for your configuration file:</p>
318
+ <input type="text" id="configNameInput" class="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:border-blue-500 transition-colors" placeholder="e.g., weekly-sync-config">
319
+ <div class="flex gap-3 mt-6">
320
+ <button onclick="closeSaveConfigModal()" class="flex-1 px-4 py-3 bg-gray-500 text-white rounded-lg font-medium hover:bg-gray-600 transition-colors">
321
+ Cancel
322
+ </button>
323
+ <button onclick="saveConfigWithName()" class="flex-1 px-4 py-3 bg-blue-600 text-white rounded-lg font-medium hover:bg-blue-700 transition-colors">
324
+ Save Configuration
325
+ </button>
326
+ </div>
327
+ </div>
328
+ </div>
329
+
330
+ <script>
331
+ // Initialize Vanta.js background
332
+ VANTA.GLOBE({
333
+ el: "#vanta-bg",
334
+ mouseControls: true,
335
+ touchControls: true,
336
+ gyroControls: false,
337
+ minHeight: 200.00,
338
+ minWidth: 200.00,
339
+ scale: 1.00,
340
+ scaleMobile: 1.00,
341
+ color: 0x667eea,
342
+ color2: 0x764ba2,
343
+ backgroundColor: 0x0
344
+ });
345
+
346
+ // API base URL - adjust as needed
347
+ const API_BASE = '/api';
348
+
349
+ let configData = {};
350
+ let selectedTables = [];
351
+ let columnMappings = {};
352
+ let sourceColumnsCache = {};
353
+ let targetColumnsCache = {};
354
+
355
+ // Initialize the interface
356
+ async function initializeInterface() {
357
+ await loadConfig();
358
+ await checkConnections();
359
+ feather.replace();
360
+ }
361
+
362
+ async function loadConfig() {
363
+ try {
364
+ showLoading('regions-list', 'Loading configuration...');
365
+ const response = await fetch(`${API_BASE}/config`);
366
+ const data = await response.json();
367
+
368
+ if (data.success) {
369
+ configData = data.config;
370
+ loadRegions();
371
+ } else {
372
+ showError('Failed to load configuration: ' + data.error);
373
+ }
374
+ } catch (error) {
375
+ showError('Error loading configuration: ' + error.message);
376
+ }
377
+ }
378
+
379
+ async function checkConnections() {
380
+ const statusContainer = document.getElementById('connection-status');
381
+ const regions = ['webapp', ...Object.keys(configData)];
382
+
383
+ statusContainer.innerHTML = '';
384
+
385
+ for (const region of regions) {
386
+ const statusCard = document.createElement('div');
387
+ statusCard.className = 'bg-white/80 rounded-xl p-4 shadow-lg border';
388
+ statusCard.innerHTML = `
389
+ <div class="flex items-center justify-between mb-2">
390
+ </body>
391
+ </html>