Created
January 21, 2025 09:36
-
-
Save baditaflorin/313b78119578b42480f30e8249de3257 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Create a new React application | |
npx create-react-app database-frontend | |
cd database-frontend | |
# Install required dependencies | |
npm install tailwindcss postcss autoprefixer lucide-react | |
# Initialize Tailwind CSS | |
npx tailwindcss init -p | |
# Create Tailwind config file | |
cat > tailwind.config.js << EOL | |
/** @type {import('tailwindcss').Config} */ | |
module.exports = { | |
content: [ | |
"./src/**/*.{js,jsx,ts,tsx}", | |
], | |
theme: { | |
extend: {}, | |
}, | |
plugins: [], | |
} | |
EOL | |
# Update index.css with Tailwind directives | |
cat > src/index.css << EOL | |
@tailwind base; | |
@tailwind components; | |
@tailwind utilities; | |
EOL | |
# Create DatabaseDemo component | |
mkdir -p src/components | |
cat > src/components/DatabaseDemo.jsx << EOL | |
$(cat << 'END_OF_COMPONENT' | |
import React, { useState } from 'react'; | |
import { AlertCircle, CheckCircle2 } from 'lucide-react'; | |
const DatabaseDemo = () => { | |
const [token, setToken] = useState(''); | |
const [message, setMessage] = useState(''); | |
const [messageType, setMessageType] = useState(''); | |
const [tableName, setTableName] = useState(''); | |
const [tableData, setTableData] = useState([]); | |
const [loading, setLoading] = useState(false); | |
const baseUrl = 'http://localhost:48080'; | |
const showMessage = (text, type = 'info') => { | |
setMessage(text); | |
setMessageType(type); | |
setTimeout(() => setMessage(''), 5000); | |
}; | |
const handleRegister = async () => { | |
try { | |
setLoading(true); | |
const response = await fetch(`${baseUrl}/auth/register`, { | |
method: 'POST', | |
headers: { 'Content-Type': 'application/json' }, | |
body: JSON.stringify({ | |
username: 'testuser', | |
password: 'testpassword123' | |
}) | |
}); | |
const data = await response.json(); | |
if (response.ok) { | |
showMessage('Registration successful!', 'success'); | |
} else { | |
showMessage(data.error || 'Registration failed', 'error'); | |
} | |
} catch (error) { | |
showMessage('Failed to connect to server', 'error'); | |
} finally { | |
setLoading(false); | |
} | |
}; | |
const handleLogin = async () => { | |
try { | |
setLoading(true); | |
const response = await fetch(`${baseUrl}/auth/login`, { | |
method: 'POST', | |
headers: { 'Content-Type': 'application/json' }, | |
body: JSON.stringify({ | |
username: 'testuser', | |
password: 'testpassword123' | |
}) | |
}); | |
const data = await response.json(); | |
if (response.ok) { | |
setToken(data.token); | |
showMessage('Login successful!', 'success'); | |
} else { | |
showMessage(data.error || 'Login failed', 'error'); | |
} | |
} catch (error) { | |
showMessage('Failed to connect to server', 'error'); | |
} finally { | |
setLoading(false); | |
} | |
}; | |
const handleCreateTable = async () => { | |
if (!token) { | |
showMessage('Please login first', 'error'); | |
return; | |
} | |
try { | |
setLoading(true); | |
const response = await fetch(`${baseUrl}/api/table/create`, { | |
method: 'POST', | |
headers: { | |
'Content-Type': 'application/json', | |
'Authorization': `Bearer ${token}` | |
}, | |
body: JSON.stringify({ | |
ddl: `CREATE TABLE products ( | |
id SERIAL PRIMARY KEY, | |
name VARCHAR(100), | |
price DECIMAL(10,2) | |
)` | |
}) | |
}); | |
const data = await response.json(); | |
if (response.ok) { | |
setTableName(data.prefixed_name); | |
showMessage('Table created successfully!', 'success'); | |
} else { | |
showMessage(data.error || 'Failed to create table', 'error'); | |
} | |
} catch (error) { | |
showMessage('Failed to connect to server', 'error'); | |
} finally { | |
setLoading(false); | |
} | |
}; | |
const handleShowRows = async () => { | |
if (!token || !tableName) { | |
showMessage('Please login and create table first', 'error'); | |
return; | |
} | |
try { | |
setLoading(true); | |
const response = await fetch(`${baseUrl}/api/table/showRows`, { | |
method: 'POST', | |
headers: { | |
'Content-Type': 'application/json', | |
'Authorization': `Bearer ${token}` | |
}, | |
body: JSON.stringify({ | |
table_name: tableName | |
}) | |
}); | |
const data = await response.json(); | |
if (response.ok) { | |
setTableData(data); | |
showMessage('Data fetched successfully!', 'success'); | |
} else { | |
showMessage(data.error || 'Failed to fetch data', 'error'); | |
} | |
} catch (error) { | |
showMessage('Failed to connect to server', 'error'); | |
} finally { | |
setLoading(false); | |
} | |
}; | |
return ( | |
<div className="max-w-4xl mx-auto p-6"> | |
<h1 className="text-2xl font-bold mb-6">0Database Demo</h1> | |
{/* Message Display */} | |
{message && ( | |
<div className={`mb-4 p-4 rounded flex items-center gap-2 ${ | |
messageType === 'error' ? 'bg-red-100 text-red-700' : | |
messageType === 'success' ? 'bg-green-100 text-green-700' : | |
'bg-blue-100 text-blue-700' | |
}`}> | |
{messageType === 'error' ? <AlertCircle size={20} /> : <CheckCircle2 size={20} />} | |
<span>{message}</span> | |
</div> | |
)} | |
{/* Action Buttons */} | |
<div className="space-y-4"> | |
<div className="flex gap-4"> | |
<button | |
onClick={handleRegister} | |
disabled={loading} | |
className="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600 disabled:opacity-50" | |
> | |
Register Test User | |
</button> | |
<button | |
onClick={handleLogin} | |
disabled={loading} | |
className="bg-green-500 text-white px-4 py-2 rounded hover:bg-green-600 disabled:opacity-50" | |
> | |
Login | |
</button> | |
</div> | |
<div className="flex gap-4"> | |
<button | |
onClick={handleCreateTable} | |
disabled={loading || !token} | |
className="bg-purple-500 text-white px-4 py-2 rounded hover:bg-purple-600 disabled:opacity-50" | |
> | |
Create Test Table | |
</button> | |
<button | |
onClick={handleShowRows} | |
disabled={loading || !token || !tableName} | |
className="bg-orange-500 text-white px-4 py-2 rounded hover:bg-orange-600 disabled:opacity-50" | |
> | |
Show Table Data | |
</button> | |
</div> | |
</div> | |
{/* Status Display */} | |
<div className="mt-6 space-y-2"> | |
<p>Token Status: {token ? 'Authenticated' : 'Not Authenticated'}</p> | |
<p>Table Name: {tableName || 'No table created'}</p> | |
</div> | |
{/* Data Display */} | |
{tableData.length > 0 && ( | |
<div className="mt-6"> | |
<h2 className="text-xl font-semibold mb-4">Table Data</h2> | |
<div className="overflow-x-auto"> | |
<table className="w-full border-collapse border border-gray-300"> | |
<thead> | |
<tr className="bg-gray-100"> | |
{Object.keys(tableData[0]).map((key) => ( | |
<th key={key} className="border border-gray-300 p-2 text-left"> | |
{key} | |
</th> | |
))} | |
</tr> | |
</thead> | |
<tbody> | |
{tableData.map((row, i) => ( | |
<tr key={i}> | |
{Object.values(row).map((value, j) => ( | |
<td key={j} className="border border-gray-300 p-2"> | |
{String(value)} | |
</td> | |
))} | |
</tr> | |
))} | |
</tbody> | |
</table> | |
</div> | |
</div> | |
)} | |
</div> | |
); | |
}; | |
export default DatabaseDemo; | |
END_OF_COMPONENT | |
) | |
EOL | |
# Update App.js | |
cat > src/App.js << EOL | |
import DatabaseDemo from './components/DatabaseDemo'; | |
function App() { | |
return ( | |
<div className="App"> | |
<DatabaseDemo /> | |
</div> | |
); | |
} | |
export default App; | |
EOL | |
# Add proxy configuration to package.json | |
sed -i '/"private": true,/a\ "proxy": "http://localhost:48080",' package.json | |
# Start the development server | |
echo "Setup complete! To start the application, run:" | |
echo "cd database-frontend" | |
echo "npm start" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment