Refactor: Replace screenshot functionality with mock data generation

This commit is contained in:
courtmanr@gmail.com
2025-03-03 22:45:04 +00:00
parent 391cd1cc5b
commit dde48ca5e1
12 changed files with 1902 additions and 36 deletions
+4
View File
@@ -16,6 +16,7 @@ build/
# Logs
logs/
*.log
socket-debug.log
# Reports
reports/
@@ -39,3 +40,6 @@ scripts/release.sh
# Release process
.release-prompt.md
.commit-prompt.md
# Development tools
/tmp/pulse-*.log
-10
View File
@@ -148,16 +148,6 @@ docker run -d -p 7654:7654 --env-file .env --name pulse-app --restart unless-sto
- Responsive design that works on desktop and mobile
- WebSocket connection for live updates
## 📱 More Screenshots
### Resource Details
![Resources](docs/images/resources.png)
*Detailed resource monitoring with real-time graphs*
### Mobile View
![Mobile](docs/images/mobile.png)
*Responsive mobile interface*
## ❓ Troubleshooting
1. **Connection Issues**: Verify your ProxMox node details in `.env`
Binary file not shown.

After

Width:  |  Height:  |  Size: 355 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 323 KiB

+1109 -26
View File
File diff suppressed because it is too large Load Diff
+2
View File
@@ -44,7 +44,9 @@
"dotenv": "^16.4.7",
"express": "^4.21.2",
"node-fetch": "^2.7.0",
"puppeteer": "^24.3.1",
"socket.io": "^4.8.1",
"socket.io-client": "^4.8.1",
"ts-node": "^10.9.2",
"typescript": "^5.7.3",
"winston": "^3.17.0"
+64
View File
@@ -0,0 +1,64 @@
# Pulse Development Tools
**⚠️ DEVELOPMENT USE ONLY ⚠️**
These tools are for development and testing purposes only. They are not part of the main Pulse application and should not be used in production environments.
## Mock Data Generator
This directory contains a tool for generating simulated data for the Pulse application. This is useful for development, testing, and creating documentation without needing a real Proxmox environment.
### Available Tools
1. **generate-mock-data.js** - Generates simulated data for the Pulse application
2. **debug-socket.js** - Debug proxy for troubleshooting socket communication
3. **debug-proxy.sh** - Runs the application with the debug proxy
### Quick Start
To use the mock data generator:
```bash
# Start the mock data server
node scripts/generate-mock-data.js
# In another terminal, start the frontend
cd frontend
VITE_API_URL=http://localhost:7655 npm run dev
```
The mock data server will run on port 7655 and provide simulated data to the frontend.
### Simulated Data
The generator creates:
- A single Proxmox node with realistic specifications
- 10 virtual machines with various configurations
- 10 containers with various configurations
- Realistic resource usage metrics that update every 2 seconds
The VMs and containers have:
- Different operating systems (Ubuntu, Debian, CentOS, Windows, etc.)
- Varying CPU, memory, and disk configurations
- Realistic network throughput
- A mix of running and stopped states
### Customizing the Data
You can modify the `generate-mock-data.js` script to change:
- The node specifications
- The number and types of VMs and containers
- The resource usage patterns
- The update frequency
### Troubleshooting
If you encounter issues with the socket communication, you can use the debug proxy:
```bash
./scripts/debug-proxy.sh
```
This will run the application with a debug proxy that logs all socket messages to `socket-debug.log`.
+19
View File
@@ -0,0 +1,19 @@
# Pulse Scripts
This directory contains various scripts used for development, testing, and maintenance of the Pulse application.
## Development Tools
These scripts are for development and testing purposes only. They are not part of the main Pulse application and should not be used in production environments.
For more information about the development tools, see [README-dev-tools.md](README-dev-tools.md).
## Available Scripts
- **generate-mock-data.js** - Generates simulated data for development and testing
- **debug-socket.js** - Debug proxy for troubleshooting socket communication
- **debug-proxy.sh** - Runs the application with the debug proxy
## Production Scripts
There are currently no production scripts in this directory.
+157
View File
@@ -0,0 +1,157 @@
#!/bin/bash
# Pulse Debug Proxy
# This script handles everything needed for testing with simulated data
# and includes a debug proxy to log all socket.io messages
# Colors for terminal output
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m' # No Color
# Port configuration
MOCK_PORT=7655
PROXY_PORT=7656
FRONTEND_PORT=3000
echo -e "${BLUE}"
echo "╔════════════════════════════════════════════════════════════╗"
echo "║ ║"
echo "║ Pulse Debug Proxy ║"
echo "║ ║"
echo "║ This script will: ║"
echo "║ 1. Kill any existing Node.js processes ║"
echo "║ 2. Start the mock data server ║"
echo "║ 3. Start the debug proxy ║"
echo "║ 4. Start the frontend with connection to the proxy ║"
echo "║ 5. Log all socket.io messages for debugging ║"
echo "║ ║"
echo "╚════════════════════════════════════════════════════════════╝"
echo -e "${NC}"
# Function to check if a command exists
command_exists() {
command -v "$1" >/dev/null 2>&1
}
# Check for required commands
if ! command_exists node; then
echo -e "${RED}Error: Node.js is not installed. Please install Node.js to continue.${NC}"
exit 1
fi
# Kill any existing Node.js processes
echo -e "${YELLOW}Killing any existing Node.js processes...${NC}"
pkill -f "node scripts/generate-mock-data.js" 2>/dev/null
pkill -f "node scripts/debug-socket.js" 2>/dev/null
pkill -f "vite" 2>/dev/null
sleep 1
# Check if ports are in use
port_check() {
lsof -i:$1 >/dev/null 2>&1
return $?
}
if port_check $MOCK_PORT; then
echo -e "${RED}Error: Port $MOCK_PORT is already in use. Please free this port and try again.${NC}"
echo -e "${YELLOW}You can try: lsof -i:$MOCK_PORT to see what's using it.${NC}"
exit 1
fi
if port_check $PROXY_PORT; then
echo -e "${RED}Error: Port $PROXY_PORT is already in use. Please free this port and try again.${NC}"
echo -e "${YELLOW}You can try: lsof -i:$PROXY_PORT to see what's using it.${NC}"
exit 1
fi
if port_check $FRONTEND_PORT; then
echo -e "${RED}Error: Port $FRONTEND_PORT is already in use. Please free this port and try again.${NC}"
echo -e "${YELLOW}You can try: lsof -i:$FRONTEND_PORT to see what's using it.${NC}"
exit 1
fi
# Start the mock data server
echo -e "${GREEN}Starting mock data server on port $MOCK_PORT...${NC}"
node scripts/generate-mock-data.js > /tmp/pulse-mock-server.log 2>&1 &
MOCK_PID=$!
# Wait for the mock server to start
echo -e "${YELLOW}Waiting for mock server to start...${NC}"
sleep 2
# Check if mock server is running
if ! ps -p $MOCK_PID > /dev/null; then
echo -e "${RED}Error: Mock server failed to start. Check /tmp/pulse-mock-server.log for details.${NC}"
exit 1
fi
# Start the debug proxy
echo -e "${GREEN}Starting debug proxy on port $PROXY_PORT...${NC}"
node scripts/debug-socket.js > /tmp/pulse-debug-proxy.log 2>&1 &
PROXY_PID=$!
# Wait for the proxy to start
echo -e "${YELLOW}Waiting for debug proxy to start...${NC}"
sleep 2
# Check if proxy is running
if ! ps -p $PROXY_PID > /dev/null; then
echo -e "${RED}Error: Debug proxy failed to start. Check /tmp/pulse-debug-proxy.log for details.${NC}"
kill $MOCK_PID
exit 1
fi
# Start the frontend
echo -e "${GREEN}Starting frontend on port $FRONTEND_PORT...${NC}"
cd frontend && VITE_API_URL=http://localhost:$PROXY_PORT npm run dev > /tmp/pulse-frontend.log 2>&1 &
FRONTEND_PID=$!
# Wait for the frontend to start
echo -e "${YELLOW}Waiting for frontend to start...${NC}"
sleep 5
# Check if frontend is running
if ! ps -p $FRONTEND_PID > /dev/null; then
echo -e "${RED}Error: Frontend failed to start. Check /tmp/pulse-frontend.log for details.${NC}"
kill $MOCK_PID
kill $PROXY_PID
exit 1
fi
# Open the browser
echo -e "${GREEN}Opening browser to http://localhost:$FRONTEND_PORT${NC}"
if command_exists open; then
# macOS
open "http://localhost:$FRONTEND_PORT"
elif command_exists xdg-open; then
# Linux
xdg-open "http://localhost:$FRONTEND_PORT"
elif command_exists explorer; then
# Windows
explorer "http://localhost:$FRONTEND_PORT"
else
echo -e "${YELLOW}Could not automatically open browser. Please open http://localhost:$FRONTEND_PORT manually.${NC}"
fi
echo -e "${GREEN}Everything is running in debug mode!${NC}"
echo -e "${YELLOW}All socket.io messages are being logged to ./socket-debug.log${NC}"
echo -e "${YELLOW}Press Ctrl+C when you're done to stop all processes.${NC}"
# Function to clean up on exit
cleanup() {
echo -e "\n${GREEN}Cleaning up...${NC}"
kill $MOCK_PID 2>/dev/null
kill $PROXY_PID 2>/dev/null
kill $FRONTEND_PID 2>/dev/null
echo -e "${GREEN}Done! Debug logs are available in ./socket-debug.log${NC}"
exit 0
}
# Set up trap to catch Ctrl+C
trap cleanup SIGINT
# Wait for user to press Ctrl+C
wait
+120
View File
@@ -0,0 +1,120 @@
/**
* Socket.io Debug Proxy for Pulse
*
* This script creates a proxy server that sits between the frontend and backend,
* logging all socket.io messages to help debug connection issues.
*/
const express = require('express');
const http = require('http');
const { Server: SocketServer } = require('socket.io');
const { io: SocketClient } = require('socket.io-client');
const fs = require('fs');
// Create Express app and HTTP server for the proxy
const app = express();
const server = http.createServer(app);
const io = new SocketServer(server, {
cors: {
origin: '*',
methods: ['GET', 'POST']
}
});
// Configuration
const PROXY_PORT = 7656;
const BACKEND_PORT = 7655;
const BACKEND_URL = `http://localhost:${BACKEND_PORT}`;
const LOG_FILE = './socket-debug.log';
// Clear previous log file
fs.writeFileSync(LOG_FILE, '--- Socket.io Debug Log ---\n\n');
// Helper function to log messages
const logMessage = (direction, type, data) => {
const timestamp = new Date().toISOString();
const message = `[${timestamp}] ${direction} | ${type} | ${JSON.stringify(data, null, 2)}\n`;
console.log(`${direction} | ${type}`);
fs.appendFileSync(LOG_FILE, message);
};
// Connect to the real backend with reconnection options
const backendSocket = SocketClient(BACKEND_URL, {
transports: ['websocket', 'polling'],
reconnection: true,
reconnectionAttempts: 10,
reconnectionDelay: 1000
});
// Handle connections from the frontend
io.on('connection', (frontendSocket) => {
console.log(`Frontend connected: ${frontendSocket.id}`);
logMessage('INFO', 'FRONTEND_CONNECTED', { socketId: frontendSocket.id });
// Request initial data from backend when frontend connects
// This ensures we capture the initial data messages
if (backendSocket.connected) {
console.log('Requesting initial data from backend');
logMessage('INFO', 'REQUESTING_INITIAL_DATA', {});
// Emit a custom message to request initial data
// The backend should respond with the initial data messages
backendSocket.emit('requestInitialData');
}
// Handle messages from frontend to backend
frontendSocket.onAny((event, ...args) => {
logMessage('FRONTEND → BACKEND', event, args);
backendSocket.emit(event, ...args);
});
// Handle disconnection
frontendSocket.on('disconnect', () => {
console.log(`Frontend disconnected: ${frontendSocket.id}`);
logMessage('INFO', 'FRONTEND_DISCONNECTED', { socketId: frontendSocket.id });
});
// Forward backend messages to frontend
backendSocket.onAny((event, ...args) => {
logMessage('BACKEND → FRONTEND', event, args);
frontendSocket.emit(event, ...args);
});
});
// Handle backend connection events
backendSocket.on('connect', () => {
console.log(`Connected to backend: ${backendSocket.id}`);
logMessage('INFO', 'BACKEND_CONNECTED', { socketId: backendSocket.id });
});
backendSocket.on('reconnect', (attemptNumber) => {
console.log(`Reconnected to backend after ${attemptNumber} attempts`);
logMessage('INFO', 'BACKEND_RECONNECTED', { attemptNumber });
});
backendSocket.on('disconnect', () => {
console.log('Disconnected from backend');
logMessage('INFO', 'BACKEND_DISCONNECTED', {});
});
backendSocket.on('connect_error', (err) => {
console.error(`Backend connection error: ${err.message}`);
logMessage('ERROR', 'BACKEND_CONNECTION_ERROR', { error: err.message });
});
// Start the proxy server
server.listen(PROXY_PORT, () => {
console.log(`
╔════════════════════════════════════════════════════════════╗
║ ║
║ Socket.io Debug Proxy ║
║ ║
║ Proxy running on port ${PROXY_PORT}
║ Forwarding to backend on port ${BACKEND_PORT}
║ ║
║ All messages are being logged to ${LOG_FILE}
║ ║
╚════════════════════════════════════════════════════════════╝
`);
});
+320
View File
@@ -0,0 +1,320 @@
/**
* Mock Data Generator for Pulse
*
* This script generates simulated data for development and testing.
* It overrides the socket connection to provide consistent, visually appealing data.
*
* Usage:
* 1. Run this script with Node.js
* 2. Open the app in your browser
* 3. Use the app with simulated data
*/
const express = require('express');
const http = require('http');
const { Server } = require('socket.io');
const path = require('path');
// Create Express app and HTTP server
const app = express();
const server = http.createServer(app);
const io = new Server(server, {
cors: {
origin: '*',
methods: ['GET', 'POST']
}
});
// Port for the mock server
const PORT = 7655;
// Generate a random number between min and max
const randomBetween = (min, max) => Math.floor(Math.random() * (max - min + 1) + min);
// Generate a random floating point number between min and max with specified precision
const randomFloatBetween = (min, max, precision = 2) => {
const value = Math.random() * (max - min) + min;
return parseFloat(value.toFixed(precision));
};
// Generate a random IP address
const randomIP = () => {
return `192.168.${randomBetween(1, 254)}.${randomBetween(1, 254)}`;
};
// Generate a random MAC address
const randomMAC = () => {
return Array(6).fill(0).map(() => {
const part = randomBetween(0, 255).toString(16);
return part.length === 1 ? `0${part}` : part;
}).join(':');
};
// Generate node data
const generateNodes = () => {
return [
{
id: "node-1",
name: "proxmox-01",
status: "online",
ip: "192.168.1.100",
uptime: 1209600, // 14 days
cpu: {
cores: 32,
usage: 45.5
},
memory: {
total: 137438953472, // 128 GB
used: 35.2
},
disk: {
total: 4398046511104, // 4 TB
used: 42.8
},
network: {
interfaces: ["eth0", "eth1"],
throughput: {
in: 52428800, // 50 MB/s
out: 20971520 // 20 MB/s
}
}
}
];
};
// Generate guest data with explicit VM and container types
const generateGuests = () => {
// VM names and OS combinations
const vmTemplates = [
{ name: "ubuntu-web", os: "ubuntu" },
{ name: "debian-db", os: "debian" },
{ name: "centos-app", os: "centos" },
{ name: "windows-ad", os: "windows" },
{ name: "fedora-dev", os: "fedora" },
{ name: "arch-build", os: "arch" },
{ name: "windows-rdp", os: "windows" },
{ name: "ubuntu-mail", os: "ubuntu" },
{ name: "debian-proxy", os: "debian" },
{ name: "centos-monitor", os: "centos" }
];
// Container names and OS combinations
const containerTemplates = [
{ name: "nginx-proxy", os: "alpine" },
{ name: "postgres-db", os: "debian" },
{ name: "redis-cache", os: "alpine" },
{ name: "nodejs-api", os: "debian" },
{ name: "python-worker", os: "alpine" },
{ name: "php-app", os: "debian" },
{ name: "mariadb-db", os: "debian" },
{ name: "mongodb-db", os: "debian" },
{ name: "haproxy-lb", os: "alpine" },
{ name: "elasticsearch", os: "debian" }
];
const guests = [];
// Generate VMs (10 VMs)
vmTemplates.forEach((template, index) => {
const vmId = 100 + index;
const cpuCores = randomBetween(2, 8);
const memoryGB = cpuCores * 2; // 2GB per core as a rule of thumb
const diskGB = randomBetween(50, 200);
guests.push({
id: `vm-${vmId}`,
name: `${template.name}-${vmId}`,
node: "node-1",
type: "qemu",
status: Math.random() > 0.2 ? "running" : "stopped", // 80% running, 20% stopped
os: template.os,
ip: Math.random() > 0.2 ? randomIP() : null, // 80% have IPs
mac: randomMAC(),
uptime: Math.random() > 0.2 ? randomBetween(3600, 2592000) : 0, // 1 hour to 30 days
cpu: {
cores: cpuCores,
usage: Math.random() > 0.2 ? randomFloatBetween(5, 85) : 0
},
memory: {
total: memoryGB * 1073741824, // Convert GB to bytes
used: Math.random() > 0.2 ? randomFloatBetween(10, 90) : 0
},
disk: {
total: diskGB * 1073741824, // Convert GB to bytes
used: Math.random() > 0.2 ? randomFloatBetween(10, 80) : 0
},
network: {
interfaces: ["eth0"],
throughput: {
in: Math.random() > 0.2 ? randomBetween(1048576, 20971520) : 0, // 1-20 MB/s
out: Math.random() > 0.2 ? randomBetween(524288, 10485760) : 0 // 0.5-10 MB/s
}
}
});
});
// Generate Containers (10 containers)
containerTemplates.forEach((template, index) => {
const containerId = 200 + index;
const cpuCores = randomBetween(1, 4);
const memoryGB = cpuCores; // 1GB per core for containers
const diskGB = randomBetween(10, 50);
guests.push({
id: `ct-${containerId}`,
name: `${template.name}-${containerId}`,
node: "node-1",
type: "lxc",
status: Math.random() > 0.2 ? "running" : "stopped", // 80% running, 20% stopped
os: template.os,
ip: Math.random() > 0.2 ? randomIP() : null, // 80% have IPs
mac: randomMAC(),
uptime: Math.random() > 0.2 ? randomBetween(3600, 2592000) : 0, // 1 hour to 30 days
cpu: {
cores: cpuCores,
usage: Math.random() > 0.2 ? randomFloatBetween(5, 85) : 0
},
memory: {
total: memoryGB * 1073741824, // Convert GB to bytes
used: Math.random() > 0.2 ? randomFloatBetween(10, 90) : 0
},
disk: {
total: diskGB * 1073741824, // Convert GB to bytes
used: Math.random() > 0.2 ? randomFloatBetween(10, 80) : 0
},
network: {
interfaces: ["eth0"],
throughput: {
in: Math.random() > 0.2 ? randomBetween(524288, 10485760) : 0, // 0.5-10 MB/s
out: Math.random() > 0.2 ? randomBetween(262144, 5242880) : 0 // 0.25-5 MB/s
}
}
});
});
return guests;
};
// Generate metrics data with the exact same structure as the guests
const generateMetrics = (guests) => {
// Create a metrics array with the same structure that your app expects
const metrics = [];
// For each guest, create a metrics entry
guests.forEach(guest => {
if (guest.status === 'running') {
// For running guests, use their current values
metrics.push({
guestId: guest.id,
timestamp: Date.now(),
metrics: { // Add this wrapper object to match the expected structure
cpu: guest.cpu.usage,
memory: {
total: guest.memory.total,
used: guest.memory.used,
percentUsed: guest.memory.used // This is already a percentage in our mock data
},
disk: {
total: guest.disk.total,
used: guest.disk.used,
percentUsed: guest.disk.used // This is already a percentage in our mock data
},
network: {
inRate: guest.network.throughput.in,
outRate: guest.network.throughput.out,
history: Array(10).fill(0).map(() => ({
in: randomBetween(Math.max(0, guest.network.throughput.in * 0.8), guest.network.throughput.in * 1.2),
out: randomBetween(Math.max(0, guest.network.throughput.out * 0.8), guest.network.throughput.out * 1.2)
}))
}
},
history: {
cpu: Array(10).fill(0).map(() =>
randomFloatBetween(Math.max(0, guest.cpu.usage - 20), Math.min(100, guest.cpu.usage + 20))
),
memory: Array(10).fill(0).map(() =>
randomFloatBetween(Math.max(0, guest.memory.used - 15), Math.min(100, guest.memory.used + 15))
),
disk: Array(10).fill(0).map(() =>
randomFloatBetween(Math.max(0, guest.disk.used - 5), Math.min(100, guest.disk.used + 5))
)
}
});
}
});
return metrics;
};
// Function to send initial data to a socket
const sendInitialData = (socket) => {
// Generate simulated data with hardcoded values
const nodes = generateNodes();
const guests = generateGuests();
// Log what we're sending
console.log(`Sending data for ${nodes.length} nodes and ${guests.length} guests`);
// Send initial data
socket.emit('message', { type: 'CONNECTED', payload: { server: 'Pulse Mock Data Generator' } });
console.log('Sent CONNECTED message');
socket.emit('message', { type: 'NODE_STATUS_UPDATE', payload: nodes });
console.log('Sent NODE_STATUS_UPDATE message');
socket.emit('message', { type: 'GUEST_STATUS_UPDATE', payload: guests });
console.log('Sent GUEST_STATUS_UPDATE message');
// Generate and send initial metrics
const metrics = generateMetrics(guests);
console.log(`Sending metrics for ${metrics.length} guests`);
socket.emit('message', { type: 'METRICS_UPDATE', payload: metrics });
console.log('Sent initial METRICS_UPDATE message');
return { nodes, guests, metrics };
};
// Socket.io connection handler
io.on('connection', (socket) => {
console.log('Client connected with ID:', socket.id);
// Send initial data
const { nodes, guests } = sendInitialData(socket);
// Handle request for initial data
socket.on('requestInitialData', () => {
console.log('Received request for initial data from client:', socket.id);
sendInitialData(socket);
});
// Send updated metrics every 2 seconds
const metricsInterval = setInterval(() => {
const updatedMetrics = generateMetrics(guests);
socket.emit('message', { type: 'METRICS_UPDATE', payload: updatedMetrics });
console.log(`Sent updated metrics at ${new Date().toLocaleTimeString()}`);
}, 2000);
// Clean up on disconnect
socket.on('disconnect', () => {
console.log('Client disconnected:', socket.id);
clearInterval(metricsInterval);
});
});
// Start the server
server.listen(PORT, () => {
console.log(`
╔════════════════════════════════════════════════════════════╗
║ ║
║ Pulse Mock Data Generator ║
║ ║
║ Server running on port ${PORT}
║ ║
║ To use: ║
║ 1. Make sure your frontend is connected to this server ║
║ 2. Use the app with simulated data ║
║ ║
╚════════════════════════════════════════════════════════════╝
`);
});
+107
View File
@@ -0,0 +1,107 @@
#!/bin/bash
# Pulse Mock Data Helper
# This script handles everything needed for running Pulse with simulated data
# Colors for terminal output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
# Function to display a fancy header
function display_header {
clear
echo -e "${BLUE}╔═════════════════════════════════════════════════════════╗${NC}"
echo -e "${BLUE}║ ║${NC}"
echo -e "${BLUE}║ Pulse Mock Data Helper ║${NC}"
echo -e "${BLUE}║ ║${NC}"
echo -e "${BLUE}╚═════════════════════════════════════════════════════════╝${NC}"
echo ""
}
# Display the header
display_header
# Check if we're in the right directory
if [ ! -f "package.json" ]; then
echo -e "${RED}Error: This script must be run from the root of the Pulse project.${NC}"
echo -e "${YELLOW}Please cd to the project root and try again.${NC}"
exit 1
fi
# Kill any existing processes
echo -e "${YELLOW}Cleaning up any existing processes...${NC}"
pkill -f "node scripts/generate-mock-data.js" 2>/dev/null
pkill -f "node scripts/debug-socket.js" 2>/dev/null
pkill -f "npm run dev" 2>/dev/null
pkill -f "vite" 2>/dev/null
# Wait a moment for processes to terminate
sleep 1
# Check if ports are in use
function check_port {
if lsof -i:$1 > /dev/null 2>&1; then
echo -e "${RED}Error: Port $1 is already in use. Please free this port and try again.${NC}"
exit 1
fi
}
check_port 7655 # Mock data server port
check_port 5173 # Vite dev server port
# Start the mock data server
echo -e "${GREEN}Starting mock data server...${NC}"
node scripts/generate-mock-data.js > /tmp/pulse-mock-server.log 2>&1 &
MOCK_SERVER_PID=$!
# Wait for the mock data server to start
echo -e "${YELLOW}Waiting for mock data server to start...${NC}"
sleep 2
# Check if the mock data server is running
if ! ps -p $MOCK_SERVER_PID > /dev/null; then
echo -e "${RED}Error: Mock data server failed to start.${NC}"
echo -e "${YELLOW}Check the logs at /tmp/pulse-mock-server.log for details.${NC}"
exit 1
fi
# Start the frontend
echo -e "${GREEN}Starting frontend...${NC}"
cd frontend
VITE_API_URL=http://localhost:7655 npm run dev > /tmp/pulse-frontend.log 2>&1 &
FRONTEND_PID=$!
# Wait for the frontend to start
echo -e "${YELLOW}Waiting for frontend to start...${NC}"
sleep 5
# Check if the frontend is running
if ! ps -p $FRONTEND_PID > /dev/null; then
echo -e "${RED}Error: Frontend failed to start.${NC}"
echo -e "${YELLOW}Check the logs at /tmp/pulse-frontend.log for details.${NC}"
exit 1
fi
# Open the browser
echo -e "${GREEN}Opening browser...${NC}"
if [[ "$OSTYPE" == "darwin"* ]]; then
open http://localhost:5173
elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
xdg-open http://localhost:5173
elif [[ "$OSTYPE" == "msys" || "$OSTYPE" == "win32" ]]; then
start http://localhost:5173
else
echo -e "${YELLOW}Please open http://localhost:5173 in your browser.${NC}"
fi
# Display success message
echo -e "${GREEN}Everything is running! The application is now available at http://localhost:5173${NC}"
echo -e "${YELLOW}Press Ctrl+C to stop all processes when you're done.${NC}"
# Wait for user to press Ctrl+C
trap "echo -e '${YELLOW}Stopping all processes...${NC}'; kill $MOCK_SERVER_PID $FRONTEND_PID 2>/dev/null; echo -e '${GREEN}Done! All processes have been stopped.${NC}'; exit 0" INT
wait