diff --git a/App.jsx b/App.jsx new file mode 100644 index 0000000..79f371b --- /dev/null +++ b/App.jsx @@ -0,0 +1,101 @@ +import { Routes, Route, Link, useLocation } from "react-router-dom"; +import { useState, useEffect } from "react"; +import MySQLMySQLMigrator from "./components/MySQLMySQLMigrator"; +import PostgreSQLPostgreSQLMigrator from "./components/PostgreSQLPostgreSQLMigrator"; +import PostgreSQLS3Migrator from "./components/PostgreSQLS3Migrator"; +import S3S3Migrator from "./components/S3S3Migrator"; + +export default function App() { + const [darkMode, setDarkMode] = useState(() => { + const saved = localStorage.getItem('darkMode'); + return saved ? JSON.parse(saved) : true; // Default to dark mode + }); + + const location = useLocation(); + + useEffect(() => { + localStorage.setItem('darkMode', JSON.stringify(darkMode)); + if (darkMode) { + document.body.classList.add('dark'); + } else { + document.body.classList.remove('dark'); + } + }, [darkMode]); + + const navItems = [ + { path: "/mysql-mysql", label: "MySQL → MySQL", icon: "🗄️" }, + { path: "/psql-psql", label: "PostgreSQL → PostgreSQL", icon: "🐘" }, + { path: "/psql-s3", label: "PostgreSQL → S3", icon: "☁️" }, + { path: "/s3-s3", label: "S3 → S3", icon: "📦" }, + ]; + + return ( +
+
+ {/* Header */} +
+
+
+

+ Universal Database Migrator +

+

+ Seamlessly migrate your databases across platforms +

+
+ +
+
+ + {/* Navigation */} + + + {/* Main Content */} +
+ + } /> + } /> + } /> + } /> + +
🚀
+

Welcome to Universal Migrator

+

+ Choose a migration type from the navigation above to get started. +

+
+ } + /> + + +
+ + ); +} \ No newline at end of file diff --git a/api.js b/api.js new file mode 100644 index 0000000..5d0946f --- /dev/null +++ b/api.js @@ -0,0 +1,69 @@ +// API Base URL من متغيرات البيئة +const API_BASE = import.meta.env.VITE_API_BASE ?? ""; + +// ========================= +// Schemas +// ========================= +async function getSchemas(type, payload) { + const r = await fetch(`${API_BASE}/api/get_schemas`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + type, + ...payload + }) + }); + return r.json(); +} + +// ========================= +// Tables +// ========================= +async function getTables(type, payload) { + const r = await fetch(`${API_BASE}/api/get_tables`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + type, + ...payload + }) + }); + return r.json(); +} + +// ========================= +// Start Migration +// ========================= +async function startMigration(type, payload) { + const r = await fetch(`${API_BASE}/api/migrate`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + type, + ...payload + }) + }); + return r.json(); +} + +// ========================= +// Progress +// ========================= +async function getProgress(type) { + const r = await fetch(`${API_BASE}/api/progress/${type}`); + return r.json(); +} + +// ========================= +// List Buckets +// ========================= +async function listBuckets(payload) { + const r = await fetch(`${API_BASE}/api/list_buckets`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(payload) + }); + return r.json(); +} + +export { getSchemas, getTables, startMigration, getProgress, listBuckets }; \ No newline at end of file diff --git a/main.jsx b/main.jsx new file mode 100644 index 0000000..8cc8d25 --- /dev/null +++ b/main.jsx @@ -0,0 +1,13 @@ +import React from "react"; +import ReactDOM from "react-dom/client"; +import { BrowserRouter } from "react-router-dom"; +import App from "./App.jsx"; +import "./styles.css"; + +ReactDOM.createRoot(document.getElementById("root")).render( + + + + + +); \ No newline at end of file diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000..af9d8dc --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,6 @@ +export default { + plugins: { + '@tailwindcss/postcss': {}, + autoprefixer: {}, + }, +} \ No newline at end of file diff --git a/vite.config.js b/vite.config.js new file mode 100644 index 0000000..c40fc47 --- /dev/null +++ b/vite.config.js @@ -0,0 +1,19 @@ +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [react()], + build: { + outDir: '../dist', // البناء ينتج مجلد dist خارج frontend + emptyOutDir: true + }, + server: { + proxy: { + '/api': { + target: 'http://localhost:8001', + changeOrigin: true + } + } + } +}); \ No newline at end of file