Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement controller and backend logic for isApproved feature #53

Merged
merged 9 commits into from
Oct 25, 2024
3 changes: 3 additions & 0 deletions src/cli/manage.js
Original file line number Diff line number Diff line change
Expand Up @@ -206,13 +206,16 @@ async function maintenance(toggle) {
async function buildWrapper(targets, options) {
try {
await build.build(targets, options);

process.exit(0);
} catch (err) {
winston.error(err.stack);
process.exit(1);
}
}



exports.build = buildWrapper;
exports.install = install;
exports.activate = activate;
Expand Down
32 changes: 32 additions & 0 deletions src/controllers/write/posts.js
Original file line number Diff line number Diff line change
Expand Up @@ -179,3 +179,35 @@ Posts.getReplies = async (req, res) => {

helpers.formatApiResponse(200, res, { replies });
};

async function markPostAsApproved(pid, uid) {
try {
// 1. Fetch the post by pid
const post = await db.getObject(`post:${pid}`);
if (!post) {
throw new Error(`Post with ID ${pid} not found`);
}

post.isApproved = !post.isApproved;

await db.setObject(`post:${pid}`, post);
return !post.isApproved;
} catch (err) {
console.error(`Failed to approve post ${pid}:`, err);
throw err;
}
}

Posts.approve = async (req, res) => {
console.log("Trying to approve");
try {
console.log("Approving post");
const { pid } = req.params;
// Assuming you have a function to mark the post as approved
const isApproved = await markPostAsApproved(pid, req.user.id);
console.log("Approved post");
res.status(200).json({ message: '[Server] Post approved successfully', isApproved: isApproved });
} catch (error) {
res.status(500).json({ error: '[Alert] An error occurred while approving the post' });
}
};
2 changes: 2 additions & 0 deletions src/install.js
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,8 @@ async function createWelcomePost() {
cid: 2,
title: 'Welcome to your NodeBB!',
content: content,
annonymousType: "none",
isApproved: true,
});
}
}
Expand Down
126 changes: 125 additions & 1 deletion src/meta/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -189,19 +189,143 @@ exports.build = async function (targets, options) {
} else {
winston.info('[build] Building in series mode');
}

await editTemplateFiles();
winston.info(`[build] Editing node_modules successful.`);

const startTime = Date.now();
await buildTargets(targets, !series, options);

const totalTime = (Date.now() - startTime) / 1000;
await cacheBuster.write();
winston.info(`[build] Asset compilation successful. Completed in ${totalTime}sec.`);

} catch (err) {
winston.error(`[build] Encountered error during build step`);
throw err;
}

};

async function editTemplateFiles() {
// Your code to modify files in node_modules/templates

await editPostTPL();

console.log(chalk.bold(chalk.green("Editing node_modules/nodebb-theme-harmony/templates/partials/topic/post.tpl")));
}

const fs = require('fs').promises;

async function editPostTPL() {
const templatePath = path.join('node_modules', 'nodebb-theme-harmony', 'templates', 'partials', 'topic', 'post.tpl');

try {
// Read the template file
let content = await fs.readFile(templatePath, 'utf8');

// Split the content into an array of lines
let lines = content.split('\n');

// Define the string to add at line 59
const stringToAddAtLine59 = `{{{ if ./isApproved }}}
<span class="verified-checkmark text-success">
<i class="fa fa-check-circle"></i>
<span class="text-muted">Instructor Approved</span>
</span>
{{{ end }}}`;

// Define the string to add at line 117
const stringToAddAtLine117 = `<button id="post-toggle-button-{./pid}" component="post/toggle-button" class="btn-ghost-sm" data-toggle="post-toggle" data-pid="{./pid}" data-csrf-token="{config.csrf_token}" >
<i class="fa fa-fw fa-toggle-on text-primary"></i>
<span id="toggle-span-{./pid}" class="text-muted">Approve Post</span>
</button>
<script>
$(document).on('click', '[component="post/toggle-button"]', function() {
const $this = $(this);
const pid = $this.attr('data-pid'); // get the post ID
const buttonId = '#post-toggle-button-' + pid; // build button ID
const spanId = '#toggle-span-' + pid; // build span ID
const csrfToken = $this.attr('data-csrf-token');
// Cache jQuery selections
const $button = $(buttonId);
const $span = $(spanId);

// Check if the button and span exist
if (!$button.length || !$span.length) {
console.error('Button or span not found for PID:', pid);
return; // Exit if elements are not found
}

const isApproved = $button.find('i').hasClass('fa-toggle-on') ? false : true; // toggle state

// Send the approval status to the server
$.ajax({
url: '/api/v3/posts/' + pid + '/approve',
method: 'PUT',
data: {
isApproved: isApproved,
CSRF: csrfToken
},
headers: {
'x-csrf-token': csrfToken,
'X-CSRFToken': csrfToken
},
success: function(response) {
// Handle success (update UI accordingly)
console.log("Approving successful. isApproved: ")
console.log(isApproved);
console.log("Response:");
console.log(response);
console.log("referring");
console.log(response.isApproved);
console.log("referring2");
console.log(response["isApproved"]);
if (response.isApproved) {
$button.find('i').removeClass('fa-toggle-on').addClass('fa-toggle-off');
$span.text('Disapprove Post');
} else {
$button.find('i').removeClass('fa-toggle-off').addClass('fa-toggle-on');
$span.text('Approve Post');
}
},
error: function(err) {
console.error('Error updating post approval status', err);
// Optionally notify the user of the error
alert('An error occurred while updating the post approval status. Please try again.');
}
});
});
</script>
`;

// Check if the content already contains the string for line 59
if (!content.includes(stringToAddAtLine59.trim())) {
// Insert the string at line 59 (keeping array zero-based, so line 58 in the array)
lines.splice(58, 0, stringToAddAtLine59);
} else {
console.log('String to add at line 59 already exists, skipping...');
}

// Check if the content already contains the string for line 117
if (!content.includes(stringToAddAtLine117.trim())) {
// Insert the string at line 117 (keeping array zero-based, so line 116 in the array)
lines.splice(116, 0, stringToAddAtLine117);
} else {
console.log('String to add at line 117 already exists, skipping...');
}

// Join the array back into a single string
content = lines.join('\n');

// Write the modified content back to the file
await fs.writeFile(templatePath, content, 'utf8');
console.log('Template file updated successfully!');
} catch (error) {
winston.error(`Failed to edit template file: ${error.message}`);
}
}


function getWebpackConfig() {
return require(process.env.NODE_ENV !== 'development' ? '../../webpack.prod' : '../../webpack.dev');
}
Expand Down
1 change: 1 addition & 0 deletions src/routes/write/posts.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ module.exports = function () {

// Shorthand route to access post routes by topic index
router.all('/+byIndex/:index*?', [middleware.checkRequired.bind(null, ['tid'])], controllers.write.posts.redirectByIndex);
setupApiRoute(router, 'put', '/:pid/approve', [...middlewares], controllers.write.posts.approve);

return router;
};