diff --git a/DEPLOYMENT_WINDOWS.md b/DEPLOYMENT_WINDOWS.md new file mode 100644 index 0000000..ff92c31 --- /dev/null +++ b/DEPLOYMENT_WINDOWS.md @@ -0,0 +1,577 @@ +# Shopfloor Dashboard - Windows Production Deployment Guide + +This guide covers deploying the Shopfloor Dashboard Node.js application to a Windows production server. + +## Prerequisites + +- Windows Server 2016 or later (or Windows 10/11) +- Administrative access to the server +- MySQL database access +- Internet connection for downloading Node.js + +--- + +## 1. Install Node.js on Windows + +### Option A: Using the Official Installer (Recommended) + +1. **Download Node.js:** + - Go to https://nodejs.org/ + - Download the **LTS (Long Term Support)** version for Windows + - Choose the Windows Installer (.msi) - 64-bit + +2. **Run the Installer:** + - Double-click the downloaded `.msi` file + - Click "Next" through the setup wizard + - Accept the license agreement + - **Important:** Make sure "Add to PATH" is checked + - Install with default options + - Click "Finish" when complete + +3. **Verify Installation:** + - Open Command Prompt or PowerShell + - Run these commands: + ```cmd + node --version + npm --version + ``` + - You should see version numbers (e.g., v20.x.x and 10.x.x) + +### Option B: Using Chocolatey (Package Manager) + +If you have Chocolatey installed: + +```powershell +# Run PowerShell as Administrator +choco install nodejs-lts -y + +# Verify +node --version +npm --version +``` + +--- + +## 2. Deploy the Application Files + +### Option A: Using Git (Recommended) + +1. **Install Git for Windows:** + - Download from https://git-scm.com/download/win + - Run installer with default options + +2. **Clone the Repository:** + ```cmd + cd C:\inetpub\wwwroot + git clone http://localhost:3000/cproudlock/shopfloor-dashboard.git + cd shopfloor-dashboard + ``` + +### Option B: Manual File Copy + +1. **Create Application Directory:** + ```cmd + mkdir C:\inetpub\wwwroot\shopfloor-dashboard + ``` + +2. **Copy these files from development:** + - `server.js` + - `package.json` + - `package-lock.json` + - `public\` directory (entire folder) + - `.gitignore` (optional) + +3. **Do NOT copy:** + - `node_modules\` (will be regenerated) + - `.git\` directory + - Any `.env` files with passwords + +--- + +## 3. Install Dependencies + +```cmd +cd C:\inetpub\wwwroot\shopfloor-dashboard +npm install --production +``` + +This will install: +- express +- mysql2 + +--- + +## 4. Configure Environment Variables + +### Option A: Using Windows Environment Variables + +1. **Open System Properties:** + - Right-click "This PC" → Properties + - Click "Advanced system settings" + - Click "Environment Variables" + +2. **Add System Variables:** + - Click "New" under System Variables + - Add each variable: + + ``` + Variable Name: PORT + Variable Value: 3001 + + Variable Name: DB_HOST + Variable Value: localhost (or your database server IP) + + Variable Name: DB_PORT + Variable Value: 3306 + + Variable Name: DB_USER + Variable Value: 570005354 (or your production user) + + Variable Name: DB_PASS + Variable Value: your-secure-password + + Variable Name: DB_NAME + Variable Value: shopdb + + Variable Name: NODE_ENV + Variable Value: production + ``` + +3. **Apply and restart Command Prompt** + +### Option B: Using a .env File (Less Secure) + +Create `config.js` in the project root: + +```javascript +module.exports = { + port: process.env.PORT || 3001, + db: { + host: process.env.DB_HOST || 'localhost', + port: process.env.DB_PORT || 3306, + user: process.env.DB_USER || '570005354', + password: process.env.DB_PASS || 'your-password', + database: process.env.DB_NAME || 'shopdb' + } +}; +``` + +**Security Warning:** Never commit passwords to Git! + +--- + +## 5. Test the Application + +```cmd +cd C:\inetpub\wwwroot\shopfloor-dashboard +node server.js +``` + +You should see: +``` +Shopfloor Dashboard running on port 3001 +Access at: http://localhost:3001 +``` + +Open a browser and test: +- http://localhost:3001 (main dashboard) +- http://localhost:3001/api/notifications (API endpoint) +- http://localhost:3001/health (health check) + +Press `Ctrl+C` to stop the test. + +--- + +## 6. Set Up as a Windows Service + +To run the dashboard automatically and keep it running, you need to set it up as a Windows service. + +### Option A: Using PM2 (Recommended) + +**Install PM2:** +```cmd +npm install -g pm2 +npm install -g pm2-windows-startup +``` + +**Configure PM2 Windows Service:** +```cmd +# Set up PM2 to run at startup +pm2-startup install + +# Start the application +cd C:\inetpub\wwwroot\shopfloor-dashboard +pm2 start server.js --name shopfloor-dashboard + +# Save the PM2 configuration +pm2 save +``` + +**Useful PM2 Commands:** +```cmd +pm2 status # Check status +pm2 logs shopfloor-dashboard # View logs +pm2 restart shopfloor-dashboard # Restart app +pm2 stop shopfloor-dashboard # Stop app +pm2 delete shopfloor-dashboard # Remove from PM2 +pm2 monit # Real-time monitoring +``` + +**PM2 Log Locations:** +``` +C:\Users\\.pm2\logs\ +``` + +### Option B: Using NSSM (Non-Sucking Service Manager) + +**Download and Install NSSM:** + +1. Download from https://nssm.cc/download +2. Extract to `C:\nssm\` +3. Add to PATH or use full path + +**Create the Service:** + +```cmd +# Navigate to NSSM directory +cd C:\nssm\win64 + +# Install service +nssm install ShopfloorDashboard "C:\Program Files\nodejs\node.exe" "C:\inetpub\wwwroot\shopfloor-dashboard\server.js" + +# Set working directory +nssm set ShopfloorDashboard AppDirectory C:\inetpub\wwwroot\shopfloor-dashboard + +# Set environment variables +nssm set ShopfloorDashboard AppEnvironmentExtra PORT=3001 DB_HOST=localhost DB_USER=570005354 DB_PASS=your-password DB_NAME=shopdb + +# Set startup type to automatic +nssm set ShopfloorDashboard Start SERVICE_AUTO_START + +# Start the service +nssm start ShopfloorDashboard +``` + +**Manage the Service:** + +```cmd +# Using NSSM +nssm stop ShopfloorDashboard +nssm start ShopfloorDashboard +nssm restart ShopfloorDashboard +nssm status ShopfloorDashboard +nssm remove ShopfloorDashboard + +# Or using Windows Services +services.msc # Opens Services window +``` + +### Option C: Using Windows Task Scheduler + +1. **Open Task Scheduler** +2. **Create Basic Task:** + - Name: Shopfloor Dashboard + - Trigger: At system startup + - Action: Start a program + - Program: `C:\Program Files\nodejs\node.exe` + - Arguments: `C:\inetpub\wwwroot\shopfloor-dashboard\server.js` + - Start in: `C:\inetpub\wwwroot\shopfloor-dashboard` +3. **Properties:** + - Run whether user is logged on or not + - Run with highest privileges + - Configure for: Windows Server 2016 or later + +--- + +## 7. Configure Windows Firewall + +```powershell +# Run PowerShell as Administrator + +# Allow port 3001 +New-NetFirewallRule -DisplayName "Shopfloor Dashboard" -Direction Inbound -LocalPort 3001 -Protocol TCP -Action Allow + +# Or if using IIS reverse proxy, allow port 80/443 +New-NetFirewallRule -DisplayName "HTTP" -Direction Inbound -LocalPort 80 -Protocol TCP -Action Allow +New-NetFirewallRule -DisplayName "HTTPS" -Direction Inbound -LocalPort 443 -Protocol TCP -Action Allow +``` + +--- + +## 8. Set Up IIS Reverse Proxy (Optional) + +If you want to use IIS as a reverse proxy to add SSL or run on port 80: + +### Install Required IIS Components: + +```powershell +# Run PowerShell as Administrator +Install-WindowsFeature -name Web-Server -IncludeManagementTools +``` + +### Install URL Rewrite and ARR: + +1. **Download and install:** + - URL Rewrite Module: https://www.iis.net/downloads/microsoft/url-rewrite + - Application Request Routing (ARR): https://www.iis.net/downloads/microsoft/application-request-routing + +2. **Enable ARR Proxy:** + - Open IIS Manager + - Click server name in left panel + - Double-click "Application Request Routing Cache" + - Click "Server Proxy Settings" in right panel + - Check "Enable proxy" + - Click Apply + +3. **Configure URL Rewrite:** + - In IIS Manager, select Default Web Site (or create new site) + - Double-click "URL Rewrite" + - Click "Add Rule(s)" → "Reverse Proxy" + - Enter: `localhost:3001` + - Click OK + +Now access the dashboard at: +- http://your-server-name or http://server-ip + +--- + +## 9. Database Configuration + +Ensure MySQL is accessible: + +### If MySQL is on the same server: + +```sql +-- Connect to MySQL +mysql -u root -p + +-- Grant permissions +GRANT ALL PRIVILEGES ON shopdb.* TO '570005354'@'localhost' IDENTIFIED BY 'your-secure-password'; +FLUSH PRIVILEGES; +``` + +### If MySQL is on a remote server: + +```sql +-- On the database server +GRANT ALL PRIVILEGES ON shopdb.* TO '570005354'@'windows-server-ip' IDENTIFIED BY 'your-secure-password'; +FLUSH PRIVILEGES; +``` + +### Test Database Connection: + +```cmd +cd C:\inetpub\wwwroot\shopfloor-dashboard +node -e "const mysql = require('mysql2'); const conn = mysql.createConnection({host:'localhost',user:'570005354',password:'your-password',database:'shopdb'}); conn.connect((err) => {if(err) console.error('Error:',err); else console.log('Connected!'); conn.end();});" +``` + +--- + +## 10. Monitoring and Logs + +### Using Event Viewer (Windows): + +1. Open Event Viewer (`eventvwr.msc`) +2. Navigate to: Windows Logs → Application +3. Look for Node.js or your service name + +### Using PM2: + +```cmd +# View real-time logs +pm2 logs shopfloor-dashboard + +# View specific log files +pm2 logs shopfloor-dashboard --lines 100 + +# Clear logs +pm2 flush +``` + +### Custom Logging: + +Add to `server.js` for file logging: + +```javascript +const fs = require('fs'); +const path = require('path'); + +// Create logs directory if it doesn't exist +const logDir = path.join(__dirname, 'logs'); +if (!fs.existsSync(logDir)) { + fs.mkdirSync(logDir); +} + +// Log to file +const logFile = path.join(logDir, `app-${new Date().toISOString().split('T')[0]}.log`); +const logStream = fs.createWriteStream(logFile, { flags: 'a' }); + +// Override console.log +const originalLog = console.log; +console.log = function(...args) { + const timestamp = new Date().toISOString(); + const message = `[${timestamp}] ${args.join(' ')}\n`; + logStream.write(message); + originalLog.apply(console, args); +}; +``` + +--- + +## 11. Security Checklist + +- [ ] Change default database passwords +- [ ] Use Windows environment variables (not hardcoded passwords) +- [ ] Enable Windows Firewall with only necessary ports +- [ ] Set up SSL certificate if exposing to internet +- [ ] Run Node.js service under limited user account (not Administrator) +- [ ] Keep Node.js updated regularly +- [ ] Set up automated database backups +- [ ] Restrict database access to application server only +- [ ] Review Windows Event Logs regularly +- [ ] Enable Windows Defender or antivirus + +--- + +## 12. Updating the Application + +### Using Git: + +```cmd +cd C:\inetpub\wwwroot\shopfloor-dashboard +git pull origin main +npm install --production + +# If using PM2: +pm2 restart shopfloor-dashboard + +# If using NSSM: +nssm restart ShopfloorDashboard +``` + +### Manual Update: + +1. Stop the service +2. Replace changed files +3. Run `npm install --production` if dependencies changed +4. Start the service + +--- + +## 13. Troubleshooting + +### Application won't start: + +```cmd +# Check Node.js version +node --version + +# Check for errors +cd C:\inetpub\wwwroot\shopfloor-dashboard +node server.js +``` + +### Can't connect to database: + +```cmd +# Test MySQL connection +mysql -h localhost -u 570005354 -p shopdb + +# Check Windows Firewall +# Check MySQL is running: services.msc +``` + +### Port already in use: + +```powershell +# Find what's using port 3001 +netstat -ano | findstr :3001 + +# Kill the process (replace PID with actual number) +taskkill /PID /F +``` + +### Service won't start automatically: + +- Check Windows Event Viewer for errors +- Verify service is set to "Automatic" startup +- Check environment variables are set correctly +- Verify file paths are correct + +### Can't access from other computers: + +- Check Windows Firewall rules +- Verify application is listening on 0.0.0.0 (not just 127.0.0.1) +- Test with: `netstat -an | findstr :3001` + +--- + +## 14. Performance Optimization + +### For Production: + +1. **Set NODE_ENV:** + ```cmd + setx NODE_ENV production /M + ``` + +2. **Increase Process Priority (if using NSSM):** + ```cmd + nssm set ShopfloorDashboard AppPriority ABOVE_NORMAL_PRIORITY_CLASS + ``` + +3. **Configure PM2 Cluster Mode (multiple instances):** + ```cmd + pm2 start server.js -i max --name shopfloor-dashboard + ``` + +--- + +## Quick Reference + +### Application Paths: +``` +Application: C:\inetpub\wwwroot\shopfloor-dashboard +Node.js: C:\Program Files\nodejs +PM2 Logs: C:\Users\\.pm2\logs +``` + +### URLs: +``` +Dashboard: http://localhost:3001 +API: http://localhost:3001/api/notifications +Health: http://localhost:3001/health +``` + +### Common Commands: +```cmd +# Start manually +node server.js + +# PM2 +pm2 start server.js --name shopfloor-dashboard +pm2 status +pm2 logs shopfloor-dashboard +pm2 restart shopfloor-dashboard + +# NSSM +nssm start ShopfloorDashboard +nssm stop ShopfloorDashboard +nssm restart ShopfloorDashboard +nssm status ShopfloorDashboard +``` + +--- + +## Support + +For issues or questions: +- Check Windows Event Viewer: `eventvwr.msc` +- Check application logs: PM2 or custom logs +- Review README.md for application details +- Contact: IT Support - West Jefferson + +--- + +**Last Updated:** October 2025 +**Version:** 1.0.0 diff --git a/public/index.html b/public/index.html index a7d0113..4fc7a23 100644 --- a/public/index.html +++ b/public/index.html @@ -22,20 +22,20 @@ } .container { - max-width: 1920px; + max-width: 100%; margin: 0 auto; - padding: 30px 40px; - padding-bottom: 100px; + padding: 50px 60px; + padding-bottom: 150px; } .header { display: grid; grid-template-columns: auto 1fr auto; align-items: center; - gap: 40px; - margin-bottom: 40px; - border-bottom: 2px solid #4181ff; /* GE Sky Blue */ - padding-bottom: 25px; + gap: 60px; + margin-bottom: 60px; + border-bottom: 4px solid #4181ff; /* GE Sky Blue */ + padding-bottom: 40px; } .logo-container { @@ -44,7 +44,7 @@ } .logo-container img { - height: 100px; + height: 160px; width: auto; } @@ -52,47 +52,48 @@ text-align: center; display: flex; flex-direction: column; - gap: 8px; + gap: 15px; } .location-title { - font-size: 18px; + font-size: 32px; font-weight: 600; color: #eaeaea; /* GE Tungsten */ text-transform: uppercase; - letter-spacing: 2px; + letter-spacing: 3px; } .header-center h1 { - font-size: 48px; + font-size: 72px; font-weight: 700; text-transform: uppercase; - letter-spacing: 2px; + letter-spacing: 3px; color: #fff; } .clock { - font-size: 36px; + font-size: 48px; font-weight: 600; letter-spacing: 1px; color: #4181ff; /* GE Sky Blue */ text-align: right; + line-height: 1.3; } .connection-status { position: fixed; - top: 20px; - right: 20px; - padding: 12px 20px; - border-radius: 6px; - font-size: 18px; + top: 30px; + right: 30px; + padding: 20px 35px; + border-radius: 10px; + font-size: 28px; font-weight: 700; z-index: 1000; display: flex; align-items: center; - gap: 10px; + gap: 15px; text-transform: uppercase; - letter-spacing: 0.5px; + letter-spacing: 1px; } .connection-status.connected { @@ -111,25 +112,25 @@ } .status-dot { - width: 12px; - height: 12px; + width: 18px; + height: 18px; border-radius: 50%; background: #00003d; } .events-section { - margin-bottom: 40px; + margin-bottom: 60px; } .section-title { - font-size: 42px; + font-size: 64px; font-weight: 800; - margin-bottom: 25px; - padding: 15px 25px; - border-radius: 8px; + margin-bottom: 40px; + padding: 25px 40px; + border-radius: 12px; display: inline-block; text-transform: uppercase; - letter-spacing: 1px; + letter-spacing: 2px; } .section-title.current { @@ -147,11 +148,11 @@ .event-card { background: #fff; color: #000; - padding: 30px 40px; - margin-bottom: 20px; - border-radius: 8px; - box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15); - border-left: 8px solid; + padding: 50px 60px; + margin-bottom: 35px; + border-radius: 12px; + box-shadow: 0 6px 30px rgba(0, 0, 0, 0.15); + border-left: 15px solid; transition: all 0.3s ease; } @@ -177,33 +178,35 @@ display: flex; justify-content: space-between; align-items: center; - margin-bottom: 20px; - gap: 20px; + margin-bottom: 30px; + gap: 30px; } .event-title { - font-size: 38px; + font-size: 56px; font-weight: 700; flex: 1; color: #00003d; /* GE Deep Navy for text */ + line-height: 1.2; } .event-ticket { - font-size: 32px; + font-size: 48px; font-weight: 700; background: #00003d; /* GE Deep Navy */ color: #fff; - padding: 10px 25px; - border-radius: 6px; + padding: 15px 35px; + border-radius: 10px; white-space: nowrap; text-transform: uppercase; - letter-spacing: 0.5px; + letter-spacing: 1px; } .event-time { - font-size: 26px; + font-size: 38px; color: #666; font-weight: 400; + line-height: 1.5; } .event-time strong { @@ -213,12 +216,12 @@ .no-events { text-align: center; - font-size: 36px; + font-size: 52px; font-weight: 600; - padding: 80px 40px; + padding: 120px 60px; background: rgba(234, 234, 234, 0.1); - border-radius: 8px; - margin-top: 30px; + border-radius: 12px; + margin-top: 50px; color: #eaeaea; /* GE Tungsten */ } @@ -229,31 +232,31 @@ right: 0; background: rgba(0, 0, 0, 0.8); text-align: center; - padding: 15px; - font-size: 22px; + padding: 25px; + font-size: 32px; z-index: 999; font-weight: 500; } .loading { text-align: center; - font-size: 36px; + font-size: 52px; font-weight: 600; - padding: 80px 40px; + padding: 120px 60px; background: rgba(234, 234, 234, 0.1); - border-radius: 8px; - margin-top: 30px; + border-radius: 12px; + margin-top: 50px; } .error-message { background: #dc3545; color: #fff; - padding: 40px; - border-radius: 8px; + padding: 60px; + border-radius: 12px; text-align: center; - font-size: 32px; + font-size: 48px; font-weight: 700; - margin: 30px 0; + margin: 50px 0; } @@ -425,7 +428,7 @@ container.innerHTML = `
⚠️ Unable to load events
- Retrying... + Retrying...
`; }