diff --git a/backend/controllers/feedbackController.js b/backend/controllers/feedbackController.js
new file mode 100644
index 0000000..a91f464
--- /dev/null
+++ b/backend/controllers/feedbackController.js
@@ -0,0 +1,31 @@
+const Feedback = require('../models/Feedback');
+
+// @desc Submit feedback
+// @route POST /api/feedback
+// @access Private
+const createFeedback = async (req, res) => {
+ try {
+ const { type, message } = req.body;
+
+ if (!type || !message) {
+ return res.status(400).json({ message: 'Type and message are required' });
+ }
+
+ const feedback = new Feedback({
+ user: req.user._id,
+ type,
+ message,
+ });
+
+ const savedFeedback = await feedback.save();
+
+ res.status(201).json(savedFeedback);
+ } catch (error) {
+ console.error(error);
+ res.status(500).json({ message: 'Server Error' });
+ }
+};
+
+module.exports = {
+ createFeedback,
+};
diff --git a/backend/models/Feedback.js b/backend/models/Feedback.js
new file mode 100644
index 0000000..a4e071c
--- /dev/null
+++ b/backend/models/Feedback.js
@@ -0,0 +1,30 @@
+const mongoose = require('mongoose');
+
+const feedbackSchema = new mongoose.Schema({
+ user: {
+ type: mongoose.Schema.Types.ObjectId,
+ ref: 'User',
+ required: true,
+ },
+ type: {
+ type: String,
+ enum: ['bug', 'feature', 'thought'],
+ required: true,
+ },
+ message: {
+ type: String,
+ required: true,
+ trim: true,
+ },
+ status: {
+ type: String,
+ enum: ['pending', 'reviewed', 'resolved'],
+ default: 'pending',
+ },
+}, {
+ timestamps: true,
+});
+
+const Feedback = mongoose.model('Feedback', feedbackSchema);
+
+module.exports = Feedback;
diff --git a/backend/routes/feedbackRoutes.js b/backend/routes/feedbackRoutes.js
new file mode 100644
index 0000000..71adeed
--- /dev/null
+++ b/backend/routes/feedbackRoutes.js
@@ -0,0 +1,8 @@
+const express = require('express');
+const router = express.Router();
+const { createFeedback } = require('../controllers/feedbackController');
+const { protect } = require('../middleware/authMiddleware');
+
+router.post('/', protect, createFeedback);
+
+module.exports = router;
diff --git a/backend/server.js b/backend/server.js
index b083d9c..e373b58 100644
--- a/backend/server.js
+++ b/backend/server.js
@@ -47,6 +47,7 @@ app.use('/api/receipts', require('./routes/receiptRoutes'));
app.use('/api/users', require('./routes/userRoutes'));
app.use('/api/budgets', require('./routes/budgetRoutes'));
app.use('/api/recurring', require('./routes/recurringTransactionRoutes'));
+app.use('/api/feedback', require('./routes/feedbackRoutes'));
// Serve static files from the uploads directory
app.use('/uploads', express.static(path.join(__dirname, 'uploads')));
diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx
index c45c3fc..aab5f92 100644
--- a/frontend/src/App.jsx
+++ b/frontend/src/App.jsx
@@ -16,6 +16,7 @@ import Layout from './components/Layout';
import ProtectedRoute from './components/ProtectedRoute';
import SetupProtectedRoute from './components/SetupProtectedRoute';
import RecurringTransactions from './pages/RecurringTransactions';
+import FeedbackPage from './pages/FeedbackPage';
function App() {
return (
@@ -52,6 +53,7 @@ function App() {
path="/recurring-transactions"
element={
+ Help us improve Paisable. Whether it's a bug, a feature request, or just some thoughts, we'd love to hear from you. +
+