first commit

This commit is contained in:
MOHAN 2026-06-13 13:05:28 +05:30
commit 30023847bc
13 changed files with 2921 additions and 0 deletions

5
.env.example Normal file
View File

@ -0,0 +1,5 @@
DB_HOST=
DB_USER=
DB_PASS=
DB_NAME=
PORT=5000

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
.env
uploads/
node_modules/

32
README.md Normal file
View File

@ -0,0 +1,32 @@
# Dine360 Ads - Backend
Node.js + Express backend for Dine360 Ads platform.
## Setup
1. Install dependencies:
```bash
npm install
```
2. Copy `.env.example` to `.env` and fill in your database credentials:
```
DB_HOST=
DB_USER=
DB_PASS=
DB_NAME=
PORT=5000
```
3. Create the `uploads/` directory:
```bash
mkdir uploads
```
4. Start the server:
```bash
node server.js
```
## Notes
- `.env` and `uploads/` are excluded from version control — configure per environment.

24
config/db.js Normal file
View File

@ -0,0 +1,24 @@
const mysql = require('mysql2');
// Create MySQL Connection Pool
const pool = mysql.createPool({
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASS,
database: process.env.DB_NAME,
waitForConnections: true,
connectionLimit: 10, // Max 10 connections at a time
queueLimit: 0
});
pool.getConnection((err, connection) => {
if (err) {
console.error("❌ Database connection failed: ", err.message);
} else {
console.log("✅ Database connected successfully!");
connection.release();
}
});
// Export database connection
module.exports = pool.promise();

28
middlewares/upload.js Normal file
View File

@ -0,0 +1,28 @@
const multer = require("multer");
const path = require("path");
const storage = multer.diskStorage({
destination: function (req, res, cb) {
cb(null, "uploads/");
},
filename: function (req, file, cb) {
cb(null, Date.now() + path.extname(file.originalname));
},
});
const fileFilter = (res, file, cb) => {
const allowedTypes = ["image/jpeg", "image/png", "video/mkv", "video/mp4"];
if (allowedTypes.includes(file.mimetype)) {
cb(null, true);
} else {
cb(new Error("Invalid File Type "), false);
}
};
const upload = multer({
storage: storage,
fileFilter: fileFilter,
limits: { fileSize: 2 * 1024 * 1024 * 1024 },
});
module.exports = upload;

1565
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

25
package.json Normal file
View File

@ -0,0 +1,25 @@
{
"name": "backend",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "",
"dependencies": {
"axios": "^1.8.4",
"cors": "^2.8.5",
"dotenv": "^16.4.7",
"express": "^4.21.2",
"express-fileupload": "^1.5.1",
"fluent-ffmpeg": "^2.1.3",
"fs-extra": "^11.3.0",
"multer": "^1.4.5-lts.1",
"mysql2": "^3.13.0",
"nodemon": "^3.1.9",
"uuid": "^11.1.0"
}
}

710
routes/adminRoutes.js Normal file
View File

@ -0,0 +1,710 @@
const express = require("express");
const router = express.Router();
const pool = require("../config/db");
const upload = require("../middlewares/upload");
const { v4: uuidv4 } = require("uuid");
const generateSlug = (name) => {
return name
.toLowerCase()
.replace(/\s+/g, "-")
.replace(/[^a-z0-9-]/g, "");
};
router.post("/add-partner", async (req, res) => {
try {
const {
name,
open_time,
close_time,
address,
city,
state,
pincode,
screens,
// logo_url, // Assuming logo_url is a URL string, adjust if needed.
} = req.body;
const slug = generateSlug(name);
const uniqueurl = slug;
var id = uuidv4();
const [result] = await pool.query(
"INSERT INTO tbl_partners (transid,name, logo_url, open_time, close_time, address, city, state, pincode, screens) VALUES (?,?, ?, ?, ?, ?, ?, ?, ?, ?)",
[
id,
name,
uniqueurl,
open_time,
close_time,
address,
city,
state,
pincode,
screens,
]
);
//hsh
var screensnumber = Number(screens);
for (let i = 0; i < screensnumber; i++) {
const [result1] = await pool.query(
"INSERT INTO tbl_screens (transid,partnerid,name) VALUES (UUID(),?, ?)",
[id, "Screen " + Number(i + 1)]
);
}
res.json({
message: "Partner Added Successfully! ",
clientid: id,
uniqueurl,
id,
});
} catch (err) {
res.status(500).json({ error: err.message });
}
});
router.post("/add-screen", async (req, res) => {
try {
const {
partnerid,
// logo_url, // Assuming logo_url is a URL string, adjust if needed.
} = req.body;
console.log(partnerid);
const [countRows] = await pool.query(
`SELECT COUNT(*) AS cnt
FROM tbl_screens
WHERE partnerid = ?`,
[partnerid]
);
const existing = countRows[0].cnt;
console.log(existing);
// 2⃣ prepare the new screen name
const newScreenName = `Screen ${existing + 1}`;
// 3⃣ insert the new screen
const [result] = await pool.query(
`INSERT INTO tbl_screens
(transid, partnerid, name)
VALUES
(UUID(), ?, ?)`,
[partnerid, newScreenName]
);
res.json({
message: "Screen Added Successfully! ",
});
} catch (err) {
console.log(err);
res.status(500).json({ error: err.message });
}
});
router.post("/delete-screen", async (req, res) => {
try {
const {
screenid,
} = req.body;
const [result] = await pool.query(
`delete from tbl_screens where transid = ?
`,
[screenid]
);
res.json({
message: "Screen Deleted Successfully! ",
});
} catch (err) {
console.log(err);
res.status(500).json({ error: err.message });
}
});
router.post("/upload", upload.single("file"), async (req, res) => {
try {
const { filename, path } = req.file;
const clientid = req.body.clientid;
await pool.query(
"insert into tbl_files (transid,client_id,file_name,file_path) values (UUID(),?,?,?)",
[clientid, filename, path]
);
res.json({ message: "File Uploaded Successfully!", filepath: path });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
router.post("/upload-partner-logo", upload.single("file"), async (req, res) => {
try {
const { filename, path } = req.file;
const partnerid = req.body.partnerid;
await pool.query("update tbl_partners set logo_url = ? where transid = ?", [
path,
partnerid,
]);
res.json({
message: "Partner Logo Uploaded Successfully!",
filepath: path,
});
} catch (err) {
res.status(500).json({ error: err.message });
}
});
router.get("/partners", async (req, res) => {
try {
const [partners] = await pool.query("select * from tbl_partners");
res.json(partners);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
router.post("/update-partner", async (req, res) => {
try {
const {
name,
open_time,
logo_url,
close_time,
address,
city,
state,
pincode,
screens,
transid,
yt,
scrolltext,
} = req.body;
const [result] = await pool.query(
"update tbl_partners set name =?, logo_url=?, open_time=?, close_time=?, address=?, city=?, state=?, pincode=?, screens=?,yt=?,scrolltext=? where transid = ?",
[
name,
logo_url,
open_time,
close_time,
address,
city,
state,
pincode,
screens,
yt,
scrolltext,
transid,
]
);
res.json({
message: "Partner Updated Successfully! ",
});
} catch (err) {
res.status(500).json({ error: err.message });
}
});
router.post("/update-screen-youtube", async (req, res) => {
try {
const { screenid, sts } = req.body;
const [result] = await pool.query(
"update tbl_screens set isyoutube=? where transid = ?",
[sts, screenid]
);
res.json({
message: "Partner Updated Successfully! ",
});
} catch (err) {
res.status(500).json({ error: err.message });
}
});
router.post("/update-screen-type", async (req, res) => {
try {
const { screenid, sts } = req.body;
const [result] = await pool.query(
"update tbl_screens set screentype=? where transid = ?",
[sts, screenid]
);
res.json({
message: "Screen Type Updated Successfully! ",
});
} catch (err) {
res.status(500).json({ error: err.message });
}
});
router.get("/clients", async (req, res) => {
try {
const [partners] = await pool.query("select * from tbl_clients");
res.json(partners);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
router.post("/add-client", async (req, res) => {
try {
const { name, emailid, phoneno, address } = req.body;
const [result] = await pool.query(
"INSERT INTO tbl_clients (transid,name,emailid,phoneno,address) VALUES (UUID(),?, ?,?,?)",
[name, emailid, phoneno, address]
);
res.json({
message: "Client Added Successfully! ",
});
} catch (err) {
res.status(500).json({ error: err.message });
}
});
router.post("/update-client", async (req, res) => {
try {
const { transid, name, emailid, phoneno, address } = req.body;
const [result] = await pool.query(
"update tbl_clients set name=?,emailid=?,phoneno=?,address=? where transid = ?",
[name, emailid, phoneno, address, transid]
);
res.json({
message: "Client Updated Successfully! ",
});
} catch (err) {
res.status(500).json({ error: err.message });
}
});
router.delete("/delete-client/:clientid", async (req, res) => {
try {
const { clientid } = req.params;
const [response] = await pool.query(
"delete from tbl_clients where transid =? ",
[clientid]
);
const [response1] = await pool.query(
"delete from tbl_files where client_id =? ",
[clientid]
);
const [response2] = await pool.query(
"delete from tbl_client_partner_mapping where clientid =? ",
[clientid]
);
res.json(response);
} catch (err) {
res.status(500), json({ error: err.message });
}
});
router.get("/get-partner/:partnreid", async (req, res) => {
try {
const { partnreid } = req.params;
const [partners] = await pool.query(
"select * from tbl_partners where transid=?",
[partnreid]
);
res.json(partners);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
router.delete("/delete-partner/:partnerid", async (req, res) => {
try {
const { partnerid } = req.params;
const [response] = await pool.query(
"delete from tbl_partners where transid =? ",
[partnerid]
);
const [response1] = await pool.query(
"delete from tbl_screens where partnerid =? ",
[partnerid]
);
const [response2] = await pool.query(
"delete from tbl_client_partner_mapping where partnerid =? ",
[partnerid]
);
res.json(response);
} catch (err) {
res.status(500), json({ error: err.message });
}
});
router.delete(
"/delete-client-partner-mapping/:partnerid/:clientid",
async (req, res) => {
try {
const { partnerid, clientid } = req.params;
const [response] = await pool.query(
"delete from tbl_client_partner_mapping where partnerid =? and clientid =?",
[partnerid, clientid]
);
res.json(response);
} catch (err) {
res.status(500), json({ error: err.message });
}
}
);
router.get("/get-client/:clientid", async (req, res) => {
try {
const { clientid } = req.params;
const [partners] = await pool.query(
"select * from tbl_clients where transid=?",
[clientid]
);
res.json(partners);
} catch (err) {
res.status(500).json({ error: err.massage });
}
});
router.get("/get-screen/:partnerid", async (req, res) => {
try {
const partnerid = req.params.partnerid;
const query = "SELECT * FROM tbl_screens WHERE partnerid = ?";
const [screens] = await pool.query(query, [partnerid]);
res.json(screens);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
//Client - Partner Mapping
router.get("/client-partner-mappings", async (req, res) => {
try {
const { clientid, partnerid } = req.query; // Get clientid and partnerid from query parameters
if (!clientid || !partnerid) {
return res
.status(400)
.json({ error: "clientid and partnerid are required." });
}
const [mappings] = await pool.query(
"SELECT * FROM tbl_client_partner_mapping WHERE clientid = ? AND partnerid = ?",
[clientid, partnerid]
);
res.json(mappings);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// router.post("/add-client-partner-mapping", async (req, res) => {
// try {
// const mappings = req.body; // Assuming req.body is an array of mapping objects
// console.log(mappings);
// if (!Array.isArray(mappings) || mappings.length === 0) {
// return res
// .status(400)
// .json({ error: "Invalid or empty mapping data provided." });
// }
// const clientID = mappings[0].clientid;
// const partnerID = mappings[0].partnerid;
// await pool.query(
// "delete from tbl_client_partner_mapping where clientid =? and partnerid = ?",
// [clientID, partnerID]
// );
// for (const mapping of mappings) {
// const {
// clientid,
// partnerid,
// screenid,
// fileid,
// file_path,
// ismonday,
// istuesday,
// iswednesday,
// isthursday,
// isfriday,
// issaturday,
// issunday,
// imageduration,
// } = mapping;
// // Basic validation (you might want to add more robust validation)
// if (!clientid || !partnerid || !screenid || !fileid || !file_path) {
// return res
// .status(400)
// .json({ error: "Missing required fields in mapping." });
// }
// await pool.query(
// "INSERT INTO tbl_client_partner_mapping (clientid, partnerid, screenid, fileid, file_path, ismonday, istuesday, iswednesday, isthursday, isfriday, issaturday, issunday,imageduration) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?)",
// [
// clientid,
// partnerid,
// screenid,
// fileid,
// file_path,
// ismonday || 0, // Default to 0 if not provided
// istuesday || 0,
// iswednesday || 0,
// isthursday || 0,
// isfriday || 0,
// issaturday || 0,
// issunday || 0,
// imageduration || 10,
// ]
// );
// }
// res.json({ message: "Client-Partner mappings added successfully!" });
// } catch (err) {
// console.log(err);
// res.status(500).json({ error: err });
// }
// });
router.post("/add-client-partner-mapping", async (req, res) => {
const mappings = req.body;
if (!Array.isArray(mappings) || mappings.length === 0) {
return res
.status(400)
.json({ error: "Invalid or empty mapping data provided." });
}
const clientID = mappings[0].clientid;
const partnerID = mappings[0].partnerid;
const conn = await pool.getConnection();
try {
await conn.beginTransaction();
// 1) fetch old values by fileid
const [oldRows] = await conn.query(
`SELECT fileid, imageduration, isinhousead, iscarousel, ismainad
FROM tbl_client_partner_mapping
WHERE clientid = ? AND partnerid = ?`,
[clientID, partnerID]
);
const oldMap = oldRows.reduce((m, row) => {
m[row.fileid] = row;
return m;
}, {});
// 2) delete existing mappings
await conn.query(
"DELETE FROM tbl_client_partner_mapping WHERE clientid = ? AND partnerid = ?",
[clientID, partnerID]
);
// 3) re-insert, pulling in old flags if the incoming mapping didnt supply them
for (const mapping of mappings) {
const {
clientid,
partnerid,
screenid,
fileid,
file_path,
ismonday = 0,
istuesday = 0,
iswednesday = 0,
isthursday = 0,
isfriday = 0,
issaturday = 0,
issunday = 0,
imageduration,
isinhousead,
iscarousel,
ismainad,
} = mapping;
// fall back to old values (or defaults) if not supplied
const old = oldMap[fileid] || {};
const duration = imageduration != null
? imageduration
: old.imageduration ?? 10;
const inhouse = isinhousead != null
? isinhousead
: old.isinhousead ?? 0;
const carousel = iscarousel != null
? iscarousel
: old.iscarousel ?? 0;
const mainAd = ismainad != null
? ismainad
: old.ismainad ?? 0;
// basic field check
if (!clientid || !partnerid || !screenid || !fileid || !file_path) {
await conn.rollback();
return res
.status(400)
.json({ error: "Missing required fields in mapping." });
}
await conn.query(
`INSERT INTO tbl_client_partner_mapping
(clientid, partnerid, screenid, fileid, file_path,
ismonday, istuesday, iswednesday, isthursday,
isfriday, issaturday, issunday,
imageduration, isinhousead, iscarousel, ismainad)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
[
clientid,
partnerid,
screenid,
fileid,
file_path,
ismonday,
istuesday,
iswednesday,
isthursday,
isfriday,
issaturday,
issunday,
duration,
inhouse,
carousel,
mainAd,
]
);
}
await conn.commit();
res.json({ message: "Client-Partner mappings updated successfully!" });
} catch (err) {
await conn.rollback();
console.error(err);
res.status(500).json({ error: err.message || err });
} finally {
conn.release();
}
});
router.post("/reorder-partner-ads", async (req, res) => {
try {
const mappings = req.body; // Assuming req.body is an array of mapping objects
if (!Array.isArray(mappings) || mappings.length === 0) {
return res
.status(400)
.json({ error: "Invalid or empty mapping data provided." });
}
const partnerID = mappings[0].partnerid;
await pool.query(
"delete from tbl_client_partner_mapping where partnerid = ?",
[partnerID]
);
for (const mapping of mappings) {
const {
clientid,
partnerid,
screenid,
fileid,
file_path,
ismonday,
istuesday,
iswednesday,
isthursday,
isfriday,
issaturday,
issunday,
imageduration,
isinhousead,
iscarousel,
ismainad,
} = mapping;
// console.log(mapping);
// Basic validation (you might want to add more robust validation)
if (!clientid || !partnerid || !screenid || !fileid || !file_path) {
return res
.status(400)
.json({ error: "Missing required fields in mapping." });
}
await pool.query(
"INSERT INTO tbl_client_partner_mapping (clientid, partnerid, screenid, fileid, file_path, ismonday, istuesday, iswednesday, isthursday, isfriday, issaturday, issunday,imageduration,isinhousead,iscarousel,ismainad) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?,?,?,?)",
[
clientid,
partnerid,
screenid,
fileid,
file_path,
ismonday || 0, // Default to 0 if not provided
istuesday || 0,
iswednesday || 0,
isthursday || 0,
isfriday || 0,
issaturday || 0,
issunday || 0,
imageduration || 10,
isinhousead || 0,
iscarousel || 0,
ismainad || 0,
]
);
}
res.json({ message: "Partner Ads Re-ordered successfully!" });
} catch (err) {
console.log(err);
res.status(500).json({ error: err.message });
}
});
router.get("/partner-ads", async (req, res) => {
try {
const { partnerid } = req.query; // Get clientid and partnerid from query parameters
if (!partnerid) {
return res.status(400).json({ error: "Partnerid is required." });
}
const [mappings] = await pool.query(
" SELECT *, (select name from tbl_screens where transid = screenid) as 'screenname',(select name from tbl_clients where transid = clientid) as 'clientname' FROM tbl_client_partner_mapping WHERE partnerid = ?",
[partnerid]
);
res.json(mappings);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
router.post("/update-settings", async (req, res) => {
try {
const { transid, value } = req.body;
const [result] = await pool.query(
"update tbl_settings set value =? where transid = ?",
[value, transid]
);
res.json({
message: "Settings Updated Successfully! ",
});
} catch (err) {
res.status(500).json({ error: err.message });
}
});
module.exports = router;

275
routes/clientRoutes.js Normal file
View File

@ -0,0 +1,275 @@
const express = require("express");
const router = express.Router();
const pool = require("../config/db");
router.get("/files/:clientId", async (req, res) => {
try {
const { clientId } = req.params;
const [files] = await pool.query(
"select * from tbl_files where client_id =? ",
[clientId]
);
res.json(files);
} catch (err) {
res.status(500), json({ error: err.message });
}
});
router.get("/ads/:partnerId/:screenName", async (req, res) => {
try {
const { partnerId, screenName } = req.params;
console.log(req.params);
// Find the screenId based on partnerId and screenName
const [screenResults] = await pool.query(
"SELECT transid FROM tbl_screens WHERE REPLACE(name, ' ', '') = ? AND SUBSTRING(partnerid, 1, 5) = SUBSTRING(?, 1, 5)",
[screenName, partnerId]
);
if (screenResults.length === 0) {
return res.status(404).json({ error: "Screen not found." });
}
const screenId = screenResults[0].transid;
const [result] = await pool.query(
"update tbl_screens set isactive=1 where transid = ?",
[screenId]
);
// Find the files associated with the screenId
const [files] = await pool.query(
"SELECT file_path,screenid,partnerid,transid,imageduration,iscarousel,isinhousead,ismainad,(select screentype from tbl_screens where transid = screenid)as screentype,(select isyoutube from tbl_screens where transid = screenid)as yt FROM tbl_client_partner_mapping WHERE screenid = ?",
[screenId]
);
res.json(files);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// router.get("/ads/:partnerId/:screenName", async (req, res) => {
// try {
// const { partnerId, screenName } = req.params;
// console.log(req.params);
// // Find the screenId based on partnerId and screenName
// const [screenResults] = await pool.query(
// "SELECT file_path,screenid,partnerid,transid,imageduration,isinhousead,iscarousel,ismainad FROM tbl_client_partner_mapping WHERE screenid = ?",
// [screenId]
// );
// if (screenResults.length === 0) {
// return res.status(404).json({ error: "Screen not found." });
// }
// const screenId = screenResults[0].transid;
// const [result] = await pool.query(
// "update tbl_screens set isactive=1 where transid = ?",
// [screenId]
// );
// // Find the files associated with the screenId
// const [files] = await pool.query(
// "SELECT * FROM tbl_client_partner_mapping WHERE screenid = ?",
// [screenId]
// );
// res.json(files);
// } catch (err) {
// res.status(500).json({ error: err.message });
// }
// });
router.post("/add-screen-log", async (req, res) => {
try {
const { screen_id, screen_name, partner_id } = req.body;
// Insert data into the `screen_logs` table
const [result1] = await pool.query(
"update tbl_screens set isactive=1 where transid = ?",
[screen_id]
);
// const [result] = await pool.query(
// "INSERT INTO tbl_screen_logs (screen_id, screen_name, partner_id) VALUES (?, ?, ?)",
// [screen_id, screen_name, partner_id]
// );
res.json({
message: "Screen log added successfully!",
});
} catch (err) {
console.log(err);
res.status(500).json({ error: err.message });
}
});
router.post("/idle-screen-log", async (req, res) => {
try {
const { screen_id, screen_name, partner_id } = req.body;
// Insert data into the `screen_logs` table
const [result1] = await pool.query(
"update tbl_screens set isactive=2 where transid = ?",
[screen_id]
);
res.json({
message: "IDLE log added successfully!",
});
} catch (err) {
console.log(err);
res.status(500).json({ error: err.message });
}
});
router.get("/get-settings", async (req, res) => {
try {
const [result] = await pool.query("select * from tbl_settings ", []);
res.json(result);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
router.post("/validate-code", async (req, res) => {
try {
const { code } = req.body;
if (!code || code.length !== 4) {
return res
.status(400)
.json({ error: "Invalid code format. It should be 4 digits." });
} // Split the code into two parts
const firstTwo = code.substring(0, 2);
const lastTwo = code.substring(3, 4); // Query to check if there is a matching record
const [rows] = await pool.query(
"SELECT partnerid, name FROM tbl_screens WHERE LEFT(partnerid, 2) = ? AND right(name, 1) = ?",
[firstTwo, lastTwo]
);
if (rows.length === 0) {
return res.status(404).json({ error: "No matching record found" });
}
const { partnerid, name } = rows[0]; // Generate the response value: first 5 letters of transid/name (without spaces)
const responseValue = `${partnerid.substring(0, 5)}/${name.replace(
/\s+/g,
""
)}`;
res.json({ success: true, value: responseValue });
// res.json([
// {
// success: true,
// value: {
// screenPath: responseValue,
// raw: responseValue
// }
// }
// ]);
} catch (err) {
console.error(err);
res.status(500).json({ error: err.message });
}
});
router.post("/validate-code-new", async (req, res) => {
try {
const { code } = req.body;
if (!code || code.length !== 4) {
return res
.status(400)
.json({ error: "Invalid code format. It should be 4 digits." });
} // Split the code into two parts
const firstTwo = code.substring(0, 2);
const lastTwo = code.substring(3, 4); // Query to check if there is a matching record
const [rows] = await pool.query(
"SELECT partnerid, name,transid FROM tbl_screens WHERE LEFT(partnerid, 2) = ? AND right(name, 1) = ?",
[firstTwo, lastTwo]
);
if (rows.length === 0) {
return res.status(404).json({ error: "No matching record found" });
}
const { partnerid, name, transid } = rows[0]; // Generate the response value: first 5 letters of transid/name (without spaces)
const responseValue = `${partnerid.substring(0, 5)}/${name.replace(
/\s+/g,
""
)}`;
//res.json({ success: true, value: responseValue });
res.json([
{
success: true,
value: {
screenPath: responseValue,
raw: responseValue,
id: transid,
},
},
]);
} catch (err) {
console.error(err);
res.status(500).json({ error: err.message });
}
});
router.post("/get-yt", async (req, res) => {
try {
const { code } = req.body;
if (!code || code.length !== 4) {
return res
.status(400)
.json({ error: "Invalid code format. It should be 4 digits." });
} // Split the code into two parts
const firstTwo = code.substring(0, 2);
const lastTwo = code.substring(3, 4); // Query to check if there is a matching record
const [rows] = await pool.query(
"SELECT * FROM tbl_partners WHERE LEFT(transid, 2) = ? ",
[firstTwo]
);
res.json(rows);
} catch (err) {
console.error(err);
res.status(500).json({ error: err.message });
}
});
router.post("/add-screen-status", async (req, res) => {
try {
const { id, sts } = req.body;
// Insert data into the `screen_logs` table
const [result1] = await pool.query(
"update tbl_screens set status=?,stsupdat = CURRENT_TIMESTAMP where transid = ?",
[sts, id]
);
res.json({
message: "Screen Status Updated successfully!",
});
} catch (err) {
console.log(err);
res.status(500).json({ error: err.message });
}
});
module.exports = router;

24
routes/monitorRoutes.js Normal file
View File

@ -0,0 +1,24 @@
const express = require('express');
const pool = require('../config/db');
const router = express.Router();
// Endpoint to receive client status
router.post('/track-status', async (req, res) => {
try {
const { client_id, status } = req.body;
const timestamp = new Date();
// Log request
await pool.query("INSERT INTO client_logs (client_id, status) VALUES (?, ?)", [client_id, status]);
// Update client last active time
await pool.query("UPDATE clients SET last_active = ? WHERE id = ?", [timestamp, client_id]);
res.json({ message: "Status logged successfully!" });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
module.exports = router;

88
routes/uploadRoutes.js Normal file
View File

@ -0,0 +1,88 @@
const express = require("express");
const multer = require("multer");
const pool = require("../config/db");
const path = require("path");
const fs = require("fs-extra");
const router = express.Router();
// Ensure the uploads directory exists
const uploadDir = path.join(__dirname, "../uploads");
fs.ensureDirSync(uploadDir);
// Configure Multer for file uploads
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, uploadDir);
},
filename: (req, file, cb) => {
cb(null, Date.now() + "_" + file.originalname); // Unique filename
},
});
const upload = multer({
storage: storage,
limits: { fileSize: 2 * 1024 * 1024 * 1024 },
}); // 2GB limit
// Upload file API
router.post("/upload", upload.single("file"), async (req, res) => {
try {
const { client_id, file_name } = req.body;
if (!req.file) {
return res.status(400).json({ error: "No file uploaded" });
}
const filePath = `uploads/${req.file.filename}`;
await pool.query(
"INSERT INTO tbl_files (transid,client_id,file_name, file_path) VALUES (UUID(),?,?, ?)",
[client_id, file_name, filePath]
);
res.json({ message: "File uploaded successfully!", file_path: filePath });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
router.post("/update-partner-logo", upload.single("file"), async (req, res) => {
try {
const { client_id, file_name } = req.body;
if (!req.file) {
return res.status(400).json({ error: "No file uploaded" });
}
const filePath = `uploads/${req.file.filename}`;
await pool.query("update tbl_partners set logo_url = ? where transid = ?", [
filePath,
client_id,
]);
res.json({ message: "File uploaded successfully!", file_path: filePath });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
router.delete("/del/:fileid", async (req, res) => {
try {
const { fileid } = req.params;
const [files] = await pool.query(
"delete from tbl_files where transid =? ",
[fileid]
);
const [filesfromads] = await pool.query(
"delete from tbl_client_partner_mapping where fileid =? ",
[fileid]
);
res.json(files);
} catch (err) {
res.status(500), json({ error: err.message });
}
});
module.exports = router;

View File

@ -0,0 +1,94 @@
// uploadRoute.js
const express = require("express");
const upload = require("../middlewares/upload"); // Import the Multer middleware
const pool = require("../config/db");
const path = require("path");
const fs = require("fs-extra");
const ffmpeg = require("fluent-ffmpeg");
const router = express.Router();
// Ensure the uploads and optimized directories exist
const uploadDir = path.join(__dirname, "../uploads");
const optimizedDir = path.join(__dirname, "../optimized");
fs.ensureDirSync(uploadDir);
fs.ensureDirSync(optimizedDir);
async function optimizeVideo(inputPath, outputPath) {
return new Promise((resolve, reject) => {
ffmpeg(inputPath)
.videoCodec("libx264")
.audioCodec("aac")
.format("mp4")
.outputOptions([
"-movflags frag_keyframe+empty_moov",
"-preset medium",
"-crf 23",
"-maxrate 2M",
"-bufsize 4M",
])
.on("end", () => {
console.log("Video optimization completed.");
resolve();
})
.on("error", (err) => {
console.error("Error optimizing video:", err);
reject(err);
})
.save(outputPath);
});
}
// Upload file API
router.post("/upload", upload.single("file"), async (req, res) => {
try {
const { client_id, file_name } = req.body;
if (!req.file) {
return res.status(400).json({ error: "No file uploaded" });
}
const inputPath = path.join(uploadDir, req.file.filename);
const outputPath = path.join(optimizedDir, "optimized_" + req.file.filename);
const dbFilePath = `optimized/optimized_${req.file.filename}`;
if (req.file.mimetype.startsWith("video/")) {
try {
await optimizeVideo(inputPath, outputPath);
await pool.query(
"INSERT INTO tbl_files (transid, client_id, file_name, file_path) VALUES (UUID(), ?, ?, ?)",
[client_id, file_name, dbFilePath]
);
res.json({ message: "File uploaded and optimized successfully!", file_path: dbFilePath });
} catch (optimizeError) {
console.error("Optimization error:", optimizeError);
await pool.query(
"INSERT INTO tbl_files (transid, client_id, file_name, file_path) VALUES (UUID(), ?, ?, ?)",
[client_id, file_name, `uploads/${req.file.filename}`]
);
res.status(500).json({ message: "File uploaded, but optimization failed.", file_path: `uploads/${req.file.filename}` });
}
} else {
await pool.query(
"INSERT INTO tbl_files (transid, client_id, file_name, file_path) VALUES (UUID(), ?, ?, ?)",
[client_id, file_name, `uploads/${req.file.filename}`]
);
res.json({ message: "File uploaded successfully!", file_path: `uploads/${req.file.filename}` });
}
} catch (err) {
console.error("General upload error:", err);
res.status(500).json({ error: err.message });
}
});
router.delete("/del/:fileid", async (req, res) => {
try {
const { fileid } = req.params;
const [files] = await pool.query("delete from tbl_files where transid =? ", [fileid]);
const [filesfromads] = await pool.query("delete from tbl_client_partner_mapping where fileid =? ", [fileid]);
res.json(files);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
module.exports = router;

48
server.js Normal file
View File

@ -0,0 +1,48 @@
require("dotenv").config();
const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
const fetch = global.fetch || require("node-fetch"); // for Node < v18
const path = require("path");
const adminRoutes = require("./routes/adminRoutes");
const clientRoutes = require("./routes/clientRoutes");
const uploadRoutes = require("./routes/uploadRoutes");
const monitorRoutes = require("./routes/monitorRoutes");
const app = express();
// Middleware
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
// Routes
app.use("/uploads", express.static(path.join(__dirname, "uploads"), {
setHeaders: (res) => {
res.setHeader("Cache-Control", "public, max-age=604800, immutable");
}
}));
app.use("/api/admin", adminRoutes);
app.use("/api/client", clientRoutes);
app.use("/api/files", uploadRoutes);
app.use("/api/monitor", monitorRoutes);
app.get("/", (req, res) => {
res.send("Dine 360 Backend server is running...");
});
// Start server
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => {
console.log("✅ Server listening on port", PORT);
});