{"id":19543261,"url":"https://github.com/codewithalamin/interactive-comments-section","last_synced_at":"2025-07-30T07:04:25.181Z","repository":{"id":185052560,"uuid":"661253552","full_name":"CodeWithAlamin/Interactive-comments-section","owner":"CodeWithAlamin","description":"Nested comment section with Vanilla JS, utilizing MVC \u0026 Pub-Sub patterns. Ideal for practicing full-stack CRUD apps!","archived":false,"fork":false,"pushed_at":"2024-10-30T13:53:21.000Z","size":1231,"stargazers_count":12,"open_issues_count":0,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-26T17:47:19.513Z","etag":null,"topics":["codepapa360","codewithalamin","comment-section","crud","crud-application","crud-functionality","css","frontend","frontend-development","frontend-mentor","html","javascript","nested-comments","nested-structures","sass"],"latest_commit_sha":null,"homepage":"https://interactive-comments-section-alamin.vercel.app","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/CodeWithAlamin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-07-02T09:15:30.000Z","updated_at":"2025-03-22T03:53:53.000Z","dependencies_parsed_at":null,"dependency_job_id":"32dba994-d272-4583-a7e0-740cca50d58a","html_url":"https://github.com/CodeWithAlamin/Interactive-comments-section","commit_stats":null,"previous_names":["codepapa360/interactive-comments-section","codewithalamin/interactive-comments-section"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/CodeWithAlamin/Interactive-comments-section","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CodeWithAlamin%2FInteractive-comments-section","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CodeWithAlamin%2FInteractive-comments-section/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CodeWithAlamin%2FInteractive-comments-section/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CodeWithAlamin%2FInteractive-comments-section/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CodeWithAlamin","download_url":"https://codeload.github.com/CodeWithAlamin/Interactive-comments-section/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CodeWithAlamin%2FInteractive-comments-section/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267827337,"owners_count":24150345,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-30T02:00:09.044Z","response_time":70,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["codepapa360","codewithalamin","comment-section","crud","crud-application","crud-functionality","css","frontend","frontend-development","frontend-mentor","html","javascript","nested-comments","nested-structures","sass"],"created_at":"2024-11-11T03:18:08.822Z","updated_at":"2025-07-30T07:04:25.141Z","avatar_url":"https://github.com/CodeWithAlamin.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003eInteractive comments section\u003c/h1\u003e\n\u003cdiv align=\"center\"\u003e\n\nChallenge from [Frontend Mentor](https://www.frontendmentor.io/challenges)\n\n\u003ch2\u003e\n\n[🚀Live Site](https://interactive-comments-section-alamin.vercel.app/)\n||\n[💡Frontend Mentor](https://www.frontendmentor.io/solutions/nested-comment-section-built-with-vanilla-js-mvc-and-pubsub-pattern-C4fL2vWc_l)\n\n\u003c/h2\u003e\n\u003c/div\u003e\n\n\u003c!-- Badges --\u003e\n\u003cdiv align=\"center\"\u003e\n\n\u003cimg src=\"https://img.shields.io/badge/Status-Completed-success?style=flat\" alt=\"Status\" /\u003e\n\n\u003c!-- Liceensee --\u003e\n\u003cimg src=\"https://img.shields.io/badge/License-MIT-blue?style=flat\" alt=\"License\" /\u003e\n\n\u003c/div\u003e\n\n\u003cp align=\"center\"\u003e\nThis is a web application that showcases an interactive comments section. Users can add new comments, reply to existing comments, edit their own comments, and vote on comments. The project follows the \u003ccode\u003eModel-View-Controller (MVC)\u003c/code\u003e architectural pattern to separate data, presentation, and user interaction. Additionally, the \u003ccode\u003ePublisher-Subscriber\u003c/code\u003e pattern is utilized for event handling, enhancing the modularity and maintainability of the codebase.\n\u003c/p\u003e\n\n\u003c!-- Screenshot --\u003e\n\u003ca align=\"center\" href=\"https://interactive-comments-section-alamin.vercel.app/\"\u003e\n\n![Screenshot](./screenshots/Interactive-comments-section-preview-CodeWithAlamin.png)\n\n\u003c/a\u003e\n\n## Technologies Used\n\n- Vanilla JavaScript: The core language used for application logic and event handling.\n- SASS: Used for styling and layout.\n- HTML\n\n## Project Structure\n\nThe project follows the MVC pattern to organize the code into three main components:\n\n1. **Model (model.js):**\n\n   - Handles data management and storage.\n   - Provides methods for storing, retrieving, and updating comments.\n   - Implements voting functionality for comments.\n   - Manages the current user data and vote history.\n\n```javascript\nexport const storeComment = async function (repliedToId, comment, parentId) {\n  // ... code for storing a new comment or reply ...\n};\n\nexport const deleteComment = function (parentId, mainId) {\n  // ... code for deleting a comment or reply ...\n};\n\n// ... other model functions ...\n```\n\n2. **View (commentView.js, deleteModalView.js, editView.js, newCommentView.js, replyView.js, scoreView.js):**\n\n   - Responsible for the presentation and rendering of data to the DOM.\n   - Utilizes the generated HTML markup templates to display comments and other elements.\n   - Implements methods to render main comments, replied comments, edit fields, delete modals, and reply fields.\n\n```javascript\nclass CommentView {\n  renderMainComment(data) {\n    // ... code for rendering the main comment to the DOM ...\n  }\n\n  renderRepliedComment(data) {\n    // ... code for rendering a replied comment to the DOM ...\n  }\n\n  // ... other rendering methods ...\n}\n```\n\n3. **Controller (controller.js):**\n   - Acts as the middleman between the Model and View components.\n   - Implements event listeners using the `Publisher-Subscriber` pattern to handle user interactions.\n   - Connects user actions to corresponding Model methods for data manipulation.\n   - Utilizes View methods to display updated data to the user.\n\n```javascript\nconst controlNewComment = async function () {\n  // ... code for handling the addition of a new comment ...\n};\n\nconst controlReplyComment = async function (repliedToId, comment, parentId) {\n  // ... code for handling the addition of a reply to a comment ...\n};\n\n// ... other control functions ...\n```\n\n### Publisher-Subscriber (Pub-Sub) pattern:\n\nThe Pub-Sub pattern is a design pattern where multiple components `(subscribers)` subscribe to `events` published by a central component `(publisher)`. Subscribers are notified whenever a relevant `event` occurs.\n\n```javascript\n// Example from controller.js\nconst init = function () {\n  editView.addHandlerEditBtn(controlEditComment);\n  scoreView.addHandlerVoting(controlVoting);\n  replyView.addHandlerReplyBtn(controlReplyComment);\n};\n\ninit();\n```\n\n## Key Features\n\nUsers should be able to:\n\n- Create, Read, Update, and Delete comments and replies.\n- Upvote and downvote comments.\n- **Bonus**: Utilized `localStorage` to save the current state in the browser and persist when the browser is refreshed.\n- **Bonus**: Instead of using the `createdAt` strings from the `data.json` file, I have used timestamps and dynamically track the time since the comment or reply was posted.\n- **Bonus**: Dark mode toggler.\n\n## What I Learned:\n\nThe MVC pattern helped me organize my code and separate different parts of the application. It made it easier to manage data, handle user interactions, and update the user interface without making everything messy. The Model represents the data and project logic, the View is responsible for the user interface, and the Controller acts as the middleman between the Model and View.\n\nOn the other hand, the Pub-Sub method provided a way for different parts of the application to communicate with each other without knowing each other's details. It's like having a bunch of people (subscribers) listening for updates from a central place (publisher). When something changes, the publisher notifies all the subscribers, and they can react accordingly.\n\nBy using these patterns, I was able to create a more organized and maintainable application. It also helped me handle user interactions and update the comments section dynamically without reloading the page. I learned how to manage data efficiently, display it on the screen, and handle user interactions smoothly.\n\nThis project built upon my previous experience with the [Forkify](https://github.com/CodeWithAlamin/Forkify-Recipe-App) app, where I first encountered these patterns. Through practice and application, I gained more confidence in using these patterns effectively and understanding their benefits in real-world projects.\n\nOverall, it was a great learning experience, and I'm excited to use these skills in future projects to create even better and more user-friendly web applications.\n\n## Author\n\n\u003cb\u003e👤 Alamin\u003c/b\u003e\n\n- Twitter - [@CodeWithAlamin](https://www.twitter.com/CodeWithAlamin)\n- LinkedIn - [@CodeWithAlamin](https://www.linkedin.com/in/CodeWithAlamin)\n- Frontend Mentor - [@CodeWithAlamin](https://www.frontendmentor.io/profile/CodeWithAlamin)\n- Github: [@CodeWithAlamin](https://github.com/CodeWithAlamin)\n\nFeel free to contact me with any questions or feedback!\n\n## Acknowledgments\n\nThis project was inspired by the \"Interactive Comments Section\" challenge from Frontend Mentor. Special thanks to Frontend Mentor for providing the design and specifications for this project.\n\n## License\n\nThis project is licensed under the [MIT](https://github.com/CodeWithAlamin/Interactive-comments-section/blob/main/LICENSE.md) License - see the LICENSE file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodewithalamin%2Finteractive-comments-section","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcodewithalamin%2Finteractive-comments-section","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodewithalamin%2Finteractive-comments-section/lists"}