This commit is contained in:
Local Server
2025-12-19 20:44:46 -06:00
parent 701f799cde
commit e4b3de4a46
113 changed files with 16673 additions and 2174 deletions

View File

@@ -1,609 +1,350 @@
const express = require("express");
const { query } = require("../config/database");
const { requireAuth } = require("../middleware/auth");
const logger = require("../config/logger");
const { asyncHandler } = require("../middleware/errorHandler");
const { sendSuccess, sendError, sendNotFound } = require("../utils/responseHelpers");
const { getById, deleteById, countRecords } = require("../utils/queryHelpers");
const { HTTP_STATUS } = require("../config/constants");
const router = express.Router();
// Dashboard stats API
router.get("/dashboard/stats", requireAuth, async (req, res) => {
try {
const productsCount = await query("SELECT COUNT(*) FROM products");
const projectsCount = await query("SELECT COUNT(*) FROM portfolioprojects");
const blogCount = await query("SELECT COUNT(*) FROM blogposts");
const pagesCount = await query("SELECT COUNT(*) FROM pages");
router.get("/dashboard/stats", requireAuth, asyncHandler(async (req, res) => {
const [productsCount, projectsCount, blogCount, pagesCount] = await Promise.all([
countRecords("products"),
countRecords("portfolioprojects"),
countRecords("blogposts"),
countRecords("pages"),
]);
res.json({
success: true,
stats: {
products: parseInt(productsCount.rows[0].count),
projects: parseInt(projectsCount.rows[0].count),
blog: parseInt(blogCount.rows[0].count),
pages: parseInt(pagesCount.rows[0].count),
},
user: {
name: req.session.name,
email: req.session.email,
role: req.session.role,
},
});
} catch (error) {
console.error("Dashboard error:", error);
res.status(500).json({ success: false, message: "Server error" });
}
});
sendSuccess(res, {
stats: {
products: productsCount,
projects: projectsCount,
blog: blogCount,
pages: pagesCount,
},
user: {
name: req.session.name,
email: req.session.email,
role: req.session.role,
},
});
}));
// Products API
router.get("/products", requireAuth, async (req, res) => {
try {
// Generic CRUD factory function
const createCRUDRoutes = (config) => {
const { table, resourceName, listFields = "*", requiresAuth = true } = config;
const auth = requiresAuth ? requireAuth : (req, res, next) => next();
// List all
router.get(`/${resourceName}`, auth, asyncHandler(async (req, res) => {
const result = await query(
"SELECT id, name, price, stockquantity, isactive, createdat FROM products ORDER BY createdat DESC"
`SELECT ${listFields} FROM ${table} ORDER BY createdat DESC`
);
res.json({
success: true,
products: result.rows,
});
} catch (error) {
console.error("Products error:", error);
res.status(500).json({ success: false, message: "Server error" });
}
});
sendSuccess(res, { [resourceName]: result.rows });
}));
// Portfolio Projects API
router.get("/portfolio/projects", requireAuth, async (req, res) => {
try {
const result = await query(
"SELECT id, title, description, imageurl, categoryid, createdat FROM portfolioprojects ORDER BY createdat DESC"
);
res.json({
success: true,
projects: result.rows,
});
} catch (error) {
console.error("Portfolio error:", error);
res.status(500).json({ success: false, message: "Server error" });
}
});
// Blog Posts API
router.get("/blog", requireAuth, async (req, res) => {
try {
const result = await query(
"SELECT id, title, slug, excerpt, ispublished, createdat FROM blogposts ORDER BY createdat DESC"
);
res.json({
success: true,
posts: result.rows,
});
} catch (error) {
console.error("Blog error:", error);
res.status(500).json({ success: false, message: "Server error" });
}
});
// Pages API
router.get("/pages", requireAuth, async (req, res) => {
try {
const result = await query(
"SELECT id, title, slug, ispublished, createdat FROM pages ORDER BY createdat DESC"
);
res.json({
success: true,
pages: result.rows,
});
} catch (error) {
console.error("Pages error:", error);
res.status(500).json({ success: false, message: "Server error" });
}
});
// Get single product
router.get("/products/:id", requireAuth, async (req, res) => {
try {
const result = await query("SELECT * FROM products WHERE id = $1", [
req.params.id,
]);
if (result.rows.length === 0) {
return res
.status(404)
.json({ success: false, message: "Product not found" });
// Get by ID
router.get(`/${resourceName}/:id`, auth, asyncHandler(async (req, res) => {
const item = await getById(table, req.params.id);
if (!item) {
return sendNotFound(res, resourceName);
}
res.json({
success: true,
product: result.rows[0],
});
} catch (error) {
console.error("Product error:", error);
res.status(500).json({ success: false, message: "Server error" });
}
});
const responseKey = resourceName.slice(0, -1); // Remove 's' for singular
sendSuccess(res, { [responseKey]: item });
}));
// Create product
router.post("/products", requireAuth, async (req, res) => {
try {
const {
name,
description,
price,
stockquantity,
category,
isactive,
isbestseller,
} = req.body;
const result = await query(
`INSERT INTO products (name, description, price, stockquantity, category, isactive, isbestseller, createdat)
VALUES ($1, $2, $3, $4, $5, $6, $7, NOW())
RETURNING *`,
[
name,
description,
price,
stockquantity || 0,
category,
isactive !== false,
isbestseller || false,
]
);
res.json({
success: true,
product: result.rows[0],
message: "Product created successfully",
});
} catch (error) {
console.error("Create product error:", error);
res.status(500).json({ success: false, message: "Server error" });
}
});
// Update product
router.put("/products/:id", requireAuth, async (req, res) => {
try {
const {
name,
description,
price,
stockquantity,
category,
isactive,
isbestseller,
} = req.body;
const result = await query(
`UPDATE products
SET name = $1, description = $2, price = $3, stockquantity = $4,
category = $5, isactive = $6, isbestseller = $7, updatedat = NOW()
WHERE id = $8
RETURNING *`,
[
name,
description,
price,
stockquantity || 0,
category,
isactive !== false,
isbestseller || false,
req.params.id,
]
);
if (result.rows.length === 0) {
return res
.status(404)
.json({ success: false, message: "Product not found" });
// Delete
router.delete(`/${resourceName}/:id`, auth, asyncHandler(async (req, res) => {
const deleted = await deleteById(table, req.params.id);
if (!deleted) {
return sendNotFound(res, resourceName);
}
sendSuccess(res, { message: `${resourceName} deleted successfully` });
}));
};
res.json({
success: true,
product: result.rows[0],
message: "Product updated successfully",
});
} catch (error) {
console.error("Update product error:", error);
res.status(500).json({ success: false, message: "Server error" });
// Products CRUD
router.get("/products", requireAuth, asyncHandler(async (req, res) => {
const result = await query(
"SELECT id, name, price, stockquantity, isactive, createdat FROM products ORDER BY createdat DESC"
);
sendSuccess(res, { products: result.rows });
}));
router.get("/products/:id", requireAuth, asyncHandler(async (req, res) => {
const product = await getById("products", req.params.id);
if (!product) {
return sendNotFound(res, "Product");
}
});
sendSuccess(res, { product });
}));
// Delete product
router.delete("/products/:id", requireAuth, async (req, res) => {
try {
const result = await query(
"DELETE FROM products WHERE id = $1 RETURNING id",
[req.params.id]
);
router.post("/products", requireAuth, asyncHandler(async (req, res) => {
const { name, description, price, stockquantity, category, isactive, isbestseller } = req.body;
if (result.rows.length === 0) {
return res
.status(404)
.json({ success: false, message: "Product not found" });
}
const result = await query(
`INSERT INTO products (name, description, price, stockquantity, category, isactive, isbestseller, createdat)
VALUES ($1, $2, $3, $4, $5, $6, $7, NOW()) RETURNING *`,
[name, description, price, stockquantity || 0, category, isactive !== false, isbestseller || false]
);
res.json({
success: true,
message: "Product deleted successfully",
});
} catch (error) {
console.error("Delete product error:", error);
res.status(500).json({ success: false, message: "Server error" });
sendSuccess(res, {
product: result.rows[0],
message: "Product created successfully",
}, HTTP_STATUS.CREATED);
}));
router.put("/products/:id", requireAuth, asyncHandler(async (req, res) => {
const { name, description, price, stockquantity, category, isactive, isbestseller } = req.body;
const result = await query(
`UPDATE products
SET name = $1, description = $2, price = $3, stockquantity = $4,
category = $5, isactive = $6, isbestseller = $7, updatedat = NOW()
WHERE id = $8 RETURNING *`,
[name, description, price, stockquantity || 0, category, isactive !== false, isbestseller || false, req.params.id]
);
if (result.rows.length === 0) {
return sendNotFound(res, "Product");
}
});
// Portfolio Project CRUD
router.get("/portfolio/projects/:id", requireAuth, async (req, res) => {
try {
const result = await query(
"SELECT * FROM portfolioprojects WHERE id = $1",
[req.params.id]
);
if (result.rows.length === 0) {
return res
.status(404)
.json({ success: false, message: "Project not found" });
}
res.json({ success: true, project: result.rows[0] });
} catch (error) {
console.error("Portfolio project error:", error);
res.status(500).json({ success: false, message: "Server error" });
}
});
sendSuccess(res, {
product: result.rows[0],
message: "Product updated successfully",
});
}));
router.post("/portfolio/projects", requireAuth, async (req, res) => {
try {
const { title, description, category, isactive } = req.body;
const result = await query(
`INSERT INTO portfolioprojects (title, description, category, isactive, createdat)
VALUES ($1, $2, $3, $4, NOW()) RETURNING *`,
[title, description, category, isactive !== false]
);
res.json({
success: true,
project: result.rows[0],
message: "Project created successfully",
});
} catch (error) {
console.error("Create portfolio project error:", error);
res.status(500).json({ success: false, message: "Server error" });
router.delete("/products/:id", requireAuth, asyncHandler(async (req, res) => {
const deleted = await deleteById("products", req.params.id);
if (!deleted) {
return sendNotFound(res, "Product");
}
});
sendSuccess(res, { message: "Product deleted successfully" });
}));
router.put("/portfolio/projects/:id", requireAuth, async (req, res) => {
try {
const { title, description, category, isactive } = req.body;
const result = await query(
`UPDATE portfolioprojects
SET title = $1, description = $2, category = $3, isactive = $4, updatedat = NOW()
WHERE id = $5 RETURNING *`,
[title, description, category, isactive !== false, req.params.id]
);
if (result.rows.length === 0) {
return res
.status(404)
.json({ success: false, message: "Project not found" });
}
res.json({
success: true,
project: result.rows[0],
message: "Project updated successfully",
});
} catch (error) {
console.error("Update portfolio project error:", error);
res.status(500).json({ success: false, message: "Server error" });
}
});
// Portfolio Projects CRUD
router.get("/portfolio/projects", requireAuth, asyncHandler(async (req, res) => {
const result = await query(
"SELECT id, title, description, imageurl, categoryid, createdat FROM portfolioprojects ORDER BY createdat DESC"
);
sendSuccess(res, { projects: result.rows });
}));
router.delete("/portfolio/projects/:id", requireAuth, async (req, res) => {
try {
const result = await query(
"DELETE FROM portfolioprojects WHERE id = $1 RETURNING id",
[req.params.id]
);
if (result.rows.length === 0) {
return res
.status(404)
.json({ success: false, message: "Project not found" });
}
res.json({ success: true, message: "Project deleted successfully" });
} catch (error) {
console.error("Delete portfolio project error:", error);
res.status(500).json({ success: false, message: "Server error" });
router.get("/portfolio/projects/:id", requireAuth, asyncHandler(async (req, res) => {
const project = await getById("portfolioprojects", req.params.id);
if (!project) {
return sendNotFound(res, "Project");
}
});
sendSuccess(res, { project });
}));
// Blog Post CRUD
router.get("/blog/:id", requireAuth, async (req, res) => {
try {
const result = await query("SELECT * FROM blogposts WHERE id = $1", [
req.params.id,
]);
if (result.rows.length === 0) {
return res
.status(404)
.json({ success: false, message: "Blog post not found" });
}
res.json({ success: true, post: result.rows[0] });
} catch (error) {
console.error("Blog post error:", error);
res.status(500).json({ success: false, message: "Server error" });
}
});
router.post("/portfolio/projects", requireAuth, asyncHandler(async (req, res) => {
const { title, description, category, isactive } = req.body;
const result = await query(
`INSERT INTO portfolioprojects (title, description, category, isactive, createdat)
VALUES ($1, $2, $3, $4, NOW()) RETURNING *`,
[title, description, category, isactive !== false]
);
sendSuccess(res, {
project: result.rows[0],
message: "Project created successfully",
}, HTTP_STATUS.CREATED);
}));
router.post("/blog", requireAuth, async (req, res) => {
try {
const {
title,
slug,
excerpt,
content,
metatitle,
metadescription,
ispublished,
} = req.body;
const result = await query(
`INSERT INTO blogposts (title, slug, excerpt, content, metatitle, metadescription, ispublished, createdat)
VALUES ($1, $2, $3, $4, $5, $6, $7, NOW()) RETURNING *`,
[
title,
slug,
excerpt,
content,
metatitle,
metadescription,
ispublished || false,
]
);
res.json({
success: true,
post: result.rows[0],
message: "Blog post created successfully",
});
} catch (error) {
console.error("Create blog post error:", error);
res.status(500).json({ success: false, message: "Server error" });
router.put("/portfolio/projects/:id", requireAuth, asyncHandler(async (req, res) => {
const { title, description, category, isactive } = req.body;
const result = await query(
`UPDATE portfolioprojects
SET title = $1, description = $2, category = $3, isactive = $4, updatedat = NOW()
WHERE id = $5 RETURNING *`,
[title, description, category, isactive !== false, req.params.id]
);
if (result.rows.length === 0) {
return sendNotFound(res, "Project");
}
});
sendSuccess(res, {
project: result.rows[0],
message: "Project updated successfully",
});
}));
router.put("/blog/:id", requireAuth, async (req, res) => {
try {
const {
title,
slug,
excerpt,
content,
metatitle,
metadescription,
ispublished,
} = req.body;
const result = await query(
`UPDATE blogposts
SET title = $1, slug = $2, excerpt = $3, content = $4, metatitle = $5,
metadescription = $6, ispublished = $7, updatedat = NOW()
WHERE id = $8 RETURNING *`,
[
title,
slug,
excerpt,
content,
metatitle,
metadescription,
ispublished || false,
req.params.id,
]
);
if (result.rows.length === 0) {
return res
.status(404)
.json({ success: false, message: "Blog post not found" });
}
res.json({
success: true,
post: result.rows[0],
message: "Blog post updated successfully",
});
} catch (error) {
console.error("Update blog post error:", error);
res.status(500).json({ success: false, message: "Server error" });
router.delete("/portfolio/projects/:id", requireAuth, asyncHandler(async (req, res) => {
const deleted = await deleteById("portfolioprojects", req.params.id);
if (!deleted) {
return sendNotFound(res, "Project");
}
});
sendSuccess(res, { message: "Project deleted successfully" });
}));
router.delete("/blog/:id", requireAuth, async (req, res) => {
try {
const result = await query(
"DELETE FROM blogposts WHERE id = $1 RETURNING id",
[req.params.id]
);
if (result.rows.length === 0) {
return res
.status(404)
.json({ success: false, message: "Blog post not found" });
}
res.json({ success: true, message: "Blog post deleted successfully" });
} catch (error) {
console.error("Delete blog post error:", error);
res.status(500).json({ success: false, message: "Server error" });
// Blog Posts CRUD
router.get("/blog", requireAuth, asyncHandler(async (req, res) => {
const result = await query(
"SELECT id, title, slug, excerpt, ispublished, createdat FROM blogposts ORDER BY createdat DESC"
);
sendSuccess(res, { posts: result.rows });
}));
router.get("/blog/:id", requireAuth, asyncHandler(async (req, res) => {
const post = await getById("blogposts", req.params.id);
if (!post) {
return sendNotFound(res, "Blog post");
}
});
sendSuccess(res, { post });
}));
router.post("/blog", requireAuth, asyncHandler(async (req, res) => {
const { title, slug, excerpt, content, metatitle, metadescription, ispublished } = req.body;
const result = await query(
`INSERT INTO blogposts (title, slug, excerpt, content, metatitle, metadescription, ispublished, createdat)
VALUES ($1, $2, $3, $4, $5, $6, $7, NOW()) RETURNING *`,
[title, slug, excerpt, content, metatitle, metadescription, ispublished || false]
);
sendSuccess(res, {
post: result.rows[0],
message: "Blog post created successfully",
}, HTTP_STATUS.CREATED);
}));
router.put("/blog/:id", requireAuth, asyncHandler(async (req, res) => {
const { title, slug, excerpt, content, metatitle, metadescription, ispublished } = req.body;
const result = await query(
`UPDATE blogposts
SET title = $1, slug = $2, excerpt = $3, content = $4, metatitle = $5,
metadescription = $6, ispublished = $7, updatedat = NOW()
WHERE id = $8 RETURNING *`,
[title, slug, excerpt, content, metatitle, metadescription, ispublished || false, req.params.id]
);
if (result.rows.length === 0) {
return sendNotFound(res, "Blog post");
}
sendSuccess(res, {
post: result.rows[0],
message: "Blog post updated successfully",
});
}));
router.delete("/blog/:id", requireAuth, asyncHandler(async (req, res) => {
const deleted = await deleteById("blogposts", req.params.id);
if (!deleted) {
return sendNotFound(res, "Blog post");
}
sendSuccess(res, { message: "Blog post deleted successfully" });
}));
// Custom Pages CRUD
router.get("/pages/:id", requireAuth, async (req, res) => {
try {
const result = await query("SELECT * FROM pages WHERE id = $1", [
req.params.id,
]);
if (result.rows.length === 0) {
return res
.status(404)
.json({ success: false, message: "Page not found" });
}
res.json({ success: true, page: result.rows[0] });
} catch (error) {
console.error("Page error:", error);
res.status(500).json({ success: false, message: "Server error" });
}
});
router.get("/pages", requireAuth, asyncHandler(async (req, res) => {
const result = await query(
"SELECT id, title, slug, ispublished, createdat FROM pages ORDER BY createdat DESC"
);
sendSuccess(res, { pages: result.rows });
}));
router.post("/pages", requireAuth, async (req, res) => {
try {
const { title, slug, content, metatitle, metadescription, ispublished } =
req.body;
router.get("/pages/:id", requireAuth, asyncHandler(async (req, res) => {
const page = await getById("pages", req.params.id);
if (!page) {
return sendNotFound(res, "Page");
}
sendSuccess(res, { page });
}));
router.post("/pages", requireAuth, asyncHandler(async (req, res) => {
const { title, slug, content, metatitle, metadescription, ispublished } = req.body;
const result = await query(
`INSERT INTO pages (title, slug, content, metatitle, metadescription, ispublished, createdat)
VALUES ($1, $2, $3, $4, $5, $6, NOW()) RETURNING *`,
[title, slug, content, metatitle, metadescription, ispublished !== false]
);
sendSuccess(res, {
page: result.rows[0],
message: "Page created successfully",
}, HTTP_STATUS.CREATED);
}));
router.put("/pages/:id", requireAuth, asyncHandler(async (req, res) => {
const { title, slug, content, metatitle, metadescription, ispublished } = req.body;
const result = await query(
`UPDATE pages
SET title = $1, slug = $2, content = $3, metatitle = $4,
metadescription = $5, ispublished = $6, updatedat = NOW()
WHERE id = $7 RETURNING *`,
[title, slug, content, metatitle, metadescription, ispublished !== false, req.params.id]
);
if (result.rows.length === 0) {
return sendNotFound(res, "Page");
}
sendSuccess(res, {
page: result.rows[0],
message: "Page updated successfully",
});
}));
router.delete("/pages/:id", requireAuth, asyncHandler(async (req, res) => {
const deleted = await deleteById("pages", req.params.id);
if (!deleted) {
return sendNotFound(res, "Page");
}
sendSuccess(res, { message: "Page deleted successfully" });
}));
// Settings Management
const settingsHandler = (key) => ({
get: asyncHandler(async (req, res) => {
const result = await query(
`INSERT INTO pages (title, slug, content, metatitle, metadescription, ispublished, createdat)
VALUES ($1, $2, $3, $4, $5, $6, NOW()) RETURNING *`,
[title, slug, content, metatitle, metadescription, ispublished !== false]
"SELECT settings FROM site_settings WHERE key = $1",
[key]
);
res.json({
success: true,
page: result.rows[0],
message: "Page created successfully",
});
} catch (error) {
console.error("Create page error:", error);
res.status(500).json({ success: false, message: "Server error" });
}
});
router.put("/pages/:id", requireAuth, async (req, res) => {
try {
const { title, slug, content, metatitle, metadescription, ispublished } =
req.body;
const result = await query(
`UPDATE pages
SET title = $1, slug = $2, content = $3, metatitle = $4,
metadescription = $5, ispublished = $6, updatedat = NOW()
WHERE id = $7 RETURNING *`,
[
title,
slug,
content,
metatitle,
metadescription,
ispublished !== false,
req.params.id,
]
const settings = result.rows.length > 0 ? result.rows[0].settings : {};
sendSuccess(res, { settings });
}),
post: asyncHandler(async (req, res) => {
const settings = req.body;
await query(
`INSERT INTO site_settings (key, settings, updatedat)
VALUES ($1, $2, NOW())
ON CONFLICT (key) DO UPDATE SET settings = $2, updatedat = NOW()`,
[key, JSON.stringify(settings)]
);
if (result.rows.length === 0) {
return res
.status(404)
.json({ success: false, message: "Page not found" });
}
res.json({
success: true,
page: result.rows[0],
message: "Page updated successfully",
});
} catch (error) {
console.error("Update page error:", error);
res.status(500).json({ success: false, message: "Server error" });
}
});
router.delete("/pages/:id", requireAuth, async (req, res) => {
try {
const result = await query("DELETE FROM pages WHERE id = $1 RETURNING id", [
req.params.id,
]);
if (result.rows.length === 0) {
return res
.status(404)
.json({ success: false, message: "Page not found" });
}
res.json({ success: true, message: "Page deleted successfully" });
} catch (error) {
console.error("Delete page error:", error);
res.status(500).json({ success: false, message: "Server error" });
}
sendSuccess(res, { message: `${key} settings saved successfully` });
}),
});
// Homepage Settings
router.get("/homepage/settings", requireAuth, async (req, res) => {
try {
const result = await query(
"SELECT settings FROM site_settings WHERE key = 'homepage'"
);
const settings = result.rows.length > 0 ? result.rows[0].settings : {};
res.json({ success: true, settings });
} catch (error) {
console.error("Homepage settings error:", error);
res.json({ success: true, settings: {} });
}
});
router.post("/homepage/settings", requireAuth, async (req, res) => {
try {
const settings = req.body;
await query(
`INSERT INTO site_settings (key, settings, updatedat)
VALUES ('homepage', $1, NOW())
ON CONFLICT (key) DO UPDATE SET settings = $1, updatedat = NOW()`,
[JSON.stringify(settings)]
);
res.json({
success: true,
message: "Homepage settings saved successfully",
});
} catch (error) {
console.error("Save homepage settings error:", error);
res.status(500).json({ success: false, message: "Server error" });
}
});
const homepageSettings = settingsHandler("homepage");
router.get("/homepage/settings", requireAuth, homepageSettings.get);
router.post("/homepage/settings", requireAuth, homepageSettings.post);
// General Settings
router.get("/settings", requireAuth, async (req, res) => {
try {
const result = await query(
"SELECT settings FROM site_settings WHERE key = 'general'"
);
const settings = result.rows.length > 0 ? result.rows[0].settings : {};
res.json({ success: true, settings });
} catch (error) {
console.error("Settings error:", error);
res.json({ success: true, settings: {} });
}
});
router.post("/settings", requireAuth, async (req, res) => {
try {
const settings = req.body;
await query(
`INSERT INTO site_settings (key, settings, updatedat)
VALUES ('general', $1, NOW())
ON CONFLICT (key) DO UPDATE SET settings = $1, updatedat = NOW()`,
[JSON.stringify(settings)]
);
res.json({ success: true, message: "Settings saved successfully" });
} catch (error) {
console.error("Save settings error:", error);
res.status(500).json({ success: false, message: "Server error" });
}
});
const generalSettings = settingsHandler("general");
router.get("/settings", requireAuth, generalSettings.get);
router.post("/settings", requireAuth, generalSettings.post);
// Menu Management
router.get("/menu", requireAuth, async (req, res) => {
try {
const result = await query(
"SELECT settings FROM site_settings WHERE key = 'menu'"
);
const items =
result.rows.length > 0 ? result.rows[0].settings.items || [] : [];
res.json({ success: true, items });
} catch (error) {
console.error("Menu error:", error);
res.json({ success: true, items: [] });
}
});
router.get("/menu", requireAuth, asyncHandler(async (req, res) => {
const result = await query(
"SELECT settings FROM site_settings WHERE key = 'menu'"
);
const items = result.rows.length > 0 ? result.rows[0].settings.items || [] : [];
sendSuccess(res, { items });
}));
router.post("/menu", requireAuth, async (req, res) => {
try {
const { items } = req.body;
await query(
`INSERT INTO site_settings (key, settings, updatedat)
VALUES ('menu', $1, NOW())
ON CONFLICT (key) DO UPDATE SET settings = $1, updatedat = NOW()`,
[JSON.stringify({ items })]
);
res.json({ success: true, message: "Menu saved successfully" });
} catch (error) {
console.error("Save menu error:", error);
res.status(500).json({ success: false, message: "Server error" });
}
});
router.post("/menu", requireAuth, asyncHandler(async (req, res) => {
const { items } = req.body;
await query(
`INSERT INTO site_settings (key, settings, updatedat)
VALUES ('menu', $1, NOW())
ON CONFLICT (key) DO UPDATE SET settings = $1, updatedat = NOW()`,
[JSON.stringify({ items })]
);
sendSuccess(res, { message: "Menu saved successfully" });
}));
module.exports = router;