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

Linking the Bug Report Form with the Bug Log page through controllers (User Story 2) #42

Draft
wants to merge 18 commits into
base: f24
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion pidfile 2

This file was deleted.

12 changes: 12 additions & 0 deletions public/openapi/read.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -340,3 +340,15 @@ paths:
description: Bug reported successfully
'400':
description: Bad request

/api/admin/get-bug-log:
get:
summary: Get bug logs
description: Endpoint to get bug logs
responses:
'200':
description: Bug logs fetched successfully
'400':
description: Bad request


58 changes: 57 additions & 1 deletion public/src/admin/dashboard/bug-logs.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,62 @@
'use strict';

define('admin/dashboard/bug-logs', [], () => {
define('admin/dashboard/bug-logs', ['jquery', 'api'], ($, api) => {
const BugLogs = {};

BugLogs.init = () => {
// Fetch and display bug logs
fetchBugLogs();

// Handle bug report submission
$('#submit').on('click', submitBugReport);
};

function fetchBugLogs() {
api.get('/api/admin/get-bug-log')
.then((data) => {
const bugLogsContainer = $('#bug-logs-container');
console.log(bugLogsContainer);
bugLogsContainer.empty();

if (data.bugLogs && data.bugLogs.length > 0) {
console.log(data.bugLogs);
data.bugLogs.forEach((log) => {
const logElement = $('<div>').addClass('bug-log');
logElement.append($('<p>').text(`Name: ${log.name}`));
logElement.append($('<p>').text(`Email: ${log.email}`));
logElement.append($('<p>').text(`Description: ${log.bugDescription}`));
logElement.append($('<p>').text(`Timestamp: ${log.timestamp}`));
bugLogsContainer.append(logElement);
});
} else {
bugLogsContainer.append($('<p>').text('No bug logs found.'));
}
})
.catch((err) => {
console.error('Error fetching bug logs:', err);
$('#bug-logs-container').append($('<p>').text('Error fetching bug logs.'));
});
}

function submitBugReport() {
const description = $('#bug-report-description').val().trim();

if (!description) {
alert('Description is required');

Check warning on line 45 in public/src/admin/dashboard/bug-logs.js

View workflow job for this annotation

GitHub Actions / test

Unexpected alert
return;
}

api.post('/api/admin/submit-bug-report', { description })
.then(() => {
alert('Bug report submitted successfully');

Check warning on line 51 in public/src/admin/dashboard/bug-logs.js

View workflow job for this annotation

GitHub Actions / test

Unexpected alert
$('#bug-report-description').val('');
fetchBugLogs();
})
.catch((err) => {
console.error('Error submitting bug report:', err);
alert('Error submitting bug report');

Check warning on line 57 in public/src/admin/dashboard/bug-logs.js

View workflow job for this annotation

GitHub Actions / test

Unexpected alert
});
}

return BugLogs;
});
42 changes: 41 additions & 1 deletion src/controllers/admin/dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,46 @@ dashboardController.getSearches = async (req, res) => {
});
};

const bugLogs = [];

dashboardController.getBugLogs = async function (req, res) {
res.render('admin/dashboard/bug-logs', {});
console.log('getbuglogs'); // Add logging
try {
// Sanitize and format bug logs before rendering
console.log('bugLogs:', bugLogs);
const sanitizedBugLogs = bugLogs.map(log => ({
user: validator.escape(String(log.user)),
description: validator.escape(String(log.description)),
timestamp: new Date(log.timestamp).toISOString(),
}));

// Pass the sanitized bug logs to the view for rendering
res.render('admin/dashboard/bug-logs', { bugLogs: sanitizedBugLogs });
} catch (error) {
console.error('Error fetching bug logs:', error); // Log the error for debugging
res.status(500).json({ message: 'Internal server error' });
}
};

dashboardController.submitBugReport = async function (req, res) {
console.log('submitBugReport'); // Add logging
console.log('req.body:', req.body); // Add logging
try {
const { description } = req.body;
if (!description) {
return res.status(400).json({ message: 'Description is required' });
}

const sanitizedDescription = validator.escape(description);
const timestamp = Date.now();
const user = req.user ? req.user.username : 'Anonymous'; // Assuming req.user contains the user information

// Add the bug report to the in-memory array
bugLogs.push({ user, description: sanitizedDescription, timestamp });
console.log('Bug report submitted:', { user, description: sanitizedDescription, timestamp });
res.status(201).json({ message: 'Bug report submitted successfully' });
} catch (error) {
console.error('Error submitting bug report:', error); // Log the error for debugging
res.status(500).json({ message: 'Internal server error' });
}
};
4 changes: 3 additions & 1 deletion src/routes/admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,16 @@ module.exports = function (app, name, middleware, controllers) {
apiRoutes(app, name, middleware, controllers);
};


function apiRoutes(router, name, middleware, controllers) {
router.get(`/api/${name}/config`, middleware.ensureLoggedIn, helpers.tryRoute(controllers.admin.getConfig));
router.get(`/api/${name}/users/csv`, middleware.ensureLoggedIn, helpers.tryRoute(controllers.admin.users.getCSV));
router.get(`/api/${name}/groups/:groupname/csv`, middleware.ensureLoggedIn, helpers.tryRoute(controllers.admin.groups.getCSV));
router.get(`/api/${name}/analytics`, middleware.ensureLoggedIn, helpers.tryRoute(controllers.admin.dashboard.getAnalytics));
router.get(`/api/${name}/advanced/cache/dump`, middleware.ensureLoggedIn, helpers.tryRoute(controllers.admin.cache.dump));

router.get(`/api/${name}/get-bug-log`, middleware.ensureLoggedIn, helpers.tryRoute(controllers.admin.dashboard.getBugLogs));
router.post(`/api/${name}/submit-bug-report`, middleware.ensureLoggedIn, helpers.tryRoute(controllers.admin.dashboard.submitBugReport));

const multipart = require('connect-multiparty');
const multipartMiddleware = multipart();

Expand Down
10 changes: 5 additions & 5 deletions src/views/admin/dashboard/bug-logs.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<th>Timestamp</th>
</tr>
</thead>
<tbody>
<tbody id="bug-logs-container">
<!-- Use Benchpress syntax for iteration -->
{{{ if !bugs.length }}}
<tr>
Expand All @@ -19,10 +19,10 @@
{{{ end }}}
{{{ each bugs }}}
<tr>
<td><!-- IMPORT bugs.title --></td>
<td><!-- IMPORT bugs.description --></td>
<td><!-- IMPORT bugs.status --></td>
<td><!-- IMPORT bugs.timestamp --></td>
<td>{{title}}</td>
<td>{{description}}</td>
<td>{{status}}</td>
<td>{{timestamp}}</td>
</tr>
{{{ end }}}
</tbody>
Expand Down
77 changes: 62 additions & 15 deletions src/views/bug-report-form.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bug Report Form</title>
<meta name="csrf-token" content="{{csrfToken}}">
<style>
.container {
background-color: #fff;
Expand Down Expand Up @@ -95,21 +96,67 @@
<input type="submit" value="Submit">
</form>
</div>
<script>
document.getElementById('bug-report-form').addEventListener('submit', function(event) {
event.preventDefault(); // Prevent the form from submitting the traditional way
const banner = document.getElementById('form-banner');
const form = document.getElementById('bug-report-form');
banner.style.display = 'block'; // Show the banner
banner.classList.add('show'); // Add the class to slide in the banner
setTimeout(() => {
banner.classList.remove('show'); // Remove the class to slide out the banner

</body>
<script>

document.addEventListener('DOMContentLoaded', function() {
const form = document.getElementById('bug-report-form');
const banner = document.getElementById('form-banner');

form.addEventListener('submit', function(event) {
event.preventDefault();

const formData = new FormData(form);
const data = {
name: formData.get('name'),
email: formData.get('email'),
'bug-description': formData.get('bug-description')
};
console.log(data);

// Get CSRF token from meta tag or other source
const csrfTokenMeta = document.querySelector('meta[name="csrf-token"]');
const csrfToken = csrfTokenMeta ? csrfTokenMeta.getAttribute('content') : '';

fetch('/api/admin/submit-bug-report', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'CSRF-Token': csrfToken // Include CSRF token in headers
},
body: JSON.stringify(data)
})
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
})
.then(result => {
if (result.success) {
banner.textContent = 'Form Submitted Successfully';
banner.classList.add('show');
setTimeout(() => {
banner.classList.remove('show');
}, 3000);
} else {
banner.textContent = 'Form Submission Failed';
banner.classList.add('show');
setTimeout(() => {
banner.style.display = 'none'; // Hide the banner after the slide out
}, 500); // Match the transition duration
}, 3000); // Display the banner for 3 seconds
form.reset(); // Reset the form fields
banner.classList.remove('show');
}, 3000);
}
})
.catch(error => {
console.error('Error:', error);
banner.textContent = 'Form Submission Failed';
banner.classList.add('show');
setTimeout(() => {
banner.classList.remove('show');
}, 3000);
});
</script>
</body>
});
});
</script>
</html>