Spaces:
Sleeping
Sleeping
# This script is used to build and prepare the frontend code during the Docker build process | |
# It is called from the Dockerfile | |
set -e # Exit on error | |
echo "Starting frontend build process..." | |
# Clear the static directory but create it if it doesn't exist | |
mkdir -p ./static | |
rm -rf ./static/* | |
if [ -d "frontend/podcraft" ]; then | |
echo "Frontend code found, attempting to build..." | |
# Navigate to the frontend directory | |
cd frontend/podcraft | |
# Check if package.json exists | |
if [ -f "package.json" ]; then | |
echo "Installing frontend dependencies..." | |
npm install --quiet || { echo "npm install failed"; exit 1; } | |
echo "Building frontend application..." | |
npm run build || { echo "npm build failed"; exit 1; } | |
# Check if the build directory exists | |
if [ -d "dist" ]; then | |
echo "Build successful, copying files to static directory..." | |
cp -r dist/* ../../static/ | |
echo "Frontend build files copied to static directory" | |
# List the contents of the static directory to verify | |
echo "Static directory contents:" | |
ls -la ../../static/ | |
else | |
echo "ERROR: Build directory 'dist' not found after build" | |
exit 1 | |
fi | |
else | |
echo "ERROR: package.json not found in frontend/podcraft" | |
exit 1 | |
fi | |
# Return to the original directory | |
cd ../.. | |
else | |
echo "Frontend code not found, creating a fallback UI" | |
mkdir -p frontend/podcraft/public | |
mkdir -p frontend/podcraft/src | |
# Create a minimal package.json | |
cat > frontend/podcraft/package.json << EOF | |
{ | |
"name": "podcraft", | |
"private": true, | |
"version": "0.0.0", | |
"type": "module", | |
"scripts": { | |
"dev": "vite", | |
"build": "vite build", | |
"lint": "eslint .", | |
"preview": "vite preview" | |
}, | |
"dependencies": { | |
"react": "^18.2.0", | |
"react-dom": "^18.2.0", | |
"react-icons": "^4.10.1", | |
"react-router-dom": "^6.15.0", | |
"reactflow": "^11.8.3" | |
}, | |
"devDependencies": { | |
"@types/react": "^18.2.15", | |
"@types/react-dom": "^18.2.7", | |
"@vitejs/plugin-react": "^4.0.3", | |
"eslint": "^8.0.0", | |
"eslint-plugin-react-hooks": "^4.0.0", | |
"eslint-plugin-react-refresh": "^0.4.0", | |
"vite": "^4.0.0" | |
} | |
} | |
EOF | |
# Create a minimal index.html | |
cat > frontend/podcraft/index.html << EOF | |
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8" /> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
<title>PodCraft - AI Podcast Generator</title> | |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" /> | |
</head> | |
<body> | |
<div id="root"></div> | |
<script type="module" src="/src/main.jsx"></script> | |
</body> | |
</html> | |
EOF | |
# Create a minimal vite.config.js | |
cat > frontend/podcraft/vite.config.js << EOF | |
import { defineConfig } from 'vite' | |
import react from '@vitejs/plugin-react' | |
export default defineConfig({ | |
plugins: [react()], | |
server: { | |
proxy: { | |
'/api': 'http://localhost:8000', | |
'/login': 'http://localhost:8000', | |
'/signup': 'http://localhost:8000', | |
'/token': 'http://localhost:8000', | |
'/generate-podcast': 'http://localhost:8000' | |
} | |
} | |
}) | |
EOF | |
# Create a minimal main.jsx | |
mkdir -p frontend/podcraft/src | |
cat > frontend/podcraft/src/main.jsx << EOF | |
import React from 'react' | |
import ReactDOM from 'react-dom/client' | |
import App from './App.jsx' | |
import './index.css' | |
ReactDOM.createRoot(document.getElementById('root')).render( | |
<React.StrictMode> | |
<App /> | |
</React.StrictMode>, | |
) | |
EOF | |
# Create a minimal App.jsx with a more functional UI | |
cat > frontend/podcraft/src/App.jsx << EOF | |
import React, { useState, useEffect } from 'react' | |
import './App.css' | |
function App() { | |
const [apiStatus, setApiStatus] = useState('checking') | |
const [mongoStatus, setMongoStatus] = useState('unknown') | |
const [apiMessage, setApiMessage] = useState('') | |
useEffect(() => { | |
// Check the API status | |
fetch('/api/status') | |
.then(response => response.json()) | |
.then(data => { | |
setApiStatus('online') | |
setApiMessage(data.message || 'API is running') | |
}) | |
.catch(error => { | |
setApiStatus('offline') | |
console.error('API Error:', error) | |
}) | |
}, []) | |
return ( | |
<div className="App"> | |
<header className="App-header"> | |
<div className="logo"> | |
<i className="fas fa-microphone-alt"></i> | |
<h1>PodCraft</h1> | |
</div> | |
<p className="tagline">AI-Powered Podcast Generator</p> | |
<div className="status-container"> | |
<div className="status-card"> | |
<div className="status-header"> | |
<i className="fas fa-server"></i> | |
<h3>API Status</h3> | |
</div> | |
<div className="status-content"> | |
<div className={`status-indicator \${apiStatus}`}> | |
{apiStatus === 'checking' ? 'Checking...' : | |
apiStatus === 'online' ? 'Online' : 'Offline'} | |
</div> | |
{apiMessage && <p className="status-message">{apiMessage}</p>} | |
</div> | |
</div> | |
</div> | |
<div className="features"> | |
<div className="feature"> | |
<i className="fas fa-robot"></i> | |
<h3>AI Debate</h3> | |
<p>Create engaging debates between AI personalities</p> | |
</div> | |
<div className="feature"> | |
<i className="fas fa-podcast"></i> | |
<h3>Podcast Generation</h3> | |
<p>Convert debates into audio podcasts</p> | |
</div> | |
<div className="feature"> | |
<i className="fas fa-cogs"></i> | |
<h3>Workflow Editor</h3> | |
<p>Customize the podcast creation process</p> | |
</div> | |
</div> | |
<div className="note"> | |
<p>Note: This is a simplified UI for the application.</p> | |
<p>The full application UI is unavailable in this build.</p> | |
<p>API endpoints can still be accessed directly for testing.</p> | |
</div> | |
</header> | |
</div> | |
) | |
} | |
export default App | |
EOF | |
# Create enhanced CSS files | |
cat > frontend/podcraft/src/index.css << EOF | |
body { | |
margin: 0; | |
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', | |
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', | |
sans-serif; | |
-webkit-font-smoothing: antialiased; | |
-moz-osx-font-smoothing: grayscale; | |
background-color: #1a1a2e; | |
color: #ffffff; | |
} | |
* { | |
box-sizing: border-box; | |
} | |
EOF | |
cat > frontend/podcraft/src/App.css << EOF | |
.App { | |
text-align: center; | |
} | |
.App-header { | |
background-color: #0f0f1a; | |
min-height: 100vh; | |
display: flex; | |
flex-direction: column; | |
align-items: center; | |
justify-content: flex-start; | |
padding: 2rem; | |
} | |
.logo { | |
display: flex; | |
align-items: center; | |
margin-bottom: 1rem; | |
} | |
.logo i { | |
font-size: 3rem; | |
color: #6366F1; | |
margin-right: 1rem; | |
} | |
.logo h1 { | |
font-size: 3rem; | |
margin: 0; | |
background: linear-gradient(90deg, #6366F1, #8B5CF6); | |
-webkit-background-clip: text; | |
-webkit-text-fill-color: transparent; | |
} | |
.tagline { | |
font-size: 1.5rem; | |
margin-bottom: 3rem; | |
color: #94a3b8; | |
} | |
.status-container { | |
width: 100%; | |
max-width: 800px; | |
margin-bottom: 3rem; | |
} | |
.status-card { | |
background-color: #1e1e2d; | |
border-radius: 0.5rem; | |
padding: 1.5rem; | |
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); | |
} | |
.status-header { | |
display: flex; | |
align-items: center; | |
margin-bottom: 1rem; | |
} | |
.status-header i { | |
font-size: 1.5rem; | |
color: #6366F1; | |
margin-right: 0.5rem; | |
} | |
.status-header h3 { | |
margin: 0; | |
font-size: 1.2rem; | |
} | |
.status-content { | |
display: flex; | |
flex-direction: column; | |
align-items: center; | |
} | |
.status-indicator { | |
padding: 0.5rem 1.5rem; | |
border-radius: 2rem; | |
font-weight: bold; | |
margin-bottom: 1rem; | |
} | |
.status-indicator.checking { | |
background-color: #374151; | |
color: #d1d5db; | |
} | |
.status-indicator.online { | |
background-color: #065f46; | |
color: #a7f3d0; | |
} | |
.status-indicator.offline { | |
background-color: #991b1b; | |
color: #fecaca; | |
} | |
.status-message { | |
font-style: italic; | |
color: #94a3b8; | |
} | |
.features { | |
display: flex; | |
flex-wrap: wrap; | |
justify-content: center; | |
gap: 2rem; | |
margin-bottom: 3rem; | |
width: 100%; | |
max-width: 1000px; | |
} | |
.feature { | |
background-color: #1e1e2d; | |
border-radius: 0.5rem; | |
padding: 1.5rem; | |
width: 100%; | |
max-width: 300px; | |
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); | |
transition: transform 0.3s ease; | |
} | |
.feature:hover { | |
transform: translateY(-5px); | |
} | |
.feature i { | |
font-size: 2.5rem; | |
color: #8B5CF6; | |
margin-bottom: 1rem; | |
} | |
.feature h3 { | |
margin: 0; | |
margin-bottom: 0.5rem; | |
font-size: 1.2rem; | |
} | |
.feature p { | |
margin: 0; | |
color: #94a3b8; | |
font-size: 0.9rem; | |
} | |
.note { | |
margin-top: 2rem; | |
padding: 1rem; | |
background-color: #1e1e2d; | |
border-radius: 0.5rem; | |
width: 100%; | |
max-width: 800px; | |
} | |
.note p { | |
margin: 0.5rem 0; | |
color: #94a3b8; | |
font-size: 0.9rem; | |
} | |
EOF | |
echo "Created fallback frontend code" | |
# Try to build and copy the fallback UI | |
cd frontend/podcraft | |
npm install --quiet || { echo "npm install failed for fallback UI"; exit 1; } | |
npm run build || { echo "npm build failed for fallback UI"; exit 1; } | |
if [ -d "dist" ]; then | |
echo "Fallback UI build successful, copying files to static directory..." | |
cp -r dist/* ../../static/ | |
echo "Fallback UI build files copied to static directory" | |
else | |
echo "ERROR: Fallback UI build directory 'dist' not found" | |
# Copy our static HTML directly as last resort | |
echo "Copying static HTML file as last resort..." | |
cp index.html ../../static/ | |
fi | |
# Return to the original directory | |
cd ../.. | |
fi | |
echo "Frontend build process completed" | |
# Make the script executable | |
chmod +x $0 |