Replace vanilla HTML with React + shadcn/ui + TailwindCSS scaffold
- Frontend: React 19 + Vite + TypeScript + TailwindCSS v4 + shadcn/ui - Pre-installed shadcn/ui components: Button, Card, Input, Separator - Multi-stage Dockerfile: build React client → serve with Express - Server.js updated to serve built React SPA with API routes - Sample landing page with shadcn/ui components demonstrating usage - Path aliases (@/) configured in tsconfig + vite config - components.json for easy `shadcn add <component>` usage Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
54
server.js
54
server.js
@@ -6,6 +6,9 @@ const path = require('path');
|
||||
const app = express();
|
||||
const PORT = process.env.PORT || 3000;
|
||||
|
||||
// Middleware
|
||||
app.use(express.json());
|
||||
|
||||
// PostgreSQL connection
|
||||
const pool = new Pool({
|
||||
host: process.env.POSTGRES_HOST || 'postgres',
|
||||
@@ -23,30 +26,22 @@ const redisClient = redis.createClient({
|
||||
}
|
||||
});
|
||||
|
||||
// Connect to Redis
|
||||
redisClient.connect().catch(console.error);
|
||||
|
||||
// Test database connections
|
||||
pool.query('SELECT NOW()', (err, res) => {
|
||||
if (err) {
|
||||
console.error('PostgreSQL connection error:', err);
|
||||
} else {
|
||||
console.log('PostgreSQL connected successfully at:', res.rows[0].now);
|
||||
console.log('PostgreSQL connected at:', res.rows[0].now);
|
||||
}
|
||||
});
|
||||
|
||||
redisClient.on('connect', () => {
|
||||
console.log('Redis connected successfully');
|
||||
});
|
||||
redisClient.on('connect', () => console.log('Redis connected'));
|
||||
redisClient.on('error', (err) => console.error('Redis error:', err));
|
||||
|
||||
redisClient.on('error', (err) => {
|
||||
console.error('Redis connection error:', err);
|
||||
});
|
||||
// --- API Routes ---
|
||||
|
||||
// Serve static files
|
||||
app.use(express.static('public'));
|
||||
|
||||
// Health check endpoint
|
||||
// Health check
|
||||
app.get('/health', async (req, res) => {
|
||||
try {
|
||||
const pgResult = await pool.query('SELECT NOW()');
|
||||
@@ -56,24 +51,37 @@ app.get('/health', async (req, res) => {
|
||||
postgres: 'connected',
|
||||
redis: 'connected',
|
||||
timestamp: pgResult.rows[0].now,
|
||||
git_commit: process.env.GIT_COMMIT || 'unknown',
|
||||
version: process.env.APP_VERSION || '1.0.0'
|
||||
});
|
||||
} catch (error) {
|
||||
res.status(500).json({
|
||||
status: 'unhealthy',
|
||||
error: error.message,
|
||||
git_commit: process.env.GIT_COMMIT || 'unknown',
|
||||
version: process.env.APP_VERSION || '1.0.0'
|
||||
});
|
||||
res.status(500).json({ status: 'unhealthy', error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
// Main route
|
||||
app.get('/', (req, res) => {
|
||||
res.sendFile(path.join(__dirname, 'public', 'index.html'));
|
||||
// Example API endpoint — replace with your own
|
||||
app.get('/api/status', async (req, res) => {
|
||||
try {
|
||||
const pgResult = await pool.query('SELECT NOW()');
|
||||
res.json({ ok: true, time: pgResult.rows[0].now });
|
||||
} catch (error) {
|
||||
res.status(500).json({ ok: false, error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
// --- Serve React Frontend ---
|
||||
// In production, serve the built React app from client/dist
|
||||
const clientDist = path.join(__dirname, 'client', 'dist');
|
||||
app.use(express.static(clientDist));
|
||||
|
||||
// SPA fallback — all non-API routes serve index.html
|
||||
app.get('*', (req, res) => {
|
||||
if (req.path.startsWith('/api/') || req.path === '/health') return;
|
||||
res.sendFile(path.join(clientDist, 'index.html'));
|
||||
});
|
||||
|
||||
app.listen(PORT, '0.0.0.0', () => {
|
||||
console.log(`Server running on port ${PORT}`);
|
||||
});
|
||||
|
||||
// Export for testing
|
||||
module.exports = { app, pool, redisClient };
|
||||
|
||||
Reference in New Issue
Block a user