Files
sst_site/routes/admin.js
2025-10-19 18:27:00 +09:00

387 lines
9.7 KiB
JavaScript

const express = require('express');
const router = express.Router();
const { body, validationResult } = require('express-validator');
const User = require('../models/User');
const Portfolio = require('../models/Portfolio');
const Service = require('../models/Service');
const Contact = require('../models/Contact');
const SiteSettings = require('../models/SiteSettings');
// Authentication middleware
const requireAuth = (req, res, next) => {
if (!req.session.user) {
return res.redirect('/admin/login');
}
next();
};
// Admin login page
router.get('/login', (req, res) => {
if (req.session.user) {
return res.redirect('/admin/dashboard');
}
res.render('admin/login', {
title: 'Admin Login - SmartSolTech',
layout: 'admin/layout',
error: null
});
});
// Admin login POST
router.post('/login', async (req, res) => {
try {
const { email, password } = req.body;
const user = await User.findOne({ email, isActive: true });
if (!user || !(await user.comparePassword(password))) {
return res.render('admin/login', {
title: 'Admin Login - SmartSolTech',
layout: 'admin/layout',
error: 'Invalid email or password'
});
}
await user.updateLastLogin();
req.session.user = {
id: user._id,
email: user.email,
name: user.name,
role: user.role
};
res.redirect('/admin/dashboard');
} catch (error) {
console.error('Admin login error:', error);
res.render('admin/login', {
title: 'Admin Login - SmartSolTech',
layout: 'admin/layout',
error: 'An error occurred. Please try again.'
});
}
});
// Admin logout
router.post('/logout', (req, res) => {
req.session.destroy(err => {
if (err) {
console.error('Logout error:', err);
}
res.redirect('/admin/login');
});
});
// Dashboard
router.get('/dashboard', requireAuth, async (req, res) => {
try {
const [
portfolioCount,
servicesCount,
contactsCount,
recentContacts,
recentPortfolio
] = await Promise.all([
Portfolio.countDocuments({ isPublished: true }),
Service.countDocuments({ isActive: true }),
Contact.countDocuments(),
Contact.find().sort({ createdAt: -1 }).limit(5),
Portfolio.find({ isPublished: true }).sort({ createdAt: -1 }).limit(5)
]);
const stats = {
portfolio: portfolioCount,
services: servicesCount,
contacts: contactsCount,
unreadContacts: await Contact.countDocuments({ isRead: false })
};
res.render('admin/dashboard', {
title: 'Dashboard - Admin Panel',
layout: 'admin/layout',
user: req.session.user,
stats,
recentContacts,
recentPortfolio
});
} catch (error) {
console.error('Dashboard error:', error);
res.status(500).render('admin/error', {
title: 'Error - Admin Panel',
layout: 'admin/layout',
message: 'Error loading dashboard'
});
}
});
// Portfolio management
router.get('/portfolio', requireAuth, async (req, res) => {
try {
const page = parseInt(req.query.page) || 1;
const limit = 20;
const skip = (page - 1) * limit;
const [portfolio, total] = await Promise.all([
Portfolio.find()
.sort({ createdAt: -1 })
.skip(skip)
.limit(limit),
Portfolio.countDocuments()
]);
const totalPages = Math.ceil(total / limit);
res.render('admin/portfolio/list', {
title: 'Portfolio Management - Admin Panel',
layout: 'admin/layout',
user: req.session.user,
portfolio,
pagination: {
current: page,
total: totalPages,
hasNext: page < totalPages,
hasPrev: page > 1
}
});
} catch (error) {
console.error('Portfolio list error:', error);
res.status(500).render('admin/error', {
title: 'Error - Admin Panel',
layout: 'admin/layout',
message: 'Error loading portfolio'
});
}
});
// Add portfolio item
router.get('/portfolio/add', requireAuth, (req, res) => {
res.render('admin/portfolio/add', {
title: 'Add Portfolio Item - Admin Panel',
layout: 'admin/layout',
user: req.session.user
});
});
// Edit portfolio item
router.get('/portfolio/edit/:id', requireAuth, async (req, res) => {
try {
const portfolio = await Portfolio.findById(req.params.id);
if (!portfolio) {
return res.status(404).render('admin/error', {
title: 'Error - Admin Panel',
layout: 'admin/layout',
message: 'Portfolio item not found'
});
}
res.render('admin/portfolio/edit', {
title: 'Edit Portfolio Item - Admin Panel',
layout: 'admin/layout',
user: req.session.user,
portfolio
});
} catch (error) {
console.error('Portfolio edit error:', error);
res.status(500).render('admin/error', {
title: 'Error - Admin Panel',
layout: 'admin/layout',
message: 'Error loading portfolio item'
});
}
});
// Services management
router.get('/services', requireAuth, async (req, res) => {
try {
const page = parseInt(req.query.page) || 1;
const limit = 20;
const skip = (page - 1) * limit;
const [services, total] = await Promise.all([
Service.find()
.sort({ createdAt: -1 })
.skip(skip)
.limit(limit),
Service.countDocuments()
]);
const totalPages = Math.ceil(total / limit);
res.render('admin/services/list', {
title: 'Services Management - Admin Panel',
layout: 'admin/layout',
user: req.session.user,
services,
pagination: {
current: page,
total: totalPages,
hasNext: page < totalPages,
hasPrev: page > 1
}
});
} catch (error) {
console.error('Services list error:', error);
res.status(500).render('admin/error', {
title: 'Error - Admin Panel',
layout: 'admin/layout',
message: 'Error loading services'
});
}
});
// Add service
router.get('/services/add', requireAuth, (req, res) => {
res.render('admin/services/add', {
title: 'Add Service - Admin Panel',
layout: 'admin/layout',
user: req.session.user
});
});
// Edit service
router.get('/services/edit/:id', requireAuth, async (req, res) => {
try {
const service = await Service.findById(req.params.id)
.populate('portfolio', 'title');
if (!service) {
return res.status(404).render('admin/error', {
title: 'Error - Admin Panel',
layout: 'admin/layout',
message: 'Service not found'
});
}
const availablePortfolio = await Portfolio.find({ isPublished: true })
.select('title category');
res.render('admin/services/edit', {
title: 'Edit Service - Admin Panel',
layout: 'admin/layout',
user: req.session.user,
service,
availablePortfolio
});
} catch (error) {
console.error('Service edit error:', error);
res.status(500).render('admin/error', {
title: 'Error - Admin Panel',
layout: 'admin/layout',
message: 'Error loading service'
});
}
});
// Contacts management
router.get('/contacts', requireAuth, async (req, res) => {
try {
const page = parseInt(req.query.page) || 1;
const limit = 20;
const skip = (page - 1) * limit;
const status = req.query.status;
let query = {};
if (status && status !== 'all') {
query.status = status;
}
const [contacts, total] = await Promise.all([
Contact.find(query)
.sort({ createdAt: -1 })
.skip(skip)
.limit(limit),
Contact.countDocuments(query)
]);
const totalPages = Math.ceil(total / limit);
res.render('admin/contacts/list', {
title: 'Contacts Management - Admin Panel',
layout: 'admin/layout',
user: req.session.user,
contacts,
currentStatus: status || 'all',
pagination: {
current: page,
total: totalPages,
hasNext: page < totalPages,
hasPrev: page > 1
}
});
} catch (error) {
console.error('Contacts list error:', error);
res.status(500).render('admin/error', {
title: 'Error - Admin Panel',
layout: 'admin/layout',
message: 'Error loading contacts'
});
}
});
// View contact details
router.get('/contacts/:id', requireAuth, async (req, res) => {
try {
const contact = await Contact.findById(req.params.id);
if (!contact) {
return res.status(404).render('admin/error', {
title: 'Error - Admin Panel',
layout: 'admin/layout',
message: 'Contact not found'
});
}
// Mark as read
if (!contact.isRead) {
contact.isRead = true;
await contact.save();
}
res.render('admin/contacts/view', {
title: 'Contact Details - Admin Panel',
layout: 'admin/layout',
user: req.session.user,
contact
});
} catch (error) {
console.error('Contact view error:', error);
res.status(500).render('admin/error', {
title: 'Error - Admin Panel',
layout: 'admin/layout',
message: 'Error loading contact'
});
}
});
// Settings
router.get('/settings', requireAuth, async (req, res) => {
try {
const settings = await SiteSettings.findOne() || new SiteSettings();
res.render('admin/settings', {
title: 'Site Settings - Admin Panel',
layout: 'admin/layout',
user: req.session.user,
settings
});
} catch (error) {
console.error('Settings error:', error);
res.status(500).render('admin/error', {
title: 'Error - Admin Panel',
layout: 'admin/layout',
message: 'Error loading settings'
});
}
});
// Media gallery
router.get('/media', requireAuth, (req, res) => {
res.render('admin/media', {
title: 'Media Gallery - Admin Panel',
layout: 'admin/layout',
user: req.session.user
});
});
module.exports = router;