Add frontend test component and debug server
This commit is contained in:
126
inventory-server/src/routes/dashboard.js
Normal file
126
inventory-server/src/routes/dashboard.js
Normal file
@@ -0,0 +1,126 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
|
||||
// Get dashboard statistics
|
||||
router.get('/stats', async (req, res) => {
|
||||
const pool = req.app.locals.pool;
|
||||
try {
|
||||
const [totalProducts] = await pool.query(
|
||||
'SELECT COUNT(*) as count FROM products WHERE visible = true'
|
||||
);
|
||||
|
||||
const [lowStockProducts] = await pool.query(
|
||||
'SELECT COUNT(*) as count FROM products WHERE stock_quantity <= 10 AND visible = true'
|
||||
);
|
||||
|
||||
const [orderStats] = await pool.query(`
|
||||
SELECT
|
||||
COUNT(DISTINCT order_number) as total_orders,
|
||||
AVG(price * quantity - COALESCE(discount, 0)) as avg_order_value
|
||||
FROM orders
|
||||
WHERE canceled = false
|
||||
AND date >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)
|
||||
`);
|
||||
|
||||
res.json({
|
||||
totalProducts: totalProducts[0].count,
|
||||
lowStockProducts: lowStockProducts[0].count,
|
||||
totalOrders: orderStats[0].total_orders || 0,
|
||||
averageOrderValue: orderStats[0].avg_order_value || 0
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error fetching dashboard stats:', error);
|
||||
res.status(500).json({ error: 'Failed to fetch dashboard statistics' });
|
||||
}
|
||||
});
|
||||
|
||||
// Get sales overview data
|
||||
router.get('/sales-overview', async (req, res) => {
|
||||
const pool = req.app.locals.pool;
|
||||
try {
|
||||
const [rows] = await pool.query(`
|
||||
SELECT
|
||||
DATE(date) as date,
|
||||
SUM(price * quantity - COALESCE(discount, 0)) as total
|
||||
FROM orders
|
||||
WHERE canceled = false
|
||||
AND date >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)
|
||||
GROUP BY DATE(date)
|
||||
ORDER BY date ASC
|
||||
`);
|
||||
|
||||
res.json(rows);
|
||||
} catch (error) {
|
||||
console.error('Error fetching sales overview:', error);
|
||||
res.status(500).json({ error: 'Failed to fetch sales overview' });
|
||||
}
|
||||
});
|
||||
|
||||
// Get recent orders
|
||||
router.get('/recent-orders', async (req, res) => {
|
||||
const pool = req.app.locals.pool;
|
||||
try {
|
||||
const [rows] = await pool.query(`
|
||||
SELECT
|
||||
order_number as id,
|
||||
customer,
|
||||
date,
|
||||
SUM(price * quantity - COALESCE(discount, 0)) as amount
|
||||
FROM orders
|
||||
WHERE canceled = false
|
||||
GROUP BY order_number, customer, date
|
||||
ORDER BY date DESC
|
||||
LIMIT 5
|
||||
`);
|
||||
|
||||
res.json(rows);
|
||||
} catch (error) {
|
||||
console.error('Error fetching recent orders:', error);
|
||||
res.status(500).json({ error: 'Failed to fetch recent orders' });
|
||||
}
|
||||
});
|
||||
|
||||
// Get category statistics
|
||||
router.get('/category-stats', async (req, res) => {
|
||||
const pool = req.app.locals.pool;
|
||||
try {
|
||||
const [rows] = await pool.query(`
|
||||
SELECT
|
||||
COALESCE(NULLIF(categories, ''), 'Uncategorized') as category,
|
||||
COUNT(*) as count
|
||||
FROM products
|
||||
WHERE visible = true
|
||||
GROUP BY categories
|
||||
ORDER BY count DESC
|
||||
LIMIT 10
|
||||
`);
|
||||
|
||||
res.json(rows);
|
||||
} catch (error) {
|
||||
console.error('Error fetching category stats:', error);
|
||||
res.status(500).json({ error: 'Failed to fetch category statistics' });
|
||||
}
|
||||
});
|
||||
|
||||
// Get stock levels
|
||||
router.get('/stock-levels', async (req, res) => {
|
||||
const pool = req.app.locals.pool;
|
||||
try {
|
||||
const [rows] = await pool.query(`
|
||||
SELECT
|
||||
SUM(CASE WHEN stock_quantity = 0 THEN 1 ELSE 0 END) as outOfStock,
|
||||
SUM(CASE WHEN stock_quantity > 0 AND stock_quantity <= 10 THEN 1 ELSE 0 END) as lowStock,
|
||||
SUM(CASE WHEN stock_quantity > 10 AND stock_quantity <= 50 THEN 1 ELSE 0 END) as inStock,
|
||||
SUM(CASE WHEN stock_quantity > 50 THEN 1 ELSE 0 END) as overStock
|
||||
FROM products
|
||||
WHERE visible = true
|
||||
`);
|
||||
|
||||
res.json(rows[0]);
|
||||
} catch (error) {
|
||||
console.error('Error fetching stock levels:', error);
|
||||
res.status(500).json({ error: 'Failed to fetch stock levels' });
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
@@ -1,10 +1,34 @@
|
||||
require('dotenv').config();
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
|
||||
// Get the absolute path to the .env file
|
||||
const envPath = path.resolve('/var/www/html/inventory/.env');
|
||||
console.log('Current working directory:', process.cwd());
|
||||
console.log('Looking for .env file at:', envPath);
|
||||
console.log('.env file exists:', fs.existsSync(envPath));
|
||||
|
||||
try {
|
||||
require('dotenv').config({ path: envPath });
|
||||
console.log('.env file loaded successfully');
|
||||
} catch (error) {
|
||||
console.error('Error loading .env file:', error);
|
||||
}
|
||||
|
||||
// Log environment variables (excluding sensitive data)
|
||||
console.log('Environment variables loaded:', {
|
||||
NODE_ENV: process.env.NODE_ENV,
|
||||
PORT: process.env.PORT,
|
||||
DB_HOST: process.env.DB_HOST,
|
||||
DB_USER: process.env.DB_USER,
|
||||
DB_NAME: process.env.DB_NAME,
|
||||
// Not logging DB_PASSWORD for security
|
||||
});
|
||||
|
||||
const express = require('express');
|
||||
const cors = require('cors');
|
||||
const mysql = require('mysql2/promise');
|
||||
const productsRouter = require('./routes/products');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const dashboardRouter = require('./routes/dashboard');
|
||||
|
||||
// Ensure required directories exist
|
||||
['logs', 'uploads'].forEach(dir => {
|
||||
@@ -15,11 +39,14 @@ const fs = require('fs');
|
||||
|
||||
const app = express();
|
||||
|
||||
// Middleware
|
||||
// CORS configuration
|
||||
app.use(cors({
|
||||
origin: process.env.CORS_ORIGIN,
|
||||
origin: ['https://inventory.kent.pw', 'https://www.inventory.kent.pw'],
|
||||
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
|
||||
allowedHeaders: ['Content-Type', 'Authorization'],
|
||||
credentials: true
|
||||
}));
|
||||
|
||||
app.use(express.json());
|
||||
|
||||
// Request logging middleware
|
||||
@@ -58,11 +85,12 @@ pool.getConnection()
|
||||
})
|
||||
.catch(err => {
|
||||
console.error('[Database] Error connecting:', err);
|
||||
process.exit(1); // Exit if we can't connect to the database
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
// Routes
|
||||
app.use('/api/products', productsRouter);
|
||||
app.use('/api/dashboard', dashboardRouter);
|
||||
|
||||
// Basic health check route
|
||||
app.get('/health', (req, res) => {
|
||||
|
||||
Reference in New Issue
Block a user