kawish14's picture
<!DOCTYPE html>
bd692f7 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SyncFlow Pro - Database Harmony Orchestrator</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://unpkg.com/feather-icons"></script>
<script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.globe.min.js"></script>
<script>
tailwind.config = {
theme: {
extend: {
colors: {
primary: '#667eea',
secondary: '#764ba2',
success: '#2ecc71',
warning: '#f39c12',
danger: '#e74c3c',
dark: '#2c3e50',
light: '#ecf0f1'
},
animation: {
'pulse-slow': 'pulse 3s cubic-bezier(0.4, 0, 0.6, 1) infinite',
'bounce-slow': 'bounce 2s infinite',
'float': 'float 6s ease-in-out infinite',
},
keyframes: {
float: {
'0%, 100%': { transform: 'translateY(0px)' },
'50%': { transform: 'translateY(-20px)' },
}
}
}
}
}
</script>
<style>
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Inter', sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
}
.glass-effect {
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(20px);
border: 1px solid rgba(255, 255, 255, 0.2);
}
.gradient-text {
background: linear-gradient(45deg, #667eea, #764ba2);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.status-glow {
box-shadow: 0 0 20px rgba(46, 204, 113, 0.4);
}
.sync-pulse {
animation: pulse 2s infinite;
}
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.05); }
100% { transform: scale(1); }
}
.progress-gradient {
background: linear-gradient(90deg, #2ecc71, #3498db, #9b59b6);
background-size: 200% 100%;
animation: gradientShift 3s ease infinite;
}
@keyframes gradientShift {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
.log-entry {
border-left: 3px solid;
padding-left: 10px;
margin: 5px 0;
transition: all 0.3s ease;
}
.log-entry:hover {
transform: translateX(5px);
background: rgba(255, 255, 255, 0.1);
}
.floating-card {
animation: float 6s ease-in-out infinite;
}
.holographic-effect {
background: linear-gradient(45deg,
rgba(102, 126, 234, 0.1),
rgba(118, 75, 162, 0.1),
rgba(46, 204, 113, 0.1));
position: relative;
overflow: hidden;
}
.holographic-effect::before {
content: '';
position: absolute;
top: -50%;
left: -50%;
width: 200%;
height: 200%;
background: linear-gradient(45deg,
transparent,
rgba(255, 255, 255, 0.1),
transparent);
transform: rotate(45deg);
animation: shine 3s infinite;
}
@keyframes shine {
0% { transform: translateX(-100%) translateY(-100%) rotate(45deg); }
100% { transform: translateX(100%) translateY(100%) rotate(45deg); }
}
</style>
</head>
<body class="min-h-screen relative overflow-x-hidden">
<!-- Animated Background -->
<div id="vanta-bg" class="absolute inset-0 z-0"></div>
<!-- Main Container -->
<div class="relative z-10 min-h-screen flex items-center justify-center p-4">
<div class="w-full max-w-7xl mx-auto">
<!-- Header Section -->
<div class="text-center mb-12 floating-card">
<div class="glass-effect rounded-2xl p-8 shadow-2xl border border-white/20">
<h1 class="text-5xl md:text-6xl font-bold gradient-text mb-4">
πŸ”„ SyncFlow Pro
</h1>
<p class="text-xl text-gray-600 mb-6">Database Harmony Orchestrator</p>
<div class="flex justify-center space-x-4">
<span class="px-4 py-2 bg-green-100 text-green-800 rounded-full text-sm font-medium flex items-center">
<span class="w-2 h-2 bg-green-500 rounded-full mr-2 animate-pulse"></span>
Real-time Monitoring
</span>
<span class="px-4 py-2 bg-blue-100 text-blue-800 rounded-full text-sm font-medium flex items-center">
<span class="w-2 h-2 bg-blue-500 rounded-full mr-2"></span>
AI-Powered Mapping
</span>
<span class="px-4 py-2 bg-purple-100 text-purple-800 rounded-full text-sm font-medium flex items-center">
<span class="w-2 h-2 bg-purple-500 rounded-full mr-2"></span>
Enterprise Ready
</span>
</div>
</div>
</div>
<!-- Connection Status Dashboard -->
<div class="glass-effect rounded-2xl p-6 shadow-2xl border border-white/20 mb-8">
<h2 class="text-2xl font-bold text-gray-800 mb-6 flex items-center">
<i data-feather="activity" class="mr-3"></i>
Connection Dashboard
</h2>
<div id="connection-status" class="grid grid-cols-1 md:grid-cols-4 gap-4">
<!-- Status cards will be populated here -->
</div>
</div>
<!-- Main Sync Interface -->
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8 mb-8">
<!-- Regions Panel -->
<div class="glass-effect rounded-2xl p-6 shadow-2xl border border-white/20">
<h3 class="text-xl font-bold text-gray-800 mb-4 flex items-center">
<i data-feather="map-pin" class="mr-2"></i>
πŸ“ Regions & Tables
</h3>
<div id="regions-list" class="space-y-4">
<div class="flex items-center justify-center py-8">
<div class="animate-spin rounded-full h-8 w-8 border-b-2 border-primary"></div>
<span class="ml-3 text-gray-600">Loading configuration...</span>
</div>
</div>
</div>
<!-- Tables Selection -->
<div class="glass-effect rounded-2xl p-6 shadow-2xl border border-white/20">
<h3 class="text-xl font-bold text-gray-800 mb-4 flex items-center">
<i data-feather="database" class="mr-2"></i>
πŸ“Š Tables to Sync
</h3>
<div id="tables-list" class="h-64 overflow-y-auto">
<div class="text-center py-8 text-gray-500">
<i data-feather="database" class="w-12 h-12 mx-auto mb-4 text-gray-300"></i>
<p>Select a region to see available tables</p>
</div>
</div>
<div class="mt-4 p-4 bg-blue-50 rounded-lg">
<div class="flex justify-between items-center">
<span class="font-medium text-blue-800">Selected Tables:</span>
<span id="selected-count" class="text-2xl font-bold text-blue-600">0</span>
</div>
</div>
</div>
<!-- Configuration Summary -->
<div class="glass-effect rounded-2xl p-6 shadow-2xl border border-white/20">
<h3 class="text-xl font-bold text-gray-800 mb-4 flex items-center">
<i data-feather="settings" class="mr-2"></i>
βš™οΈ Sync Configuration
</h3>
<div class="space-y-4">
<div class="holographic-effect rounded-lg p-4 text-center">
<div class="text-3xl font-bold text-gray-800 mb-2" id="mapping-percentage">0%</div>
<div class="text-sm text-gray-600">Auto-Mapping Complete</div>
<div class="w-full bg-gray-200 rounded-full h-2 mt-2">
<div id="mapping-progress" class="progress-gradient h-2 rounded-full transition-all duration-500" style="width: 0%"></div>
</div>
</div>
<div class="grid grid-cols-2 gap-4">
<div class="bg-green-50 p-3 rounded-lg text-center">
<div class="text-2xl font-bold text-green-600" id="mapped-count">0</div>
<div class="text-sm text-green-800">Mapped Columns</div>
</div>
<div class="bg-orange-50 p-3 rounded-lg text-center">
<div class="text-2xl font-bold text-orange-600" id="unmapped-count">0</div>
<div class="text-sm text-orange-800">Needs Review</div>
</div>
</div>
</div>
</div>
</div>
<!-- Column Mapping Section -->
<div id="column-mapping" class="glass-effect rounded-2xl p-6 shadow-2xl border border-white/20 mb-8 hidden">
<h3 class="text-xl font-bold text-gray-800 mb-4 flex items-center">
<i data-feather="link" class="mr-2"></i>
πŸ”— Intelligent Column Mapping
</h3>
<div id="mapping-container" class="space-y-4">
<!-- Mapping content will be populated here -->
</div>
</div>
<!-- Action Buttons -->
<div class="glass-effect rounded-2xl p-6 shadow-2xl border border-white/20 mb-8">
<div class="flex flex-wrap gap-4 justify-center">
<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">
<i data-feather="folder" class="mr-2"></i>
πŸ“ Load Config
</button>
<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">
<i data-feather="save" class="mr-2"></i>
πŸ’Ύ Save Config
</button>
<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">
<i data-feather="check-square" class="mr-2"></i>
πŸ“‹ Select All Tables
</button>
<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">
<i data-feather="play" class="mr-2"></i>
πŸš€ Start Sync
</button>
</div>
</div>
<!-- Progress and Logs -->
<div id="progress-container" class="glass-effect rounded-2xl p-6 shadow-2xl border border-white/20 hidden">
<h3 class="text-xl font-bold text-gray-800 mb-4 flex items-center">
<i data-feather="bar-chart-2" class="mr-2"></i>
πŸ“ˆ Sync Progress
</h3>
<div class="mb-6">
<div class="flex justify-between mb-2">
<span class="font-medium text-gray-700">Sync Progress</span>
<span id="progress-percentage" class="font-bold text-blue-600">0%</span>
</div>
<div class="w-full bg-gray-200 rounded-full h-4">
<div id="progress-fill" class="progress-gradient h-4 rounded-full transition-all duration-500" style="width: 0%"></div>
</div>
</div>
<div class="bg-gray-900 rounded-lg p-4">
<div class="flex justify-between items-center mb-3">
<span class="text-white font-medium">Sync Logs</span>
<button onclick="clearLogs()" class="text-gray-400 hover:text-white text-sm">
<i data-feather="trash-2" class="w-4 h-4"></i>
</button>
</div>
<div id="sync-log" class="h-48 overflow-y-auto font-mono text-sm text-green-400 bg-black/30 rounded p-3">
<div class="log-entry border-l-green-500">Ready to start synchronization...</div>
</div>
</div>
</div>
</div>
</div>
<!-- Save Config Modal -->
<div id="saveConfigModal" class="fixed inset-0 bg-black/50 flex items-center justify-center z-50 hidden">
<div class="glass-effect rounded-2xl p-8 max-w-md w-full mx-4 shadow-2xl border border-white/20">
<h3 class="text-2xl font-bold text-gray-800 mb-4 flex items-center">
<i data-feather="save" class="mr-3"></i>
πŸ’Ύ Save Configuration
</h3>
<p class="text-gray-600 mb-4">Enter a name for your configuration file:</p>
<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">
<div class="flex gap-3 mt-6">
<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">
Cancel
</button>
<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">
Save Configuration
</button>
</div>
</div>
</div>
<script>
// Initialize Vanta.js background
VANTA.GLOBE({
el: "#vanta-bg",
mouseControls: true,
touchControls: true,
gyroControls: false,
minHeight: 200.00,
minWidth: 200.00,
scale: 1.00,
scaleMobile: 1.00,
color: 0x667eea,
color2: 0x764ba2,
backgroundColor: 0x0
});
// API base URL - adjust as needed
const API_BASE = '/api';
let configData = {};
let selectedTables = [];
let columnMappings = {};
let sourceColumnsCache = {};
let targetColumnsCache = {};
// Initialize the interface
async function initializeInterface() {
await loadConfig();
await checkConnections();
feather.replace();
}
async function loadConfig() {
try {
showLoading('regions-list', 'Loading configuration...');
const response = await fetch(`${API_BASE}/config`);
const data = await response.json();
if (data.success) {
configData = data.config;
loadRegions();
} else {
showError('Failed to load configuration: ' + data.error);
}
} catch (error) {
showError('Error loading configuration: ' + error.message);
}
}
async function checkConnections() {
const statusContainer = document.getElementById('connection-status');
const regions = ['webapp', ...Object.keys(configData)];
statusContainer.innerHTML = '';
for (const region of regions) {
const statusCard = document.createElement('div');
statusCard.className = 'bg-white/80 rounded-xl p-4 shadow-lg border';
statusCard.innerHTML = `
<div class="flex items-center justify-between mb-2">
</body>
</html>