123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- import React, { useState, useEffect } from 'react';
- import axios from 'axios';
- const API_URL = process.env.REACT_APP_API_URL || 'http://localhost:4000';
- function App() {
- const [users, setUsers] = useState([]);
- const [stats, setStats] = useState({ totalUsers: 0, activeUsers: 0, serverStatus: 'Unknown' });
- const [loading, setLoading] = useState(true);
- const [error, setError] = useState(null);
- useEffect(() => {
- fetchData();
- }, []);
- const fetchData = async () => {
- try {
- setLoading(true);
- setError(null);
- // Fetch users and stats in parallel
- const [usersResponse, statsResponse] = await Promise.all([
- axios.get(`${API_URL}/api/users`),
- axios.get(`${API_URL}/api/stats`)
- ]);
- setUsers(usersResponse.data);
- setStats(statsResponse.data);
- } catch (err) {
- console.error('Error fetching data:', err);
- setError(`Failed to fetch data: ${err.message}`);
- } finally {
- setLoading(false);
- }
- };
- const addSampleUser = async () => {
- try {
- const sampleUsers = [
- { name: 'Alice Johnson', email: 'alice@example.com', role: 'Developer' },
- { name: 'Bob Smith', email: 'bob@example.com', role: 'Designer' },
- { name: 'Charlie Brown', email: 'charlie@example.com', role: 'Manager' },
- { name: 'Diana Prince', email: 'diana@example.com', role: 'Tester' }
- ];
-
- const randomUser = sampleUsers[Math.floor(Math.random() * sampleUsers.length)];
- await axios.post(`${API_URL}/api/users`, randomUser);
-
- // Refresh data
- fetchData();
- } catch (err) {
- console.error('Error adding user:', err);
- setError(`Failed to add user: ${err.message}`);
- }
- };
- if (loading) {
- return (
- <div className="container">
- <div className="card">
- <div className="loading">Loading BYOP Sample Application...</div>
- </div>
- </div>
- );
- }
- return (
- <div className="container">
- <div className="card">
- <div className="header">
- <h1>🚀 BYOP Sample App</h1>
- <p>Multi-Component Application Testing Platform</p>
- </div>
- {error && (
- <div className="error">
- {error}
- </div>
- )}
- <div className="system-info">
- <h4>🔧 System Information</h4>
- <p><strong>Frontend:</strong> React 18 (Port 3000)</p>
- <p><strong>Backend API:</strong> Node.js + Express (Port 5000)</p>
- <p><strong>Database:</strong> PostgreSQL (Port 5432)</p>
- <p><strong>Environment:</strong> {process.env.NODE_ENV || 'development'}</p>
- <p><strong>API URL:</strong> {API_URL}</p>
- </div>
- <div className="stats-grid">
- <div className="stat-card">
- <h3>{stats.totalUsers}</h3>
- <p>Total Users</p>
- </div>
- <div className="stat-card">
- <h3>{stats.activeUsers}</h3>
- <p>Active Users</p>
- </div>
- <div className="stat-card">
- <h3>{stats.serverStatus}</h3>
- <p>Server Status</p>
- </div>
- </div>
- <div className="users-section">
- <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '20px' }}>
- <h2>👥 Users ({users.length})</h2>
- <button className="btn" onClick={addSampleUser}>
- Add Sample User
- </button>
- </div>
- {users.length === 0 ? (
- <div style={{ textAlign: 'center', padding: '40px', color: '#666' }}>
- <p>No users found. Click "Add Sample User" to get started!</p>
- </div>
- ) : (
- <div className="users-grid">
- {users.map((user) => (
- <div key={user.id} className="user-card">
- <h4>{user.name}</h4>
- <p><strong>Email:</strong> {user.email}</p>
- <p><strong>Role:</strong> {user.role}</p>
- <p><strong>Created:</strong> {new Date(user.created_at).toLocaleDateString()}</p>
- </div>
- ))}
- </div>
- )}
- </div>
- <div style={{ textAlign: 'center', marginTop: '40px', padding: '20px', background: '#f8f9fa', borderRadius: '8px' }}>
- <h3>🧪 BYOP Engine Test Status</h3>
- <p>This application demonstrates:</p>
- <ul style={{ textAlign: 'left', maxWidth: '600px', margin: '0 auto' }}>
- <li>✅ Multi-component architecture (Frontend + Backend + Database)</li>
- <li>✅ Docker containerization with individual Dockerfiles</li>
- <li>✅ Docker Compose orchestration</li>
- <li>✅ API communication between services</li>
- <li>✅ Database persistence and operations</li>
- <li>✅ Production-ready builds with Nginx</li>
- </ul>
- <button className="btn" onClick={fetchData} style={{ marginTop: '20px' }}>
- 🔄 Refresh Data
- </button>
- </div>
- </div>
- </div>
- );
- }
- export default App;
|