{"id":28519821,"url":"https://github.com/estebanrfp/dcms","last_synced_at":"2025-07-05T13:32:08.405Z","repository":{"id":297253898,"uuid":"996199237","full_name":"estebanrfp/dCMS","owner":"estebanrfp","description":"Distributed P2P CMS Example - GraphDB (GDB)","archived":false,"fork":false,"pushed_at":"2025-06-04T16:32:05.000Z","size":16,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-06-04T21:48:22.788Z","etag":null,"topics":["cms","distributed","gdb","graphdb","nostr","p2p"],"latest_commit_sha":null,"homepage":"https://estebanrfp.github.io/dCMS/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/estebanrfp.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2025-06-04T15:44:19.000Z","updated_at":"2025-06-04T16:32:07.000Z","dependencies_parsed_at":"2025-06-04T21:48:27.245Z","dependency_job_id":null,"html_url":"https://github.com/estebanrfp/dCMS","commit_stats":null,"previous_names":["estebanrfp/dcms"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/estebanrfp%2FdCMS","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/estebanrfp%2FdCMS/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/estebanrfp%2FdCMS/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/estebanrfp%2FdCMS/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/estebanrfp","download_url":"https://codeload.github.com/estebanrfp/dCMS/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/estebanrfp%2FdCMS/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":258832598,"owners_count":22764909,"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","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":["cms","distributed","gdb","graphdb","nostr","p2p"],"created_at":"2025-06-09T06:30:35.853Z","updated_at":"2025-07-05T13:32:08.400Z","avatar_url":"https://github.com/estebanrfp.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Distributed P2P CMS Example - GraphDB (GDB)\n\n![dVoting App Screenshot](https://media.licdn.com/dms/image/v2/C4E22AQF8hH6r8AnF5w/feedshare-shrink_800/feedshare-shrink_800/0/1644574363392?e=2147483647\u0026v=beta\u0026t=EvaCR-whYo4jTQ0HmYXeVGlMOKxdkJ4pV-s2gxkbsCQ) \u003c!-- Replace placeholder.png with an actual screenshot --\u003e\n\nThis project is a frontend prototype for a **Distributed Peer-to-Peer (P2P) Content Management System (dCMS)**. It demonstrates the user interface and client-side functionalities for creating, viewing, and managing content.\n\nThe dCMS is designed to operate on a decentralized P2P network, using a Graph Database (GDB) for data storage and real-time synchronization. The target backend library for achieving this is **`gdb-p2p`**, a minimalist Graph Database with P2P support. This README describes the frontend application and how it's intended to integrate with the `gdb-p2p` API.\n\n## Core dCMS Frontend Features\n\nThis frontend, built with HTML, CSS, and JavaScript (`app.js`), provides the following user experiences:\n\n*   **Post Listing (Grid View):** Displays all posts in a responsive image grid.\n*   **Individual Post View:**\n    *   Shows full post details: title, metadata (author, date - conceptual), image, and content.\n    *   Renders Markdown content into HTML using Showdown.js.\n*   **Post Creation \u0026 Editing:**\n    *   A comprehensive form for creating new posts or editing existing ones.\n    *   Fields include: Title, Slug (auto-generated from title, read-only), Short Description, Tags, Image URL, Status (Draft/Published), and Markdown Content.\n    *   **Live Markdown Preview:** Real-time feedback on how Markdown content will render.\n    *   **Word Count:** Dynamically updates for the Markdown content.\n*   **Post Deletion:** Functionality to remove posts (accessible from the editor).\n*   **Intuitive Navigation:** Simple menu to switch between viewing all posts and creating a new post.\n*   **Responsive Design:** Adapts to various screen sizes.\n*   **Latest Posts Footer:** Displays a list of recently updated posts.\n\n## Intended Architecture with `gdb-p2p`\n\nThe true power of this dCMS will be realized when `app.js` is integrated with the `gdb-p2p` library. Here's how the frontend functionalities are designed to map to `gdb-p2p` operations:\n\n1.  **Initialization:**\n    *   Upon loading, `app.js` would initialize a `gdb-p2p` instance:\n        ```javascript\n        // In app.js\n        // import { GraphDB } from \"https://cdn.jsdelivr.net/npm/gdb-p2p/+esm\"; // Or from npm\n        const db = new GraphDB(\"dcms-main-database\", { password: \"user-chosen-password\" /* optional */ });\n        ```\n\n2.  **Displaying Posts (Grid View \u0026 Latest Posts Footer):**\n    *   The main post grid and the \"Últimos Posts Actualizados\" footer would be populated using `db.map()`.\n    *   This allows for fetching posts with specific criteria (e.g., `status: 'published'`) and sorting (e.g., by modification date).\n    *   Crucially, `db.map()`'s real-time callback (`({ id, value, action }) =\u003e { ... }`) would enable the UI to update automatically when posts are added, modified, or removed by any peer in the network.\n        ```javascript\n        // Example: Fetching published posts for the grid, sorted by creation time\n        const { unsubscribe: unsubscribeGrid } = await db.map(\n          { query: { type: \"post\", status: \"published\" }, field: \"createdAt\", order: \"desc\", realtime: true },\n          handlePostUpdateForGrid // A function in app.js to update the DOM\n        );\n        ```\n\n3.  **Viewing an Individual Post:**\n    *   When a user clicks on a post, `app.js` would use `db.get(postId)` to retrieve the specific post's data.\n        ```javascript\n        const { result } = await db.get(selectedPostId);\n        if (result) {\n          displayPostDetails(result.value); // result.value contains the post object\n        }\n        ```\n\n4.  **Creating/Editing Posts:**\n    *   The \"Nuevo Post\" / \"Editar Post\" form submission would trigger `db.put(postData, postId?)`.\n    *   For new posts, `db.put(postData)` creates a new node and returns its ID.\n    *   For existing posts, `db.put(updatedPostData, existingPostId)` updates the node.\n    *   Post data would include fields like `title`, `content`, `imageUrl`, `tags`, `status`, `createdAt`, `updatedAt`.\n        ```javascript\n        // Example: Saving a new post\n        const newPost = { type: \"post\", title: \"...\", content: \"...\", status: \"draft\", createdAt: new Date().toISOString(), updatedAt: new Date().toISOString() };\n        const newPostId = await db.put(newPost);\n        ```\n\n5.  **Deleting Posts:**\n    *   The \"Eliminar Post\" button would call `db.remove(postId)`.\n        ```javascript\n        await db.remove(postIdToDelete);\n        ```\n\n6.  **Tags \u0026 Relationships (Advanced Usage):**\n    *   While tags can be stored as an array within the post object, a more robust graph approach would be to create separate nodes for tags and link them to posts using `db.link(postId, tagId, \"has_tag\")`. This allows for more powerful querying based on tag relationships.\n\n7.  **P2P Collaboration Aspects:**\n    *   `db.room.onPeerJoin` / `onPeerLeave` could be used to show active collaborators.\n    *   `db.room.makeAction` could enable advanced features like synchronized cursors for multi-user editing of a post in the future.\n\n## Tech Stack (Frontend)\n\n*   **HTML5:** Semantic structure.\n*   **CSS3:** Custom styling (`styles.css`).\n*   **JavaScript (ES6+ Modules):** Application logic, DOM manipulation, and intended `gdb-p2p` integration (`app.js`).\n*   **Showdown.js:** For client-side Markdown to HTML conversion (post content and live preview).\n\n## Getting Started (Frontend Prototype)\n\n### Prerequisites\n\n*   A modern web browser.\n*   (Optional) A local web server for development (recommended for ES6 modules).\n\n### Running the Frontend Prototype\n\n1.  **Clone the repository:**\n    ```bash\n    git clone \u003crepository-url\u003e\n    cd \u003crepository-name\u003e\n    ```\n2.  **Open `index.html`:**\n    *   Directly in your browser: `file:///path/to/your/clone/index.html`\n    *   Or using a local server (e.g., with Python):\n        ```bash\n        python -m http.server\n        ```\n        Then navigate to `http://localhost:8000`.\n\n**Note:** This runs the frontend UI only. Data operations are currently simulated in `app.js` (e.g., using `localStorage` or in-memory arrays). Full P2P functionality requires integrating `gdb-p2p`.\n\n## Project Structure\n\n```\n/\n├── index.html        # Main HTML structure of the dCMS\n├── styles.css        # CSS styles\n├── app.js            # Core JavaScript logic (to be integrated with gdb-p2p)\n└── README.md         # This file\n```\n\n## Future Development: Full `gdb-p2p` Integration\n\nThe primary next step for this project is to fully integrate `app.js` with the `gdb-p2p` library:\n\n*   **Initialize `GraphDB`** on application start.\n*   **Replace mock data handling** in `app.js` with `db.put()`, `db.get()`, `db.map()`, and `db.remove()` calls.\n*   Implement **real-time UI updates** using the callback mechanism of `db.map()`.\n*   Manage **post slugs**, ensuring uniqueness (potentially a check before `db.put()`).\n*   Refine **data models** for posts, considering timestamps (using `gdb-p2p`'s HLCs automatically handled by `get` and `map` callbacks), authors, and tags.\n*   Explore using `db.link()` for richer relationships (e.g., post-to-author, post-to-tag).\n*   Implement **encryption** using the `password` option in `new GraphDB()` if secure storage is desired.\n\n## Contributing\n\nContributions are welcome, especially those focused on the `gdb-p2p` integration and enhancing the P2P capabilities of the CMS.\n1.  Fork the repository.\n2.  Create a feature branch.\n3.  Commit your changes.\n4.  Push to the branch.\n5.  Open a Pull Request.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Festebanrfp%2Fdcms","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Festebanrfp%2Fdcms","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Festebanrfp%2Fdcms/lists"}