I am new to React and Node.Js and I am trying to create a simulation site where a manager can upload promotions into the server to showcase. The images and pdf are able to be showcased on my own local machine but unfortunately , it doesn’t showcase on the real server. May I understand why this is happening and how I should fix this? My local machine is running on windows while the server is running on linux
Client-side App.js:
<code>//Client App.js
import './App.css';
import { Route, Routes, Link } from 'react-router-dom';
import PromoBannerConf from './PromoBannerConf';
import Home from './Home';
import PromoCarousel from './PromoCarousel';
import BankAccountOfferings from './bank_account_offerings';
import StaffBankAccountOfferings from './staff/staff_bank_accounts_offerings';
import ApproveAccounts from './staff/approve_accounts';
import Login from "./login/Login";
import Register from "./register/Register";
import Dashboard from './customer/Dashboard';
import Deposit from './customer/Deposit';
import Transfer from './customer/Transfer';
import Withdraw from './customer/Withdraw';
const App = () => {
return (
<div className="App">
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/promo-banner-conf">Promo Banner Config</Link>
</li>
<li>
<Link to="/promo-carousel">Promo Carousel</Link>
</li>
<li>
<Link to="/bank-account-offerings">See bank accounts offered</Link>
</li>
<li>
<Link to="/Dashboard">See customer dashboard</Link>
</li>
<li>
<Link to="/login">Login</Link>
</li>
<li>
<Link to="/Register">Register</Link>
</li>
</ul>
</nav>
<Routes>
<Route path="/login" element={<Login/>}/>
<Route path="/register" element={<Register/>}/>
<Route path="/promo-banner-conf" element={<PromoBannerConf />} />
<Route path="/promo-carousel" element={<PromoCarousel />} />
<Route path="/bank_account_offerings" element={<BankAccountOfferings />} />
<Route path="/staff/bank_account_offerings" element={<StaffBankAccountOfferings />} />
<Route path="/staff/approve_accounts" element={<ApproveAccounts />} />
<Route path="/" element={<Home />} />
<Route path="/dashboard" element= {<Dashboard />} />
<Route path="/deposit" element= {<Deposit />} />
<Route path="/transfer" element= {<Transfer />} />
<Route path="/withdraw" element= {<Withdraw />} />
</Routes>
</div>
);
}
export default App;
</code>
<code>//Client App.js
import './App.css';
import { Route, Routes, Link } from 'react-router-dom';
import PromoBannerConf from './PromoBannerConf';
import Home from './Home';
import PromoCarousel from './PromoCarousel';
import BankAccountOfferings from './bank_account_offerings';
import StaffBankAccountOfferings from './staff/staff_bank_accounts_offerings';
import ApproveAccounts from './staff/approve_accounts';
import Login from "./login/Login";
import Register from "./register/Register";
import Dashboard from './customer/Dashboard';
import Deposit from './customer/Deposit';
import Transfer from './customer/Transfer';
import Withdraw from './customer/Withdraw';
const App = () => {
return (
<div className="App">
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/promo-banner-conf">Promo Banner Config</Link>
</li>
<li>
<Link to="/promo-carousel">Promo Carousel</Link>
</li>
<li>
<Link to="/bank-account-offerings">See bank accounts offered</Link>
</li>
<li>
<Link to="/Dashboard">See customer dashboard</Link>
</li>
<li>
<Link to="/login">Login</Link>
</li>
<li>
<Link to="/Register">Register</Link>
</li>
</ul>
</nav>
<Routes>
<Route path="/login" element={<Login/>}/>
<Route path="/register" element={<Register/>}/>
<Route path="/promo-banner-conf" element={<PromoBannerConf />} />
<Route path="/promo-carousel" element={<PromoCarousel />} />
<Route path="/bank_account_offerings" element={<BankAccountOfferings />} />
<Route path="/staff/bank_account_offerings" element={<StaffBankAccountOfferings />} />
<Route path="/staff/approve_accounts" element={<ApproveAccounts />} />
<Route path="/" element={<Home />} />
<Route path="/dashboard" element= {<Dashboard />} />
<Route path="/deposit" element= {<Deposit />} />
<Route path="/transfer" element= {<Transfer />} />
<Route path="/withdraw" element= {<Withdraw />} />
</Routes>
</div>
);
}
export default App;
</code>
//Client App.js
import './App.css';
import { Route, Routes, Link } from 'react-router-dom';
import PromoBannerConf from './PromoBannerConf';
import Home from './Home';
import PromoCarousel from './PromoCarousel';
import BankAccountOfferings from './bank_account_offerings';
import StaffBankAccountOfferings from './staff/staff_bank_accounts_offerings';
import ApproveAccounts from './staff/approve_accounts';
import Login from "./login/Login";
import Register from "./register/Register";
import Dashboard from './customer/Dashboard';
import Deposit from './customer/Deposit';
import Transfer from './customer/Transfer';
import Withdraw from './customer/Withdraw';
const App = () => {
return (
<div className="App">
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/promo-banner-conf">Promo Banner Config</Link>
</li>
<li>
<Link to="/promo-carousel">Promo Carousel</Link>
</li>
<li>
<Link to="/bank-account-offerings">See bank accounts offered</Link>
</li>
<li>
<Link to="/Dashboard">See customer dashboard</Link>
</li>
<li>
<Link to="/login">Login</Link>
</li>
<li>
<Link to="/Register">Register</Link>
</li>
</ul>
</nav>
<Routes>
<Route path="/login" element={<Login/>}/>
<Route path="/register" element={<Register/>}/>
<Route path="/promo-banner-conf" element={<PromoBannerConf />} />
<Route path="/promo-carousel" element={<PromoCarousel />} />
<Route path="/bank_account_offerings" element={<BankAccountOfferings />} />
<Route path="/staff/bank_account_offerings" element={<StaffBankAccountOfferings />} />
<Route path="/staff/approve_accounts" element={<ApproveAccounts />} />
<Route path="/" element={<Home />} />
<Route path="/dashboard" element= {<Dashboard />} />
<Route path="/deposit" element= {<Deposit />} />
<Route path="/transfer" element= {<Transfer />} />
<Route path="/withdraw" element= {<Withdraw />} />
</Routes>
</div>
);
}
export default App;
Server-side App.js:
<code>const express = require("express");
const cors = require("cors");
const session = require("express-session");
const app = express();
const router = express.Router();
const path = require("path");
const fs = require("fs");
// const authRouter = require("./routes/customer/auth")
// const promoRouter = require("./routes/promo/PromoBannerConf");
// const transactionLimitRouter = require("./routes/transaction_limit");
// const depositRouter = require("./routes/customer/deposit");
// const withdrawRouter = require("./routes/customer/withdraw");
// const transferRouter = require("./routes/customer/transfer");
const staffAuthRouter = require("./routes/staff/staff_auth");
const staffManagementRouter = require("./routes/staff/staff_management")
const securityPolicyConfigurationRouter = require("./routes/staff/security_policy_configuration")
// Add interest!
const schedule = require('node-schedule')
// Base route for testing
router.get("/", (req, res) => {
res.json({ message: "Welcome to SingStride Bank" });
});
// Read environment variable from file (for development)
require("dotenv").config()
const interestTime = require("./interest_credit.js")
// var d = new Date();
// d.setDate(d.getDate() - 1)
// interestTime(d);
schedule.scheduleJob('0 0 * * *', () => {
var d = new Date();
d.setDate(d.getDate() - 1)
interestTime(d);
}) // run everyday at midnight
// Enable json parsing
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.enable("trust proxy");
// Enable session
const devMode = app.get("env") === "development";
app.use(session({
resave: false,
saveUninitialized: true,
secret: process.env.SESSION_SECRET,
cookie: {
path: '/',
httpOnly: true,
secure: !devMode,
maxAge: !devMode ? process.env.SESSION_TIMEOUT_MINUTES * 60000 : null
}
}));
// Configure cors
app.use(cors({
credentials: true,
origin: ["http://localhost:3000", "https://cantrevealthissiteunfortunately.com"]
}));
// Serve static files
app.use('/files', express.static(path.join(__dirname, 'files/promos')));
app.get('/files/:filename', (req, res) => {
const filePath = path.join(__dirname, 'files/promos', req.params.filename);
fs.access(filePath, fs.constants.F_OK, (err) => {
if (err) {
res.status(404).send('File not found');
} else {
res.sendFile(filePath);
}
});
});
// Add routes to router
router.get("/", (req, res) => {
res.json({ message: "Welcome to SingStride Bank" });
});
// Import and use other routes...
const authRouter = require("./routes/customer/auth");
router.use("/auth", authRouter);
const approveAccountRouter = require("./routes/staff/approve_account");
router.use("/staff/approve_account", approveAccountRouter);
const promoRouter = require("./routes/promo/PromoBannerConf");
router.use("/promo", promoRouter); // Add the route for PromoRouter
const transactionLimitRouter = require("./routes/transaction_limit");
router.use("/transaction_limit", transactionLimitRouter);
const dashboardRouter = require("./routes/customer/dashboard");
router.use("/dashboard", dashboardRouter);
const depositRouter = require("./routes/customer/deposit");
router.use("/deposit", depositRouter);
const withdrawRouter = require("./routes/customer/withdraw");
router.use("/withdraw", withdrawRouter);
const transferRouter = require("./routes/customer/transfer");
router.use("/transfer", transferRouter);
router.use("/staff/auth", staffAuthRouter)
router.use("/staff/staff_management", staffManagementRouter)
router.use("/staff/security_policy_configuration", securityPolicyConfigurationRouter)
// Bank account offerings (staff)
const staffBankAccountOfferings = require("./routes/staff/bank_account_offerings.js");
router.use("/staff/bank_account_offerings", staffBankAccountOfferings);
// Bank account offerings (customer)
// Note: NOT A DUPLICATE
const customerBankAccountOfferings = require("./routes/bank_account_offerings");
router.use("/bank_account_offerings", customerBankAccountOfferings);
// Add /api prefix to all routes
app.use("/api", router);
// Overwrite default error handler so it doesn't send error logs to user
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send('Something broke!');
});
// Listen on port 5000 only if the script is run directly (not required as a module)
if (require.main === module) {
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
}
module.exports = app;
</code>
<code>const express = require("express");
const cors = require("cors");
const session = require("express-session");
const app = express();
const router = express.Router();
const path = require("path");
const fs = require("fs");
// const authRouter = require("./routes/customer/auth")
// const promoRouter = require("./routes/promo/PromoBannerConf");
// const transactionLimitRouter = require("./routes/transaction_limit");
// const depositRouter = require("./routes/customer/deposit");
// const withdrawRouter = require("./routes/customer/withdraw");
// const transferRouter = require("./routes/customer/transfer");
const staffAuthRouter = require("./routes/staff/staff_auth");
const staffManagementRouter = require("./routes/staff/staff_management")
const securityPolicyConfigurationRouter = require("./routes/staff/security_policy_configuration")
// Add interest!
const schedule = require('node-schedule')
// Base route for testing
router.get("/", (req, res) => {
res.json({ message: "Welcome to SingStride Bank" });
});
// Read environment variable from file (for development)
require("dotenv").config()
const interestTime = require("./interest_credit.js")
// var d = new Date();
// d.setDate(d.getDate() - 1)
// interestTime(d);
schedule.scheduleJob('0 0 * * *', () => {
var d = new Date();
d.setDate(d.getDate() - 1)
interestTime(d);
}) // run everyday at midnight
// Enable json parsing
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.enable("trust proxy");
// Enable session
const devMode = app.get("env") === "development";
app.use(session({
resave: false,
saveUninitialized: true,
secret: process.env.SESSION_SECRET,
cookie: {
path: '/',
httpOnly: true,
secure: !devMode,
maxAge: !devMode ? process.env.SESSION_TIMEOUT_MINUTES * 60000 : null
}
}));
// Configure cors
app.use(cors({
credentials: true,
origin: ["http://localhost:3000", "https://cantrevealthissiteunfortunately.com"]
}));
// Serve static files
app.use('/files', express.static(path.join(__dirname, 'files/promos')));
app.get('/files/:filename', (req, res) => {
const filePath = path.join(__dirname, 'files/promos', req.params.filename);
fs.access(filePath, fs.constants.F_OK, (err) => {
if (err) {
res.status(404).send('File not found');
} else {
res.sendFile(filePath);
}
});
});
// Add routes to router
router.get("/", (req, res) => {
res.json({ message: "Welcome to SingStride Bank" });
});
// Import and use other routes...
const authRouter = require("./routes/customer/auth");
router.use("/auth", authRouter);
const approveAccountRouter = require("./routes/staff/approve_account");
router.use("/staff/approve_account", approveAccountRouter);
const promoRouter = require("./routes/promo/PromoBannerConf");
router.use("/promo", promoRouter); // Add the route for PromoRouter
const transactionLimitRouter = require("./routes/transaction_limit");
router.use("/transaction_limit", transactionLimitRouter);
const dashboardRouter = require("./routes/customer/dashboard");
router.use("/dashboard", dashboardRouter);
const depositRouter = require("./routes/customer/deposit");
router.use("/deposit", depositRouter);
const withdrawRouter = require("./routes/customer/withdraw");
router.use("/withdraw", withdrawRouter);
const transferRouter = require("./routes/customer/transfer");
router.use("/transfer", transferRouter);
router.use("/staff/auth", staffAuthRouter)
router.use("/staff/staff_management", staffManagementRouter)
router.use("/staff/security_policy_configuration", securityPolicyConfigurationRouter)
// Bank account offerings (staff)
const staffBankAccountOfferings = require("./routes/staff/bank_account_offerings.js");
router.use("/staff/bank_account_offerings", staffBankAccountOfferings);
// Bank account offerings (customer)
// Note: NOT A DUPLICATE
const customerBankAccountOfferings = require("./routes/bank_account_offerings");
router.use("/bank_account_offerings", customerBankAccountOfferings);
// Add /api prefix to all routes
app.use("/api", router);
// Overwrite default error handler so it doesn't send error logs to user
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send('Something broke!');
});
// Listen on port 5000 only if the script is run directly (not required as a module)
if (require.main === module) {
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
}
module.exports = app;
</code>
const express = require("express");
const cors = require("cors");
const session = require("express-session");
const app = express();
const router = express.Router();
const path = require("path");
const fs = require("fs");
// const authRouter = require("./routes/customer/auth")
// const promoRouter = require("./routes/promo/PromoBannerConf");
// const transactionLimitRouter = require("./routes/transaction_limit");
// const depositRouter = require("./routes/customer/deposit");
// const withdrawRouter = require("./routes/customer/withdraw");
// const transferRouter = require("./routes/customer/transfer");
const staffAuthRouter = require("./routes/staff/staff_auth");
const staffManagementRouter = require("./routes/staff/staff_management")
const securityPolicyConfigurationRouter = require("./routes/staff/security_policy_configuration")
// Add interest!
const schedule = require('node-schedule')
// Base route for testing
router.get("/", (req, res) => {
res.json({ message: "Welcome to SingStride Bank" });
});
// Read environment variable from file (for development)
require("dotenv").config()
const interestTime = require("./interest_credit.js")
// var d = new Date();
// d.setDate(d.getDate() - 1)
// interestTime(d);
schedule.scheduleJob('0 0 * * *', () => {
var d = new Date();
d.setDate(d.getDate() - 1)
interestTime(d);
}) // run everyday at midnight
// Enable json parsing
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.enable("trust proxy");
// Enable session
const devMode = app.get("env") === "development";
app.use(session({
resave: false,
saveUninitialized: true,
secret: process.env.SESSION_SECRET,
cookie: {
path: '/',
httpOnly: true,
secure: !devMode,
maxAge: !devMode ? process.env.SESSION_TIMEOUT_MINUTES * 60000 : null
}
}));
// Configure cors
app.use(cors({
credentials: true,
origin: ["http://localhost:3000", "https://cantrevealthissiteunfortunately.com"]
}));
// Serve static files
app.use('/files', express.static(path.join(__dirname, 'files/promos')));
app.get('/files/:filename', (req, res) => {
const filePath = path.join(__dirname, 'files/promos', req.params.filename);
fs.access(filePath, fs.constants.F_OK, (err) => {
if (err) {
res.status(404).send('File not found');
} else {
res.sendFile(filePath);
}
});
});
// Add routes to router
router.get("/", (req, res) => {
res.json({ message: "Welcome to SingStride Bank" });
});
// Import and use other routes...
const authRouter = require("./routes/customer/auth");
router.use("/auth", authRouter);
const approveAccountRouter = require("./routes/staff/approve_account");
router.use("/staff/approve_account", approveAccountRouter);
const promoRouter = require("./routes/promo/PromoBannerConf");
router.use("/promo", promoRouter); // Add the route for PromoRouter
const transactionLimitRouter = require("./routes/transaction_limit");
router.use("/transaction_limit", transactionLimitRouter);
const dashboardRouter = require("./routes/customer/dashboard");
router.use("/dashboard", dashboardRouter);
const depositRouter = require("./routes/customer/deposit");
router.use("/deposit", depositRouter);
const withdrawRouter = require("./routes/customer/withdraw");
router.use("/withdraw", withdrawRouter);
const transferRouter = require("./routes/customer/transfer");
router.use("/transfer", transferRouter);
router.use("/staff/auth", staffAuthRouter)
router.use("/staff/staff_management", staffManagementRouter)
router.use("/staff/security_policy_configuration", securityPolicyConfigurationRouter)
// Bank account offerings (staff)
const staffBankAccountOfferings = require("./routes/staff/bank_account_offerings.js");
router.use("/staff/bank_account_offerings", staffBankAccountOfferings);
// Bank account offerings (customer)
// Note: NOT A DUPLICATE
const customerBankAccountOfferings = require("./routes/bank_account_offerings");
router.use("/bank_account_offerings", customerBankAccountOfferings);
// Add /api prefix to all routes
app.use("/api", router);
// Overwrite default error handler so it doesn't send error logs to user
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send('Something broke!');
});
// Listen on port 5000 only if the script is run directly (not required as a module)
if (require.main === module) {
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
}
module.exports = app;
Client-side PromoBannerConf.js:
<code>import React, { useEffect, useState } from 'react';
import './PromoBannerConf.css';
const PromoBannerConf = () => {
const [selectedImage, setSelectedImage] = useState(null);
const [selectedPDF, setSelectedPDF] = useState(null);
const [message, setMessage] = useState('');
const [promotions, setPromotions] = useState([]);
const [selectedIds, setSelectedIds] = useState([]);
useEffect(() => {
fetchPromotions();
}, []);
const fetchPromotions = () => {
fetch(`${process.env.REACT_APP_API_URL}/api/promo/all`)
.then(response => response.json())
.then(data => {
console.log('Fetched promotions:', data);
setPromotions(data);
})
.catch(error => console.error('Error fetching promotions:', error));
};
const onImageChange = event => {
setSelectedImage(event.target.files[0]);
};
const onPDFChange = event => {
setSelectedPDF(event.target.files[0]);
};
const onFileUpload = () => {
if (!selectedImage || !selectedPDF) {
setMessage('Both image and PDF are required');
return;
}
const formData = new FormData();
formData.append('promoImage', selectedImage);
formData.append('promoPDF', selectedPDF);
fetch(`${process.env.REACT_APP_API_URL}/api/promo/upload`, {
method: 'POST',
body: formData,
})
.then(response => {
if (!response.ok) {
return response.text().then(text => { throw new Error(text) });
}
return response.json();
})
.then(data => {
setMessage(data.message);
fetchPromotions(); // Refresh the promotions list
})
.catch(error => {
console.error('Oh oh something went wrong', error);
setMessage('Oh oh something went wrong');
});
};
const handleStatusChange = (id, newStatus) => {
fetch(`${process.env.REACT_APP_API_URL}/api/promo/update-status`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ id, status: newStatus })
})
.then(response => response.json())
.then(data => {
setPromotions(promotions.map(promo =>
promo.id === id ? { ...promo, status: newStatus } : promo
));
})
.catch(error => console.error('Oh oh something went wrong', error));
};
const handleCheckboxChange = (id) => {
setSelectedIds(prevSelectedIds => {
if (prevSelectedIds.includes(id)) {
return prevSelectedIds.filter(selectedId => selectedId !== id);
} else {
return [...prevSelectedIds, id];
}
});
};
const handleDeleteSelected = () => {
fetch(`${process.env.REACT_APP_API_URL}/api/promo/delete`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ ids: selectedIds })
})
.then(response => response.json())
.then(data => {
setMessage(data.message);
fetchPromotions(); // Refresh the promotions list
setSelectedIds([]); // Clear selected IDs
})
.catch(error => console.error('Oh oh something went wrong', error));
};
const getFileURL = (filePath) => {
return `${process.env.REACT_APP_API_URL}/${(filePath)}`;
};
return (
<div className="container">
<h2>Upload Promotion Banner</h2>
<div className="upload-section">
<label>Upload Image</label>
<input type="file" accept="image/*" onChange={onImageChange} />
<label>Upload PDF</label>
<input type="file" accept="application/pdf" onChange={onPDFChange} />
<button onClick={onFileUpload}>
Upload!
</button>
</div>
<p className="message">{message}</p>
<h2>Promotion Banners</h2>
<div className="table-section">
<table>
<thead>
<tr>
<th>ID</th>
<th>Image</th>
<th>Document</th>
<th>Status</th>
<th>Change Status</th>
<th>Select</th>
</tr>
</thead>
<tbody>
{promotions.map(promo => (
<tr key={promo.id}>
<td>{promo.id}</td>
<td><img src={getFileURL(promo.promotion_image)} alt="promotion" width="100" /></td>
<td><a href={getFileURL(promo.promotion_document)} target="_blank" rel="noopener noreferrer">View PDF</a></td>
<td>{promo.status}</td>
<td>
<select
value={promo.status}
onChange={(e) => handleStatusChange(promo.id, e.target.value)}
>
<option value="active">Active</option>
<option value="inactive">Inactive</option>
</select>
</td>
<td>
<input
type="checkbox"
checked={selectedIds.includes(promo.id)}
onChange={() => handleCheckboxChange(promo.id)}
/>
</td>
</tr>
))}
</tbody>
</table>
<button className="delete-button" onClick={handleDeleteSelected}>
Delete Selected
</button>
</div>
</div>
);
}
export default PromoBannerConf;
</code>
<code>import React, { useEffect, useState } from 'react';
import './PromoBannerConf.css';
const PromoBannerConf = () => {
const [selectedImage, setSelectedImage] = useState(null);
const [selectedPDF, setSelectedPDF] = useState(null);
const [message, setMessage] = useState('');
const [promotions, setPromotions] = useState([]);
const [selectedIds, setSelectedIds] = useState([]);
useEffect(() => {
fetchPromotions();
}, []);
const fetchPromotions = () => {
fetch(`${process.env.REACT_APP_API_URL}/api/promo/all`)
.then(response => response.json())
.then(data => {
console.log('Fetched promotions:', data);
setPromotions(data);
})
.catch(error => console.error('Error fetching promotions:', error));
};
const onImageChange = event => {
setSelectedImage(event.target.files[0]);
};
const onPDFChange = event => {
setSelectedPDF(event.target.files[0]);
};
const onFileUpload = () => {
if (!selectedImage || !selectedPDF) {
setMessage('Both image and PDF are required');
return;
}
const formData = new FormData();
formData.append('promoImage', selectedImage);
formData.append('promoPDF', selectedPDF);
fetch(`${process.env.REACT_APP_API_URL}/api/promo/upload`, {
method: 'POST',
body: formData,
})
.then(response => {
if (!response.ok) {
return response.text().then(text => { throw new Error(text) });
}
return response.json();
})
.then(data => {
setMessage(data.message);
fetchPromotions(); // Refresh the promotions list
})
.catch(error => {
console.error('Oh oh something went wrong', error);
setMessage('Oh oh something went wrong');
});
};
const handleStatusChange = (id, newStatus) => {
fetch(`${process.env.REACT_APP_API_URL}/api/promo/update-status`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ id, status: newStatus })
})
.then(response => response.json())
.then(data => {
setPromotions(promotions.map(promo =>
promo.id === id ? { ...promo, status: newStatus } : promo
));
})
.catch(error => console.error('Oh oh something went wrong', error));
};
const handleCheckboxChange = (id) => {
setSelectedIds(prevSelectedIds => {
if (prevSelectedIds.includes(id)) {
return prevSelectedIds.filter(selectedId => selectedId !== id);
} else {
return [...prevSelectedIds, id];
}
});
};
const handleDeleteSelected = () => {
fetch(`${process.env.REACT_APP_API_URL}/api/promo/delete`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ ids: selectedIds })
})
.then(response => response.json())
.then(data => {
setMessage(data.message);
fetchPromotions(); // Refresh the promotions list
setSelectedIds([]); // Clear selected IDs
})
.catch(error => console.error('Oh oh something went wrong', error));
};
const getFileURL = (filePath) => {
return `${process.env.REACT_APP_API_URL}/${(filePath)}`;
};
return (
<div className="container">
<h2>Upload Promotion Banner</h2>
<div className="upload-section">
<label>Upload Image</label>
<input type="file" accept="image/*" onChange={onImageChange} />
<label>Upload PDF</label>
<input type="file" accept="application/pdf" onChange={onPDFChange} />
<button onClick={onFileUpload}>
Upload!
</button>
</div>
<p className="message">{message}</p>
<h2>Promotion Banners</h2>
<div className="table-section">
<table>
<thead>
<tr>
<th>ID</th>
<th>Image</th>
<th>Document</th>
<th>Status</th>
<th>Change Status</th>
<th>Select</th>
</tr>
</thead>
<tbody>
{promotions.map(promo => (
<tr key={promo.id}>
<td>{promo.id}</td>
<td><img src={getFileURL(promo.promotion_image)} alt="promotion" width="100" /></td>
<td><a href={getFileURL(promo.promotion_document)} target="_blank" rel="noopener noreferrer">View PDF</a></td>
<td>{promo.status}</td>
<td>
<select
value={promo.status}
onChange={(e) => handleStatusChange(promo.id, e.target.value)}
>
<option value="active">Active</option>
<option value="inactive">Inactive</option>
</select>
</td>
<td>
<input
type="checkbox"
checked={selectedIds.includes(promo.id)}
onChange={() => handleCheckboxChange(promo.id)}
/>
</td>
</tr>
))}
</tbody>
</table>
<button className="delete-button" onClick={handleDeleteSelected}>
Delete Selected
</button>
</div>
</div>
);
}
export default PromoBannerConf;
</code>
import React, { useEffect, useState } from 'react';
import './PromoBannerConf.css';
const PromoBannerConf = () => {
const [selectedImage, setSelectedImage] = useState(null);
const [selectedPDF, setSelectedPDF] = useState(null);
const [message, setMessage] = useState('');
const [promotions, setPromotions] = useState([]);
const [selectedIds, setSelectedIds] = useState([]);
useEffect(() => {
fetchPromotions();
}, []);
const fetchPromotions = () => {
fetch(`${process.env.REACT_APP_API_URL}/api/promo/all`)
.then(response => response.json())
.then(data => {
console.log('Fetched promotions:', data);
setPromotions(data);
})
.catch(error => console.error('Error fetching promotions:', error));
};
const onImageChange = event => {
setSelectedImage(event.target.files[0]);
};
const onPDFChange = event => {
setSelectedPDF(event.target.files[0]);
};
const onFileUpload = () => {
if (!selectedImage || !selectedPDF) {
setMessage('Both image and PDF are required');
return;
}
const formData = new FormData();
formData.append('promoImage', selectedImage);
formData.append('promoPDF', selectedPDF);
fetch(`${process.env.REACT_APP_API_URL}/api/promo/upload`, {
method: 'POST',
body: formData,
})
.then(response => {
if (!response.ok) {
return response.text().then(text => { throw new Error(text) });
}
return response.json();
})
.then(data => {
setMessage(data.message);
fetchPromotions(); // Refresh the promotions list
})
.catch(error => {
console.error('Oh oh something went wrong', error);
setMessage('Oh oh something went wrong');
});
};
const handleStatusChange = (id, newStatus) => {
fetch(`${process.env.REACT_APP_API_URL}/api/promo/update-status`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ id, status: newStatus })
})
.then(response => response.json())
.then(data => {
setPromotions(promotions.map(promo =>
promo.id === id ? { ...promo, status: newStatus } : promo
));
})
.catch(error => console.error('Oh oh something went wrong', error));
};
const handleCheckboxChange = (id) => {
setSelectedIds(prevSelectedIds => {
if (prevSelectedIds.includes(id)) {
return prevSelectedIds.filter(selectedId => selectedId !== id);
} else {
return [...prevSelectedIds, id];
}
});
};
const handleDeleteSelected = () => {
fetch(`${process.env.REACT_APP_API_URL}/api/promo/delete`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ ids: selectedIds })
})
.then(response => response.json())
.then(data => {
setMessage(data.message);
fetchPromotions(); // Refresh the promotions list
setSelectedIds([]); // Clear selected IDs
})
.catch(error => console.error('Oh oh something went wrong', error));
};
const getFileURL = (filePath) => {
return `${process.env.REACT_APP_API_URL}/${(filePath)}`;
};
return (
<div className="container">
<h2>Upload Promotion Banner</h2>
<div className="upload-section">
<label>Upload Image</label>
<input type="file" accept="image/*" onChange={onImageChange} />
<label>Upload PDF</label>
<input type="file" accept="application/pdf" onChange={onPDFChange} />
<button onClick={onFileUpload}>
Upload!
</button>
</div>
<p className="message">{message}</p>
<h2>Promotion Banners</h2>
<div className="table-section">
<table>
<thead>
<tr>
<th>ID</th>
<th>Image</th>
<th>Document</th>
<th>Status</th>
<th>Change Status</th>
<th>Select</th>
</tr>
</thead>
<tbody>
{promotions.map(promo => (
<tr key={promo.id}>
<td>{promo.id}</td>
<td><img src={getFileURL(promo.promotion_image)} alt="promotion" width="100" /></td>
<td><a href={getFileURL(promo.promotion_document)} target="_blank" rel="noopener noreferrer">View PDF</a></td>
<td>{promo.status}</td>
<td>
<select
value={promo.status}
onChange={(e) => handleStatusChange(promo.id, e.target.value)}
>
<option value="active">Active</option>
<option value="inactive">Inactive</option>
</select>
</td>
<td>
<input
type="checkbox"
checked={selectedIds.includes(promo.id)}
onChange={() => handleCheckboxChange(promo.id)}
/>
</td>
</tr>
))}
</tbody>
</table>
<button className="delete-button" onClick={handleDeleteSelected}>
Delete Selected
</button>
</div>
</div>
);
}
export default PromoBannerConf;
Server side PromoBannerConf.js:
<code>const express = require("express");
const mysql = require('mysql2');
const multer = require('multer');
const path = require('path');
const fs = require('fs');
const router = express.Router();
var dbconfig = {
host: process.env.DB_HOST,
port: process.env.DB_PORT,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
connectionLimit: 15
};
console.log("Database configuration:", dbconfig);
var db_pool = mysql.createPool(dbconfig);
db_pool.getConnection((err, connection) => {
if (err) {
console.error('Error connecting to the database:', err);
return;
}
console.log('Database connection established');
connection.release();
});
function ensureDirExists(dir) {
if (!fs.existsSync(dir)){
fs.mkdirSync(dir, { recursive: true });
}
}
const storage = multer.diskStorage({
destination: function (req, file, cb) {
const dir = './files/promos';
ensureDirExists(dir);
cb(null, dir);
},
filename: function (req, file, cb) {
cb(null, file.originalname);
}
});
const upload = multer({
storage: storage,
limits: { fileSize: 500 * 10 ** 6 },
fileFilter: function (req, file, cb) {
checkFileType(file, cb);
}
}).fields([{ name: 'promoImage', maxCount: 1 }, { name: 'promoPDF', maxCount: 1 }]);
function checkFileType(file, cb) {
const filetypes = /jpeg|jpg|png|pdf/;
const extname = filetypes.test(path.extname(file.originalname).toLowerCase());
const mimetype = filetypes.test(file.mimetype);
if (mimetype && extname) {
return cb(null, true);
} else {
cb('Error: Incorrect file type');
}
}
function checkDbConnection(req, res, next) {
db_pool.getConnection((err, connection) => {
if (err) {
console.error('Error connecting to the database:', err);
return res.status(500).json({ message: 'Database connection error', error: err });
}
connection.release();
next();
});
}
router.use(checkDbConnection);
router.get('/all', (req, res) => {
const sql = `SELECT * FROM ${process.env.DB_NAME}.promotion`;
db_pool.query(sql, (err, rows, fields) => {
if (err) {
console.error('Error fetching promotions:', err);
res.status(500).json({ message: "Error fetching promotions", error: err });
} else {
res.status(200).json(rows);
}
});
});
router.post('/upload', (req, res) => {
upload(req, res, (err) => {
if (err) {
console.error('Error during file upload:', err);
res.status(400).json({ message: err });
} else {
if (!req.files.promoImage || !req.files.promoPDF) {
res.status(400).json({ message: 'Both image and PDF are required' });
} else {
const imagePath = `./files/promos/${req.files.promoImage[0].originalname}`;
const pdfPath = `./files/promos/${req.files.promoPDF[0].originalname}`;
const sql = 'INSERT INTO promotion (promotion_image, promotion_document, status) VALUES (?, ?, ?)';
const values = [imagePath, pdfPath, 'active'];
db_pool.query(sql, values, (dbErr, result) => {
if (dbErr) {
console.error('Error inserting into database:', dbErr);
res.status(500).json({ message: 'Error inserting into database', error: dbErr });
} else {
res.status(200).json({
message: 'Promotion uploaded successfully',
file: imagePath
});
}
});
}
}
});
});
router.post('/update-status', (req, res) => {
const { id, status } = req.body;
const sql = `UPDATE ${process.env.DB_NAME}.promotion SET status = ? WHERE id = ?`;
db_pool.query(sql, [status, id], (err, result) => {
if (err) {
console.error('Error updating status:', err);
res.status(500).json({ message: 'Error updating status', error: err });
} else {
res.status(200).json({ message: 'Status updated successfully' });
}
});
});
router.post('/delete', (req, res) => {
const { ids } = req.body;
const sqlGetPaths = `SELECT promotion_image, promotion_document FROM ${process.env.DB_NAME}.promotion WHERE id IN (?)`;
db_pool.query(sqlGetPaths, [ids], (err, results) => {
if (err) {
console.error('Error fetching file paths:', err);
res.status(500).json({ message: 'Error fetching file paths', error: err });
return;
}
results.forEach(result => {
const imagePath = result.promotion_image;
const pdfPath = result.promotion_document;
fs.unlink(imagePath, (unlinkErr) => {
if (unlinkErr) {
console.error('Error deleting image file:', unlinkErr);
}
});
fs.unlink(pdfPath, (unlinkErr) => {
if (unlinkErr) {
console.error('Error deleting PDF file:', unlinkErr);
}
});
});
const sqlDelete = `DELETE FROM ${process.env.DB_NAME}.promotion WHERE id IN (?)`;
db_pool.query(sqlDelete, [ids], (dbErr, result) => {
if (dbErr) {
console.error('Error deleting records:', dbErr);
res.status(500).json({ message: 'Error deleting records', error: dbErr });
} else {
res.status(200).json({ message: 'Promotions deleted successfully' });
}
});
});
});
module.exports = router;
</code>
<code>const express = require("express");
const mysql = require('mysql2');
const multer = require('multer');
const path = require('path');
const fs = require('fs');
const router = express.Router();
var dbconfig = {
host: process.env.DB_HOST,
port: process.env.DB_PORT,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
connectionLimit: 15
};
console.log("Database configuration:", dbconfig);
var db_pool = mysql.createPool(dbconfig);
db_pool.getConnection((err, connection) => {
if (err) {
console.error('Error connecting to the database:', err);
return;
}
console.log('Database connection established');
connection.release();
});
function ensureDirExists(dir) {
if (!fs.existsSync(dir)){
fs.mkdirSync(dir, { recursive: true });
}
}
const storage = multer.diskStorage({
destination: function (req, file, cb) {
const dir = './files/promos';
ensureDirExists(dir);
cb(null, dir);
},
filename: function (req, file, cb) {
cb(null, file.originalname);
}
});
const upload = multer({
storage: storage,
limits: { fileSize: 500 * 10 ** 6 },
fileFilter: function (req, file, cb) {
checkFileType(file, cb);
}
}).fields([{ name: 'promoImage', maxCount: 1 }, { name: 'promoPDF', maxCount: 1 }]);
function checkFileType(file, cb) {
const filetypes = /jpeg|jpg|png|pdf/;
const extname = filetypes.test(path.extname(file.originalname).toLowerCase());
const mimetype = filetypes.test(file.mimetype);
if (mimetype && extname) {
return cb(null, true);
} else {
cb('Error: Incorrect file type');
}
}
function checkDbConnection(req, res, next) {
db_pool.getConnection((err, connection) => {
if (err) {
console.error('Error connecting to the database:', err);
return res.status(500).json({ message: 'Database connection error', error: err });
}
connection.release();
next();
});
}
router.use(checkDbConnection);
router.get('/all', (req, res) => {
const sql = `SELECT * FROM ${process.env.DB_NAME}.promotion`;
db_pool.query(sql, (err, rows, fields) => {
if (err) {
console.error('Error fetching promotions:', err);
res.status(500).json({ message: "Error fetching promotions", error: err });
} else {
res.status(200).json(rows);
}
});
});
router.post('/upload', (req, res) => {
upload(req, res, (err) => {
if (err) {
console.error('Error during file upload:', err);
res.status(400).json({ message: err });
} else {
if (!req.files.promoImage || !req.files.promoPDF) {
res.status(400).json({ message: 'Both image and PDF are required' });
} else {
const imagePath = `./files/promos/${req.files.promoImage[0].originalname}`;
const pdfPath = `./files/promos/${req.files.promoPDF[0].originalname}`;
const sql = 'INSERT INTO promotion (promotion_image, promotion_document, status) VALUES (?, ?, ?)';
const values = [imagePath, pdfPath, 'active'];
db_pool.query(sql, values, (dbErr, result) => {
if (dbErr) {
console.error('Error inserting into database:', dbErr);
res.status(500).json({ message: 'Error inserting into database', error: dbErr });
} else {
res.status(200).json({
message: 'Promotion uploaded successfully',
file: imagePath
});
}
});
}
}
});
});
router.post('/update-status', (req, res) => {
const { id, status } = req.body;
const sql = `UPDATE ${process.env.DB_NAME}.promotion SET status = ? WHERE id = ?`;
db_pool.query(sql, [status, id], (err, result) => {
if (err) {
console.error('Error updating status:', err);
res.status(500).json({ message: 'Error updating status', error: err });
} else {
res.status(200).json({ message: 'Status updated successfully' });
}
});
});
router.post('/delete', (req, res) => {
const { ids } = req.body;
const sqlGetPaths = `SELECT promotion_image, promotion_document FROM ${process.env.DB_NAME}.promotion WHERE id IN (?)`;
db_pool.query(sqlGetPaths, [ids], (err, results) => {
if (err) {
console.error('Error fetching file paths:', err);
res.status(500).json({ message: 'Error fetching file paths', error: err });
return;
}
results.forEach(result => {
const imagePath = result.promotion_image;
const pdfPath = result.promotion_document;
fs.unlink(imagePath, (unlinkErr) => {
if (unlinkErr) {
console.error('Error deleting image file:', unlinkErr);
}
});
fs.unlink(pdfPath, (unlinkErr) => {
if (unlinkErr) {
console.error('Error deleting PDF file:', unlinkErr);
}
});
});
const sqlDelete = `DELETE FROM ${process.env.DB_NAME}.promotion WHERE id IN (?)`;
db_pool.query(sqlDelete, [ids], (dbErr, result) => {
if (dbErr) {
console.error('Error deleting records:', dbErr);
res.status(500).json({ message: 'Error deleting records', error: dbErr });
} else {
res.status(200).json({ message: 'Promotions deleted successfully' });
}
});
});
});
module.exports = router;
</code>
const express = require("express");
const mysql = require('mysql2');
const multer = require('multer');
const path = require('path');
const fs = require('fs');
const router = express.Router();
var dbconfig = {
host: process.env.DB_HOST,
port: process.env.DB_PORT,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
connectionLimit: 15
};
console.log("Database configuration:", dbconfig);
var db_pool = mysql.createPool(dbconfig);
db_pool.getConnection((err, connection) => {
if (err) {
console.error('Error connecting to the database:', err);
return;
}
console.log('Database connection established');
connection.release();
});
function ensureDirExists(dir) {
if (!fs.existsSync(dir)){
fs.mkdirSync(dir, { recursive: true });
}
}
const storage = multer.diskStorage({
destination: function (req, file, cb) {
const dir = './files/promos';
ensureDirExists(dir);
cb(null, dir);
},
filename: function (req, file, cb) {
cb(null, file.originalname);
}
});
const upload = multer({
storage: storage,
limits: { fileSize: 500 * 10 ** 6 },
fileFilter: function (req, file, cb) {
checkFileType(file, cb);
}
}).fields([{ name: 'promoImage', maxCount: 1 }, { name: 'promoPDF', maxCount: 1 }]);
function checkFileType(file, cb) {
const filetypes = /jpeg|jpg|png|pdf/;
const extname = filetypes.test(path.extname(file.originalname).toLowerCase());
const mimetype = filetypes.test(file.mimetype);
if (mimetype && extname) {
return cb(null, true);
} else {
cb('Error: Incorrect file type');
}
}
function checkDbConnection(req, res, next) {
db_pool.getConnection((err, connection) => {
if (err) {
console.error('Error connecting to the database:', err);
return res.status(500).json({ message: 'Database connection error', error: err });
}
connection.release();
next();
});
}
router.use(checkDbConnection);
router.get('/all', (req, res) => {
const sql = `SELECT * FROM ${process.env.DB_NAME}.promotion`;
db_pool.query(sql, (err, rows, fields) => {
if (err) {
console.error('Error fetching promotions:', err);
res.status(500).json({ message: "Error fetching promotions", error: err });
} else {
res.status(200).json(rows);
}
});
});
router.post('/upload', (req, res) => {
upload(req, res, (err) => {
if (err) {
console.error('Error during file upload:', err);
res.status(400).json({ message: err });
} else {
if (!req.files.promoImage || !req.files.promoPDF) {
res.status(400).json({ message: 'Both image and PDF are required' });
} else {
const imagePath = `./files/promos/${req.files.promoImage[0].originalname}`;
const pdfPath = `./files/promos/${req.files.promoPDF[0].originalname}`;
const sql = 'INSERT INTO promotion (promotion_image, promotion_document, status) VALUES (?, ?, ?)';
const values = [imagePath, pdfPath, 'active'];
db_pool.query(sql, values, (dbErr, result) => {
if (dbErr) {
console.error('Error inserting into database:', dbErr);
res.status(500).json({ message: 'Error inserting into database', error: dbErr });
} else {
res.status(200).json({
message: 'Promotion uploaded successfully',
file: imagePath
});
}
});
}
}
});
});
router.post('/update-status', (req, res) => {
const { id, status } = req.body;
const sql = `UPDATE ${process.env.DB_NAME}.promotion SET status = ? WHERE id = ?`;
db_pool.query(sql, [status, id], (err, result) => {
if (err) {
console.error('Error updating status:', err);
res.status(500).json({ message: 'Error updating status', error: err });
} else {
res.status(200).json({ message: 'Status updated successfully' });
}
});
});
router.post('/delete', (req, res) => {
const { ids } = req.body;
const sqlGetPaths = `SELECT promotion_image, promotion_document FROM ${process.env.DB_NAME}.promotion WHERE id IN (?)`;
db_pool.query(sqlGetPaths, [ids], (err, results) => {
if (err) {
console.error('Error fetching file paths:', err);
res.status(500).json({ message: 'Error fetching file paths', error: err });
return;
}
results.forEach(result => {
const imagePath = result.promotion_image;
const pdfPath = result.promotion_document;
fs.unlink(imagePath, (unlinkErr) => {
if (unlinkErr) {
console.error('Error deleting image file:', unlinkErr);
}
});
fs.unlink(pdfPath, (unlinkErr) => {
if (unlinkErr) {
console.error('Error deleting PDF file:', unlinkErr);
}
});
});
const sqlDelete = `DELETE FROM ${process.env.DB_NAME}.promotion WHERE id IN (?)`;
db_pool.query(sqlDelete, [ids], (dbErr, result) => {
if (dbErr) {
console.error('Error deleting records:', dbErr);
res.status(500).json({ message: 'Error deleting records', error: dbErr });
} else {
res.status(200).json({ message: 'Promotions deleted successfully' });
}
});
});
});
module.exports = router;