feat: Mail template management UI and API CRUD

- Added full CRUD endpoints for mail templates (create, update, delete, preview)
- Introduced Joi validators for template create/update/preview
- Updated routes/controller to support ID and type lookups
- Built React Templates page with HTML editor, preview, and clipboard helpers
- Added navigation entry and route for /templates
- Enhanced documentation (README, QUICKSTART, KULLANIM, frontend/backend README)
This commit is contained in:
salvacybersec
2025-11-10 17:27:19 +03:00
parent dc16d0c549
commit 20191eb35d
11 changed files with 661 additions and 13 deletions

View File

@@ -1,6 +1,11 @@
const { MailTemplate } = require('../models');
const mailService = require('../services/mail.service');
const buildTemplateResponse = (template) => ({
success: true,
data: template,
});
// Get all templates
exports.getAllTemplates = async (req, res, next) => {
try {
@@ -17,6 +22,25 @@ exports.getAllTemplates = async (req, res, next) => {
}
};
// Get template by ID
exports.getTemplateById = async (req, res, next) => {
try {
const { id } = req.params;
const template = await MailTemplate.findByPk(id);
if (!template) {
return res.status(404).json({
success: false,
error: 'Template not found',
});
}
res.json(buildTemplateResponse(template));
} catch (error) {
next(error);
}
};
// Get template by type
exports.getTemplateByType = async (req, res, next) => {
try {
@@ -33,9 +57,71 @@ exports.getTemplateByType = async (req, res, next) => {
});
}
res.json(buildTemplateResponse(template));
} catch (error) {
next(error);
}
};
// Create template
exports.createTemplate = async (req, res, next) => {
try {
const template = await MailTemplate.create(req.body);
res.status(201).json(buildTemplateResponse(template));
} catch (error) {
if (error.name === 'SequelizeUniqueConstraintError') {
return res.status(400).json({
success: false,
error: 'Bu template_type değeri zaten kullanılıyor.',
});
}
next(error);
}
};
// Update template
exports.updateTemplate = async (req, res, next) => {
try {
const { id } = req.params;
const template = await MailTemplate.findByPk(id);
if (!template) {
return res.status(404).json({
success: false,
error: 'Template not found',
});
}
await template.update(req.body);
res.json(buildTemplateResponse(template));
} catch (error) {
if (error.name === 'SequelizeUniqueConstraintError') {
return res.status(400).json({
success: false,
error: 'Bu template_type değeri zaten kullanılıyor.',
});
}
next(error);
}
};
// Delete template
exports.deleteTemplate = async (req, res, next) => {
try {
const { id } = req.params;
const template = await MailTemplate.findByPk(id);
if (!template) {
return res.status(404).json({
success: false,
error: 'Template not found',
});
}
await template.destroy();
res.json({
success: true,
data: template,
message: 'Template deleted successfully',
});
} catch (error) {
next(error);
@@ -68,5 +154,4 @@ exports.previewTemplate = async (req, res, next) => {
}
};
module.exports = exports;
module.exports = exports;