From 102c0bd1be29eb95efbb524064b433b280fbea58 Mon Sep 17 00:00:00 2001 From: Piyush Aditya Kar <74527230+HilariousSoupXD@users.noreply.github.com> Date: Fri, 11 Apr 2025 00:34:35 +0530 Subject: [PATCH 1/8] Added complaint tracking system, updated the code elsewhere for stability. --- ComplaintBox.cpp | 35 +++++++++++++++++++++++++++++------ ComplaintBox.h | 1 + complaints_export.csv | 9 +++++---- main.cpp | 26 ++++++++++++++++++++------ 4 files changed, 55 insertions(+), 16 deletions(-) diff --git a/ComplaintBox.cpp b/ComplaintBox.cpp index 6abd894..0034579 100644 --- a/ComplaintBox.cpp +++ b/ComplaintBox.cpp @@ -96,12 +96,14 @@ void ComplaintBox::fileComplaint() { cout << YELLOW << "Enter complaint message: " << RESET; getline(cin, message); - string sql = "INSERT INTO complaints (category, subCategory, message) VALUES ('" + category + "', '" + subCategory + "', '" + message + "');"; + string sql = "INSERT INTO complaints (category, subCategory, message, status) VALUES ('" + + category + "', '" + subCategory + "', '" + message + "', 'Pending');"; + if (sqlite3_exec(db, sql.c_str(), 0, 0, &errMsg) != SQLITE_OK) { cout << RED << "Error: " << errMsg << RESET << endl; sqlite3_free(errMsg); } else { - cout << BOLDGREEN << "Complaint filed successfully!\n" << RESET; + cout << BOLDGREEN << "Complaint filed successfully with status 'Pending'!\n" << RESET; } } @@ -112,8 +114,8 @@ void ComplaintBox::exportComplaintsToCSV() { return; } - file << "complaint_id,category,subCategory,message\n"; - string sql = "SELECT complaint_id, category, subCategory, message FROM complaints;"; + file << "complaint_id,category,subCategory,message,status\n"; + string sql = "SELECT complaint_id, category, subCategory, message, status FROM complaints;"; auto callback = [](void *data, int argc, char **argv, char **colName) -> int { ofstream *f = static_cast(data); for (int i = 0; i < argc; i++) { @@ -138,10 +140,11 @@ void ComplaintBox::searchComplaints() { cin.ignore(); getline(cin, keyword); - string sql = "SELECT complaint_id, category, subCategory, message FROM complaints " + string sql = "SELECT complaint_id, category, subCategory, message, status FROM complaints " "WHERE category LIKE '%" + keyword + "%' OR " "subCategory LIKE '%" + keyword + "%' OR " - "message LIKE '%" + keyword + "%';"; + "message LIKE '%" + keyword + "%' OR " + "status LIKE '%" + keyword + "%';"; cout << CYAN << "\nSearch Results:\n" << RESET; auto callback = [](void *data, int argc, char **argv, char **colName) -> int { @@ -157,3 +160,23 @@ void ComplaintBox::searchComplaints() { sqlite3_free(errMsg); } } + + +void ComplaintBox::updateComplaintStatus(int complaint_id, const std::string& new_status) { + sqlite3_stmt* stmt; + std::string sql = "UPDATE complaints SET status = ? WHERE complaint_id = ?"; + + if (sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, nullptr) == SQLITE_OK) { + sqlite3_bind_text(stmt, 1, new_status.c_str(), -1, SQLITE_STATIC); + sqlite3_bind_int(stmt, 2, complaint_id); + + if (sqlite3_step(stmt) == SQLITE_DONE) { + cout << GREEN << "Status updated successfully.\n" << RESET; + } else { + cerr << RED << "Failed to update status.\n" << RESET; + } + } else { + cerr << RED << "SQL Prepare Failed: " << sqlite3_errmsg(db) << "\n" << RESET; + } + sqlite3_finalize(stmt); +} \ No newline at end of file diff --git a/ComplaintBox.h b/ComplaintBox.h index 4dbc09a..7e2a703 100644 --- a/ComplaintBox.h +++ b/ComplaintBox.h @@ -26,6 +26,7 @@ class ComplaintBox { void fileComplaint(); void exportComplaintsToCSV(); void searchComplaints(); + void updateComplaintStatus(int complaint_id, const std::string& new_status); private: sqlite3 *db; diff --git a/complaints_export.csv b/complaints_export.csv index eb444d4..468864e 100644 --- a/complaints_export.csv +++ b/complaints_export.csv @@ -1,4 +1,5 @@ -complaint_id,category,subCategory,message -1,Infrastructural,Hostel,Washrooms are not being regularly cleaned. -2,Management,College Events,Admin paisa kha gaya bc -3,Infrastructure,Hostel,MMC change karo mc +complaint_id,category,subCategory,message,status +1,Infrastructural,Hostel,Washrooms are not being regularly cleaned.,Pending +2,Management,College Events,Admin paisa kha gaya bc,Resolved +3,Infrastructure,Hostel,MMC change karo mc,Pending +4,College,Clasroom,ACs need to be installed,Pending diff --git a/main.cpp b/main.cpp index d9c12f7..8836659 100644 --- a/main.cpp +++ b/main.cpp @@ -8,15 +8,18 @@ int main() { do { cout << BOLDVIOLET << "\n==== Complaint Box Menu ====\n" << RESET; - cout << CYAN << "1. Register User\n" + cout << CYAN + << "1. Register User\n" << "2. Register Admin\n" << "3. User Login\n" << "4. Admin Login\n" << "5. File Complaint\n" << "6. Export Complaints to CSV\n" << "7. Search Complaints\n" - << "8. Exit\n" << RESET; - + << "8. Update Complaint Status (Admin Only)\n" + << "9. Exit\n" + << RESET; + cout << WHITE << "Choice: " << RESET; cin >> choice; @@ -42,13 +45,24 @@ int main() { case 7: cb.searchComplaints(); break; - case 8: + case 8: { + int id; + string status; + cout << YELLOW << "Enter Complaint ID to update: " << RESET; + cin >> id; + cout << YELLOW << "Enter new status (Pending/In Progress/Resolved): " << RESET; + cin.ignore(); + getline(cin, status); + cb.updateComplaintStatus(id, status); + break; + } + case 9: cout << BOLDGREEN << "Exiting..." << RESET << endl; break; default: cout << BOLDRED << "Invalid choice!\n" << RESET; } - } while (choice != 8); + } while (choice != 9); return 0; -} +} \ No newline at end of file From b770174cc6fb5bc76a24e18eae8f81993b98dd8f Mon Sep 17 00:00:00 2001 From: Piyush Aditya Kar <74527230+HilariousSoupXD@users.noreply.github.com> Date: Fri, 11 Apr 2025 12:39:51 +0530 Subject: [PATCH 2/8] Improved control flow by restricting Complaint Status feature --- ComplaintBox.cpp | 10 +++++++++- ComplaintBox.h | 4 +++- main.cpp | 26 +++++++++++++++----------- 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/ComplaintBox.cpp b/ComplaintBox.cpp index 0034579..1f97755 100644 --- a/ComplaintBox.cpp +++ b/ComplaintBox.cpp @@ -79,6 +79,7 @@ bool ComplaintBox::loginUser(bool isAdmin) { if (success) { cout << GREEN << "Login successful!\n" << RESET; + admin_logged_in = isAdmin; return true; } else { cout << RED << "Invalid credentials!\n" << RESET; @@ -86,6 +87,7 @@ bool ComplaintBox::loginUser(bool isAdmin) { } } + void ComplaintBox::fileComplaint() { string category, subCategory, message; cout << YELLOW << "Enter category: " << RESET; @@ -163,8 +165,13 @@ void ComplaintBox::searchComplaints() { void ComplaintBox::updateComplaintStatus(int complaint_id, const std::string& new_status) { + if (!admin_logged_in) { + cout << RED << "Only admins can update complaint status.\n" << RESET; + return; + } + sqlite3_stmt* stmt; - std::string sql = "UPDATE complaints SET status = ? WHERE complaint_id = ?"; + string sql = "UPDATE complaints SET status = ? WHERE complaint_id = ?"; if (sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, nullptr) == SQLITE_OK) { sqlite3_bind_text(stmt, 1, new_status.c_str(), -1, SQLITE_STATIC); @@ -178,5 +185,6 @@ void ComplaintBox::updateComplaintStatus(int complaint_id, const std::string& ne } else { cerr << RED << "SQL Prepare Failed: " << sqlite3_errmsg(db) << "\n" << RESET; } + sqlite3_finalize(stmt); } \ No newline at end of file diff --git a/ComplaintBox.h b/ComplaintBox.h index 7e2a703..9dd08c8 100644 --- a/ComplaintBox.h +++ b/ComplaintBox.h @@ -26,11 +26,13 @@ class ComplaintBox { void fileComplaint(); void exportComplaintsToCSV(); void searchComplaints(); - void updateComplaintStatus(int complaint_id, const std::string& new_status); + void updateComplaintStatus(int complaint_id, const string& new_status); + bool isAdminLoggedIn() const { return admin_logged_in; } private: sqlite3 *db; char *errMsg; + bool admin_logged_in = false; void createTables(); }; diff --git a/main.cpp b/main.cpp index 8836659..b358068 100644 --- a/main.cpp +++ b/main.cpp @@ -45,17 +45,21 @@ int main() { case 7: cb.searchComplaints(); break; - case 8: { - int id; - string status; - cout << YELLOW << "Enter Complaint ID to update: " << RESET; - cin >> id; - cout << YELLOW << "Enter new status (Pending/In Progress/Resolved): " << RESET; - cin.ignore(); - getline(cin, status); - cb.updateComplaintStatus(id, status); - break; - } + case 8: + if (!cb.isAdminLoggedIn()) { + cout << RED << "Only admins can update complaint status. Please login as admin first.\n" << RESET; + break; + } else { + int id; + string status; + cout << YELLOW << "Enter Complaint ID to update: " << RESET; + cin >> id; + cin.ignore(); + cout << YELLOW << "Enter new status (Pending/In Progress/Resolved): " << RESET; + getline(cin, status); + cb.updateComplaintStatus(id, status); + break; + } case 9: cout << BOLDGREEN << "Exiting..." << RESET << endl; break; From a504e01566ba2a7e696bbfeec8da716e0accda58 Mon Sep 17 00:00:00 2001 From: Piyush Aditya Kar <74527230+HilariousSoupXD@users.noreply.github.com> Date: Fri, 11 Apr 2025 19:00:07 +0530 Subject: [PATCH 3/8] Added pasword hashing --- ComplaintBox.cpp | 20 ++++++++++++++++++-- main.cpp | 5 +++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/ComplaintBox.cpp b/ComplaintBox.cpp index 1f97755..0802a46 100644 --- a/ComplaintBox.cpp +++ b/ComplaintBox.cpp @@ -3,9 +3,22 @@ #include #include #include +#include using namespace std; +string hashPassword(const string& password) { + unsigned char hash[SHA256_DIGEST_LENGTH]; + SHA256((const unsigned char*)password.c_str(), password.size(), hash); + + stringstream ss; + for (int i = 0; i < SHA256_DIGEST_LENGTH; ++i) + ss << hex << setw(2) << setfill('0') << (int)hash[i]; + + return ss.str(); +} + + ComplaintBox::ComplaintBox() { sqlite3_open("complaints.db", &db); createTables(); @@ -51,7 +64,8 @@ void ComplaintBox::registerUser(bool isAdmin) { cin >> pass; string table = isAdmin ? "adminusers" : "users"; - string sql = "INSERT INTO " + table + " (username, password) VALUES ('" + uname + "', '" + pass + "');"; + string hashedPass = hashPassword(pass); + string sql = "INSERT INTO " + table + " (username, password) VALUES ('" + uname + "', '" + hashedPass + "');"; if (sqlite3_exec(db, sql.c_str(), 0, 0, &errMsg) != SQLITE_OK) { cout << RED << "Error: " << errMsg << RESET << endl; @@ -69,7 +83,9 @@ bool ComplaintBox::loginUser(bool isAdmin) { cin >> pass; string table = isAdmin ? "adminusers" : "users"; - string sql = "SELECT * FROM " + table + " WHERE username = '" + uname + "' AND password = '" + pass + "';"; + string hashedPass = hashPassword(pass); + string sql = "SELECT * FROM " + table + " WHERE username = '" + uname + "' AND password = '" + hashedPass + "';"; + bool success = false; sqlite3_exec(db, sql.c_str(), [](void *successPtr, int, char **, char **) -> int { diff --git a/main.cpp b/main.cpp index 027abaf..5963d2a 100644 --- a/main.cpp +++ b/main.cpp @@ -1,11 +1,12 @@ +// g++ main.cpp ComplaintBox.cpp -lssl -lcrypto -lsqlite3 -o complaintbox + #include #include "ComplaintBox.h" using namespace std; int main() { ComplaintBox cb; - string choice; - int choiceNum = 0; + int choice = 0; do { cout << BOLDVIOLET << "\n==== Complaint Box Menu ====\n" << RESET; From 041522bcd53124b4cf9f3c5b15f2fb45707c6f64 Mon Sep 17 00:00:00 2001 From: Piyush Aditya Kar <74527230+HilariousSoupXD@users.noreply.github.com> Date: Fri, 11 Apr 2025 19:41:50 +0530 Subject: [PATCH 4/8] Added fucntionality to mask passwords --- ComplaintBox.cpp | 50 ++++++++++++++++++++++++++++++++++--------- complaints_export.csv | 6 ++---- 2 files changed, 42 insertions(+), 14 deletions(-) diff --git a/ComplaintBox.cpp b/ComplaintBox.cpp index 0802a46..9b95657 100644 --- a/ComplaintBox.cpp +++ b/ComplaintBox.cpp @@ -4,9 +4,28 @@ #include #include #include +#include using namespace std; +string getHiddenPassword() { + string pass; + char ch; + while ((ch = _getch()) != '\r') { // Enter key + if (ch == '\b') { // Backspace + if (!pass.empty()) { + cout << "\b \b"; + pass.pop_back(); + } + } else { + pass += ch; + cout << '*'; + } + } + cout << endl; + return pass; +} + string hashPassword(const string& password) { unsigned char hash[SHA256_DIGEST_LENGTH]; SHA256((const unsigned char*)password.c_str(), password.size(), hash); @@ -32,10 +51,12 @@ void ComplaintBox::createTables() { string sqlUsers = "CREATE TABLE IF NOT EXISTS users (username TEXT PRIMARY KEY, password TEXT);"; string sqlAdmins = "CREATE TABLE IF NOT EXISTS adminusers (username TEXT PRIMARY KEY, password TEXT);"; string sqlComplaints = "CREATE TABLE IF NOT EXISTS complaints (" - "complaint_id INTEGER PRIMARY KEY AUTOINCREMENT, " - "category TEXT, " - "subCategory TEXT, " - "message TEXT);"; + "complaint_id INTEGER PRIMARY KEY AUTOINCREMENT, " + "category TEXT, " + "subCategory TEXT, " + "message TEXT, " + "status TEXT DEFAULT 'Pending');"; + sqlite3_exec(db, sqlUsers.c_str(), 0, 0, &errMsg); sqlite3_exec(db, sqlAdmins.c_str(), 0, 0, &errMsg); @@ -43,7 +64,7 @@ void ComplaintBox::createTables() { } void ComplaintBox::registerUser(bool isAdmin) { - string uname, pass; + string uname; cout << PURPLE << "Enter username: " << RESET; cin >> uname; @@ -61,13 +82,21 @@ void ComplaintBox::registerUser(bool isAdmin) { } cout << PURPLE << "Enter password: " << RESET; - cin >> pass; + string pass1 = getHiddenPassword(); + + cout << PURPLE << "Confirm password: " << RESET; + string pass2 = getHiddenPassword(); + + if (pass1 != pass2) { + cout << RED << "Passwords do not match. Registration failed.\n" << RESET; + return; + } string table = isAdmin ? "adminusers" : "users"; - string hashedPass = hashPassword(pass); - string sql = "INSERT INTO " + table + " (username, password) VALUES ('" + uname + "', '" + hashedPass + "');"; + string hashedPass = hashPassword(pass1); + string insertSql = "INSERT INTO " + table + " (username, password) VALUES ('" + uname + "', '" + hashedPass + "');"; - if (sqlite3_exec(db, sql.c_str(), 0, 0, &errMsg) != SQLITE_OK) { + if (sqlite3_exec(db, insertSql.c_str(), 0, 0, &errMsg) != SQLITE_OK) { cout << RED << "Error: " << errMsg << RESET << endl; sqlite3_free(errMsg); } else { @@ -75,12 +104,13 @@ void ComplaintBox::registerUser(bool isAdmin) { } } + bool ComplaintBox::loginUser(bool isAdmin) { string uname, pass; cout << CYAN << "Enter username: " << RESET; cin >> uname; cout << CYAN << "Enter password: " << RESET; - cin >> pass; + pass = getHiddenPassword(); string table = isAdmin ? "adminusers" : "users"; string hashedPass = hashPassword(pass); diff --git a/complaints_export.csv b/complaints_export.csv index 468864e..8370284 100644 --- a/complaints_export.csv +++ b/complaints_export.csv @@ -1,5 +1,3 @@ complaint_id,category,subCategory,message,status -1,Infrastructural,Hostel,Washrooms are not being regularly cleaned.,Pending -2,Management,College Events,Admin paisa kha gaya bc,Resolved -3,Infrastructure,Hostel,MMC change karo mc,Pending -4,College,Clasroom,ACs need to be installed,Pending +1,Infrastructure,Fests,Admin paisa kha gaya bc,Pending +2,Hostel,Mess,MMC badlo mc,Pending From d00712db69beda1c82e37dfb97f0a2b8f4533e50 Mon Sep 17 00:00:00 2001 From: Piyush Aditya Kar <74527230+HilariousSoupXD@users.noreply.github.com> Date: Fri, 11 Apr 2025 20:16:18 +0530 Subject: [PATCH 5/8] Timestamp of the filled complaint is now being tracked and can be exported --- ComplaintBox.cpp | 26 ++++++++++++++------------ complaints_export.csv | 5 ++--- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/ComplaintBox.cpp b/ComplaintBox.cpp index 9b95657..e19d356 100644 --- a/ComplaintBox.cpp +++ b/ComplaintBox.cpp @@ -51,12 +51,12 @@ void ComplaintBox::createTables() { string sqlUsers = "CREATE TABLE IF NOT EXISTS users (username TEXT PRIMARY KEY, password TEXT);"; string sqlAdmins = "CREATE TABLE IF NOT EXISTS adminusers (username TEXT PRIMARY KEY, password TEXT);"; string sqlComplaints = "CREATE TABLE IF NOT EXISTS complaints (" - "complaint_id INTEGER PRIMARY KEY AUTOINCREMENT, " - "category TEXT, " - "subCategory TEXT, " - "message TEXT, " - "status TEXT DEFAULT 'Pending');"; - + "complaint_id INTEGER PRIMARY KEY AUTOINCREMENT, " + "category TEXT, " + "subCategory TEXT, " + "message TEXT, " + "status TEXT DEFAULT 'Pending', " + "timestamp DATETIME DEFAULT CURRENT_TIMESTAMP);"; sqlite3_exec(db, sqlUsers.c_str(), 0, 0, &errMsg); sqlite3_exec(db, sqlAdmins.c_str(), 0, 0, &errMsg); @@ -155,15 +155,17 @@ void ComplaintBox::fileComplaint() { } } + void ComplaintBox::exportComplaintsToCSV() { ofstream file("complaints_export.csv"); if (!file.is_open()) { cout << RED << "Failed to create CSV file.\n" << RESET; return; } - - file << "complaint_id,category,subCategory,message,status\n"; - string sql = "SELECT complaint_id, category, subCategory, message, status FROM complaints;"; + + file << "complaint_id,category,subCategory,message,status,timestamp\n"; // Include timestamp in header + string sql = "SELECT complaint_id, category, subCategory, message, status, timestamp FROM complaints;"; // Include timestamp + auto callback = [](void *data, int argc, char **argv, char **colName) -> int { ofstream *f = static_cast(data); for (int i = 0; i < argc; i++) { @@ -171,14 +173,14 @@ void ComplaintBox::exportComplaintsToCSV() { } return 0; }; - + if (sqlite3_exec(db, sql.c_str(), callback, &file, &errMsg) != SQLITE_OK) { cout << RED << "Export failed: " << errMsg << RESET << endl; sqlite3_free(errMsg); } else { - cout << BOLDGREEN << "Complaints exported to 'complaints_export.csv'!\n" << RESET; + cout << BOLDGREEN << "Complaints exported to 'complaints_export.csv' with timestamp!\n" << RESET; } - + file.close(); } diff --git a/complaints_export.csv b/complaints_export.csv index 8370284..20d4075 100644 --- a/complaints_export.csv +++ b/complaints_export.csv @@ -1,3 +1,2 @@ -complaint_id,category,subCategory,message,status -1,Infrastructure,Fests,Admin paisa kha gaya bc,Pending -2,Hostel,Mess,MMC badlo mc,Pending +complaint_id,category,subCategory,message,status,timestamp +1,College,Fests,Admin chor mc,Pending,2025-04-11 14:43:14 From 4f521f1f7410a23751c08737bde160f0ffd2169b Mon Sep 17 00:00:00 2001 From: Piyush Aditya Kar <74527230+HilariousSoupXD@users.noreply.github.com> Date: Fri, 11 Apr 2025 22:18:22 +0530 Subject: [PATCH 6/8] Added notification system for admins --- ComplaintBox.cpp | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/ComplaintBox.cpp b/ComplaintBox.cpp index e19d356..34bdb50 100644 --- a/ComplaintBox.cpp +++ b/ComplaintBox.cpp @@ -56,7 +56,8 @@ void ComplaintBox::createTables() { "subCategory TEXT, " "message TEXT, " "status TEXT DEFAULT 'Pending', " - "timestamp DATETIME DEFAULT CURRENT_TIMESTAMP);"; + "timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, " + "notified INTEGER DEFAULT 0);"; sqlite3_exec(db, sqlUsers.c_str(), 0, 0, &errMsg); sqlite3_exec(db, sqlAdmins.c_str(), 0, 0, &errMsg); @@ -125,7 +126,26 @@ bool ComplaintBox::loginUser(bool isAdmin) { if (success) { cout << GREEN << "Login successful!\n" << RESET; - admin_logged_in = isAdmin; + admin_logged_in = isAdmin; + + if (isAdmin) { + const char* countSQL = "SELECT COUNT(*) FROM complaints WHERE notified = 0;"; + int newComplaints = 0; + sqlite3_exec(db, countSQL, [](void* data, int argc, char** argv, char**) -> int { + *(int*)data = atoi(argv[0]); + return 0; + }, &newComplaints, &errMsg); + + if (newComplaints > 0) { + cout << YELLOW << "You have " << newComplaints << " new complaint(s)!\n" << RESET; + + const char* updateSQL = "UPDATE complaints SET notified = 1 WHERE notified = 0;"; + sqlite3_exec(db, updateSQL, 0, 0, &errMsg); + } else { + cout << GREEN << "No new complaints since your last login.\n" << RESET; + } + } + return true; } else { cout << RED << "Invalid credentials!\n" << RESET; From e6f8fcf9459eaa58221e41595a93cb51c0b28771 Mon Sep 17 00:00:00 2001 From: Piyush Aditya Kar <74527230+HilariousSoupXD@users.noreply.github.com> Date: Fri, 11 Apr 2025 22:55:47 +0530 Subject: [PATCH 7/8] Added tracking of who filed what complaint --- ComplaintBox.cpp | 22 ++++++++++++++++------ complaints_export.csv | 8 ++++++-- globals.h | 8 ++++++++ main.cpp | 2 ++ 4 files changed, 32 insertions(+), 8 deletions(-) create mode 100644 globals.h diff --git a/ComplaintBox.cpp b/ComplaintBox.cpp index 34bdb50..e98810f 100644 --- a/ComplaintBox.cpp +++ b/ComplaintBox.cpp @@ -5,6 +5,10 @@ #include #include #include +#include "globals.h" + + +std::string logged_in_username = "random"; using namespace std; @@ -127,6 +131,7 @@ bool ComplaintBox::loginUser(bool isAdmin) { if (success) { cout << GREEN << "Login successful!\n" << RESET; admin_logged_in = isAdmin; + logged_in_username = uname; if (isAdmin) { const char* countSQL = "SELECT COUNT(*) FROM complaints WHERE notified = 0;"; @@ -164,18 +169,21 @@ void ComplaintBox::fileComplaint() { cout << YELLOW << "Enter complaint message: " << RESET; getline(cin, message); - string sql = "INSERT INTO complaints (category, subCategory, message, status) VALUES ('" - + category + "', '" + subCategory + "', '" + message + "', 'Pending');"; + string filedBy = logged_in_username.empty() ? "random" : logged_in_username; + + string sql = "INSERT INTO complaints (category, subCategory, message, status, filed_by) VALUES ('" + + category + "', '" + subCategory + "', '" + message + "', 'Pending', '" + filedBy + "');"; if (sqlite3_exec(db, sql.c_str(), 0, 0, &errMsg) != SQLITE_OK) { cout << RED << "Error: " << errMsg << RESET << endl; sqlite3_free(errMsg); } else { - cout << BOLDGREEN << "Complaint filed successfully with status 'Pending'!\n" << RESET; + cout << BOLDGREEN << "Complaint filed successfully by '" << filedBy << "' with status 'Pending'!\n" << RESET; } } + void ComplaintBox::exportComplaintsToCSV() { ofstream file("complaints_export.csv"); if (!file.is_open()) { @@ -183,8 +191,9 @@ void ComplaintBox::exportComplaintsToCSV() { return; } - file << "complaint_id,category,subCategory,message,status,timestamp\n"; // Include timestamp in header - string sql = "SELECT complaint_id, category, subCategory, message, status, timestamp FROM complaints;"; // Include timestamp + file << "complaint_id,filed_by,category,subCategory,message,status,timestamp\n"; + + string sql = "SELECT complaint_id, filed_by, category, subCategory, message, status, timestamp FROM complaints;"; // Updated SQL auto callback = [](void *data, int argc, char **argv, char **colName) -> int { ofstream *f = static_cast(data); @@ -198,12 +207,13 @@ void ComplaintBox::exportComplaintsToCSV() { cout << RED << "Export failed: " << errMsg << RESET << endl; sqlite3_free(errMsg); } else { - cout << BOLDGREEN << "Complaints exported to 'complaints_export.csv' with timestamp!\n" << RESET; + cout << BOLDGREEN << "Complaints exported to 'complaints_export.csv' with filed_by and timestamp!\n" << RESET; } file.close(); } + void ComplaintBox::searchComplaints() { string keyword; cout << YELLOW << "Enter keyword to search for: " << RESET; diff --git a/complaints_export.csv b/complaints_export.csv index 20d4075..9106c52 100644 --- a/complaints_export.csv +++ b/complaints_export.csv @@ -1,2 +1,6 @@ -complaint_id,category,subCategory,message,status,timestamp -1,College,Fests,Admin chor mc,Pending,2025-04-11 14:43:14 +complaint_id,filed_by,category,subCategory,message,status,timestamp +1,random,College,Fests,Admin chor mc,Pending,2025-04-11 14:43:14 +2,random,College,Infrastructure,Add AC in class,Pending,2025-04-11 16:46:37 +3,Kartik,College,Faculty,B Nath,Pending,2025-04-11 17:19:58 +4,XD,Admin,Admin,Salary nahi milti sed,Pending,2025-04-11 17:21:05 +5,random,College,Gymkhana,Why,Pending,2025-04-11 17:21:58 diff --git a/globals.h b/globals.h new file mode 100644 index 0000000..aba3eb6 --- /dev/null +++ b/globals.h @@ -0,0 +1,8 @@ +#ifndef GLOBALS_H +#define GLOBALS_H + +#include + +extern std::string logged_in_username; + +#endif diff --git a/main.cpp b/main.cpp index 5963d2a..92722ec 100644 --- a/main.cpp +++ b/main.cpp @@ -2,6 +2,8 @@ #include #include "ComplaintBox.h" +#include "globals.h" + using namespace std; int main() { From 429f9c04fff167428bb682df276301a4be39c791 Mon Sep 17 00:00:00 2001 From: Piyush Aditya Kar <74527230+HilariousSoupXD@users.noreply.github.com> Date: Fri, 11 Apr 2025 23:09:41 +0530 Subject: [PATCH 8/8] Added a simple clause to restrict export access. --- ComplaintBox.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/ComplaintBox.cpp b/ComplaintBox.cpp index e98810f..1476c8e 100644 --- a/ComplaintBox.cpp +++ b/ComplaintBox.cpp @@ -185,15 +185,20 @@ void ComplaintBox::fileComplaint() { void ComplaintBox::exportComplaintsToCSV() { + if (!admin_logged_in) { + cout << RED << "Only admins are allowed to export complaints.\n" << RESET; + return; + } + ofstream file("complaints_export.csv"); if (!file.is_open()) { cout << RED << "Failed to create CSV file.\n" << RESET; return; } - file << "complaint_id,filed_by,category,subCategory,message,status,timestamp\n"; + file << "complaint_id,filed_by,category,subCategory,message,status,timestamp\n"; - string sql = "SELECT complaint_id, filed_by, category, subCategory, message, status, timestamp FROM complaints;"; // Updated SQL + string sql = "SELECT complaint_id, filed_by, category, subCategory, message, status, timestamp FROM complaints;"; auto callback = [](void *data, int argc, char **argv, char **colName) -> int { ofstream *f = static_cast(data); @@ -207,13 +212,14 @@ void ComplaintBox::exportComplaintsToCSV() { cout << RED << "Export failed: " << errMsg << RESET << endl; sqlite3_free(errMsg); } else { - cout << BOLDGREEN << "Complaints exported to 'complaints_export.csv' with filed_by and timestamp!\n" << RESET; + cout << BOLDGREEN << "Complaints exported to 'complaints_export.csv'\n" << RESET; } file.close(); } + void ComplaintBox::searchComplaints() { string keyword; cout << YELLOW << "Enter keyword to search for: " << RESET;