#include #include #include #include #include #include using namespace std; struct Note { string title; string content; string type; string deadlineDate; bool done; }; void displayMenu(); void addNewNote(vector ¬es); void listNotes(const vector ¬es); void editNote(vector ¬es); void markNoteAsDone(vector ¬es); void deleteNote(vector ¬es); void saveNotes(const vector ¬es); void loadNotes(vector ¬es); bool isTitleUnique(const vector ¬es, const string &title); bool isValidType(const string &type); bool isValidDate(const string &deadlineDate); bool isFileEmpty(const string &filename); void writeHeader(ofstream &outFile); int main() { vector notes; loadNotes(notes); int choice; do { displayMenu(); cout << "Enter your choice: "; cin >> choice; switch (choice) { case 1: addNewNote(notes); break; case 2: listNotes(notes); break; case 3: editNote(notes); break; case 4: markNoteAsDone(notes); break; case 5: deleteNote(notes); break; case 0: saveNotes(notes); cout << "Exiting the program. Goodbye!" << endl; break; default: cout << "Invalid choice. Please try again." << endl; } } while (choice != 0); return 0; } void displayMenu() { cout << "*********MAIN MENU**********" << endl; cout << "(1) Add new note" << endl; cout << "(2) List notes" << endl; cout << "(3) Edit note" << endl; cout << "(4) Mark note as done" << endl; cout << "(5) Delete note" << endl; cout << "(0) Exit" << endl; cout << "****************************" << endl; } void addNewNote(vector ¬es) { // ignore inputan sebelumnya Note newNote; cin.ignore(); // lakukan perulangan do { //lakukan terus menerus // tampilakan cout berikut cout << "Enter title (must be unique and without spaces): "; // ambil inputan dan jadikan inputan menjadi title getline(cin, newNote.title); //sampai while ini terpenuhi } while (!isTitleUnique(notes, newNote.title) || newNote.title.find(' ') != string::npos); cout << "Enter content: "; getline(cin, newNote.content); do { cout << "Enter type (important/not_important): "; cin >> newNote.type; } while (!isValidType(newNote.type)); do { cout << "Enter date (YYYY-MM-DD): "; cin >> newNote.deadlineDate; } while (!isValidDate(newNote.deadlineDate)); newNote.done = false; notes.push_back(newNote); saveNotes(notes); cout << "Note added successfully!" << endl; } void listNotes(const vector ¬es) { if (notes.empty()) { cout << "No notes available." << endl; } else { cout << "*********LIST OF NOTES**********" << endl; for (const auto ¬e : notes) { cout << "Title: " << note.title << endl; cout << "Content: " << note.content << endl; cout << "Type: " << note.type << endl; cout << "Deadline Date: " << note.deadlineDate << endl; cout << "Status: " << (note.done ? "Done" : "Not Done") << endl; cout << "-------------------------------" << endl; } cout << "*********************************" << endl; } } void editNote(vector ¬es) { cin.ignore(); cout << "Enter the title of the note you want to edit: "; string searchTitle; getline(cin, searchTitle); bool found = false; for (auto ¬e : notes) { if (note.title == searchTitle) { do { cout << "Enter new title (must be unique and without spaces): "; getline(cin, searchTitle); } while (!isTitleUnique(notes, searchTitle) || searchTitle.find(' ') != string::npos); note.title = searchTitle; cout << "Enter new content: "; getline(cin, note.content); do { cout << "Enter new type (important/not_important): "; cin >> note.type; } while (!isValidType(note.type)); do { cout << "Enter new date (YYYY-MM-DD): "; cin >> note.deadlineDate; } while (!isValidDate(note.deadlineDate)); cout << "Note edited successfully!" << endl; found = true; saveNotes(notes); break; } } if (!found) { cout << "Note with title '" << searchTitle << "' not found." << endl; } } void markNoteAsDone(vector ¬es) { cin.ignore(); cout << "Enter the title of the note you want to mark as done: "; string searchTitle; getline(cin, searchTitle); bool found = false; for (auto ¬e : notes) { if (note.title == searchTitle) { note.done = true; cout << "Note marked as done!" << endl; found = true; saveNotes(notes); break; } } if (!found) { cout << "Note with title '" << searchTitle << "' not found." << endl; } } struct NoteWithTitle { string searchTitle; NoteWithTitle(const string &title) : searchTitle(title) {} bool operator()(const Note ¬e) const { return note.title == searchTitle; } }; void deleteNote(vector ¬es) { cin.ignore(); cout << "Enter the title of the note you want to delete: "; string searchTitle; getline(cin, searchTitle); NoteWithTitle noteWithTitle(searchTitle); auto it = remove_if(notes.begin(), notes.end(), noteWithTitle); if (it != notes.end()) { notes.erase(it, notes.end()); cout << "Note deleted successfully!" << endl; saveNotes(notes); } else { cout << "Note with title '" << searchTitle << "' not found." << endl; } } void saveNotes(const vector ¬es) { ofstream outFile("notes.csv"); if (outFile.is_open()) { if (isFileEmpty("notes.csv")) { cout << "is emtpy" << endl; writeHeader(outFile); }else{ cout << "is npt emtpy" << endl; } for (const auto ¬e : notes) { outFile << note.title << "," << note.content << "," << note.type << "," << note.deadlineDate << "," << note.done << endl; } outFile.close(); cout << "Notes saved to file." << endl; } else { cerr << "Unable to open file for saving notes." << endl; } } bool isFileEmpty(const string &filename) { ifstream file(filename); return file.peek() == ifstream::traits_type::eof(); } void writeHeader(ofstream &outFile) { outFile << "title,content,type,deadline_date,done" << endl; } void loadNotes(vector ¬es) { ifstream inFile("notes.csv"); if (inFile.is_open()) { Note temp; while (getline(inFile, temp.title, ',')) { getline(inFile, temp.content, ','); getline(inFile, temp.type, ','); getline(inFile, temp.deadlineDate, ','); string done; getline(inFile, done); temp.done = (done == "1"); notes.push_back(temp); } inFile.close(); cout << "Notes loaded from file." << endl; } else { cout << "No existing notes file found. Creating a new one." << endl; } } bool isTitleUnique(const vector ¬es, const string &title) { string lowerTitle = title; transform(lowerTitle.begin(), lowerTitle.end(), lowerTitle.begin(), ::tolower); for (const auto ¬e : notes) { string lowerNoteTitle = note.title; transform(lowerNoteTitle.begin(), lowerNoteTitle.end(), lowerNoteTitle.begin(), ::tolower); if (lowerNoteTitle == lowerTitle) { cout << "Title '" << title << "' already exists. Please enter a different title." << endl; return false; } } return true; } bool isValidType(const string &type) { string lowercaseType = type; transform(lowercaseType.begin(), lowercaseType.end(), lowercaseType.begin(), ::tolower); if (lowercaseType == "important" || lowercaseType == "not_important") { return true; } else { cout << "Invalid type. Please enter 'important' or 'not_important'." << endl; return false; } } bool isValidDate(const string &deadlineDate) { if (deadlineDate.length() != 10) { cout << "Invalid date format. Please enter the date in the format YYYY-MM-DD." << endl; return false; } try { int year = stoi(deadlineDate.substr(0, 4)); int month = stoi(deadlineDate.substr(5, 2)); int day = stoi(deadlineDate.substr(8, 2)); if (year < 1000 || year > 9999 || month < 1 || month > 12 || day < 1 || day > 31) { cout << "Invalid date. Please enter a valid date." << endl; return false; } if ((month == 4 || month == 6 || month == 9 || month == 11) && day > 30) { cout << "Invalid date. Month " << month << " has 30 days or less." << endl; return false; } if (month == 2) { bool isLeapYear = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)); if ((isLeapYear && day > 29) || (!isLeapYear && day > 28)) { cout << "Invalid date. February in year " << year << " has " << (isLeapYear ? "29" : "28") << " days." << endl; return false; } } return true; } catch (const invalid_argument &) { cout << "Invalid date format. Please enter the date in the format YYYY-MM-DD." << endl; return false; } }