{"id":32892284,"url":"https://github.com/elenaches/ionic-react-journaling-app","last_synced_at":"2026-04-08T23:34:02.574Z","repository":{"id":323216287,"uuid":"1092519202","full_name":"ElenaChes/ionic-react-journaling-app","owner":"ElenaChes","description":"A mobile journaling app built with Ionic (React) and a Node.js/Express backend using MongoDB. Stitched supports tracking daily tasks, notes, and events/episodes, with built-in history look-up and statistics.","archived":false,"fork":false,"pushed_at":"2025-11-08T19:35:44.000Z","size":2953,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-11-08T21:12:05.374Z","etag":null,"topics":["capacitor","express-api","expressjs","full-stack","fullstack","ionic","ionic-app","ionic-capacitor","ionic-framework","ionic-react","journaling-app","mobile-app","mongodb","nodejs","prototype","react","rest-api"],"latest_commit_sha":null,"homepage":"","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/ElenaChes.png","metadata":{"files":{"readme":"docs/README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-11-08T19:21:50.000Z","updated_at":"2025-11-08T19:36:59.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ElenaChes/ionic-react-journaling-app","commit_stats":null,"previous_names":["elenaches/ionic-react-journaling-app"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/ElenaChes/ionic-react-journaling-app","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ElenaChes%2Fionic-react-journaling-app","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ElenaChes%2Fionic-react-journaling-app/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ElenaChes%2Fionic-react-journaling-app/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ElenaChes%2Fionic-react-journaling-app/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ElenaChes","download_url":"https://codeload.github.com/ElenaChes/ionic-react-journaling-app/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ElenaChes%2Fionic-react-journaling-app/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":283625008,"owners_count":26866771,"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-11-10T02:00:06.292Z","response_time":53,"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":["capacitor","express-api","expressjs","full-stack","fullstack","ionic","ionic-app","ionic-capacitor","ionic-framework","ionic-react","journaling-app","mobile-app","mongodb","nodejs","prototype","react","rest-api"],"created_at":"2025-11-10T05:01:06.584Z","updated_at":"2026-04-08T23:34:02.567Z","avatar_url":"https://github.com/ElenaChes.png","language":"JavaScript","readme":"# Stitched - Journaling App\n\n\u003cimg align=\"right\" style=\"width:150px; height:auto;\" src=\"/frontend/resources/splash.png\"\u003e\n\n\u003cp\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Ionic-grey?logo=ionic\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/React-grey?logo=react\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/TypeScript-grey?logo=typescript\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Capacitor-grey?logo=capacitor\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Node.js-grey?logo=node.js\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Express.js-grey?logo=express\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/MongoDB-grey?logo=mongodb\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/🔨-Prototype_App-grey?labelColor=lightgrey\"\u003e\n\u003c/p\u003e\n\nA mobile journaling app built with Ionic (React \u0026 TypeScript) and a Node.js/Express backend using MongoDB.\u003cbr\u003e\nStitched supports tracking recurring tasks (Moments), daily notes (Memories), and events/episodes (Mementos), with built-in history look-up and statistics.\n\n\u003e [!CAUTION]\n\u003e Development on this project is currently paused, and it isn't production-ready. See [Current Status \u0026 Limitations](#current-status--limitations) for details.\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ch3\u003eContent\u003c/h3\u003e\u003c/summary\u003e\n\n- [Concept](#concept)\n  - [Moment](#moment)\n  - [Memory](#memory)\n  - [Memento](#memento)\n- [Current Status \\\u0026 Limitations](#current-status--limitations)\n  - [Limited Frontend and Non-Dynamic UI](#limited-frontend-and-non-dynamic-ui)\n  - [Notifications](#notifications)\n  - [Debugging](#debugging)\n- [Project Structure](#project-structure)\n- [Dependencies](#dependencies)\n- [Database](#database)\n- [Installation](#installation)\n  - [Backend](#backend)\n  - [Frontend](#frontend)\n    - [Android](#android)\n    - [iOS](#ios)\n- [Usage](#usage)\n- [Future Plans](#future-plans)\n\n\u003c/details\u003e\n\u003chr\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003csub\u003eJournal Page\u003c/sub\u003e\u003cbr\u003e\n  \u003cimg style=\"width:250px; height:auto;\" src=\"https://github.com/user-attachments/assets/39fdbb08-b889-4fc0-a002-dbe7bc7c93c0\" /\u003e\n\u003c/p\u003e\n\n# Concept\n\nStitched has three types of data one can journal:\n\n## Moment\n\n\u003cdiv inline=\"float\" align=\"right\"\u003e\u003csub\u003eJournal - Moments Checklist\u003c/sub\u003e\u003c/div\u003e\n\u003cimg align=\"right\" style=\"width:150px; height:auto;\" src=\"https://github.com/user-attachments/assets/0e9c91ec-a025-4d9f-9ac1-eaef65544c55\" /\u003e\n\nRecurring tasks with flexible schedules.\n\nFor example, \"Lunch\" can be tracked as a **daily** task, or \"Laundry\" as a task to complete **twice per month**.\u003cbr\u003e\nEach moment is displayed differently based on its frequency and previous completions, indicating whether it is \u003cins\u003edue\u003c/ins\u003e, \u003cins\u003ecould be done\u003c/ins\u003e today, or \u003cins\u003enot due\u003c/ins\u003e.\n\nThe **History** tab displays when each task was completed, didn't need to be done, or was skipped, along with statistics such as completion percentage.\n\n\u003cp align=\"center\"\u003e\n  \u003csub\u003eHistory - \"Lunch\" Moment\u003c/sub\u003e\n  \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\n  \u003csub\u003eHistory - \"Laundry\" Moment\u003c/sub\u003e\n  \u003cbr\u003e\n  \u003cimg style=\"width:auto; height:500px;\" src=\"https://github.com/user-attachments/assets/80f9ca39-585c-4ec7-9d13-69b5cf3178dd\" /\u003e\n  \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\n  \u003cimg style=\"width:auto; height:500px;\" src=\"https://github.com/user-attachments/assets/ae5fea27-6dcc-4bd1-bf2f-352dc3df74f2\" /\u003e\n\u003c/p\u003e\n\n## Memory\n\n\u003cdiv inline=\"float\" align=\"right\"\u003e\u003csub\u003eJournal - Memories Notes\u003c/sub\u003e\u0026nbsp;\u0026nbsp;\u0026nbsp;\u003c/div\u003e\n\u003cimg align=\"right\" style=\"width:160px; height:auto;\" src=\"https://github.com/user-attachments/assets/97e098d8-fa57-4efd-811e-f588608f1b1d\" /\u003e\n\nDaily notes with custom titles.\n\nFor example, a \"Daily summary\" note can list the activities of the day, or an \"Ideas\" note can store more abstract thoughts.\n\n\u003e [!NOTE]\n\u003e Notes are rendered with small formatting conversions for readability:\n\u003e\n\u003e - `- List` -\u003e `• List`\n\u003e - `[ ] Empty checkbox` -\u003e `☐ Empty checkbox`\n\u003e - `[x] Checked checkbox` -\u003e `☒ Checked checkbox`\n\u003e - `This is complete V` -\u003e `This is complete ✓`\n\u003e - `This is complete X` -\u003e `This is complete ✗`\n\u003e - `---` -\u003e `⎯⎯⎯⎯⎯⎯⎯⎯⎯` (separator)\n\nThe **History** tab includes a search bar to quickly find past notes by \u003cins\u003ekeyword\u003c/ins\u003e.\n\n\u003cp align=\"center\"\u003e\n  \u003csub\u003eHistory - Memories with Keyword \"readme\"\u003c/sub\u003e\u003cbr\u003e\n  \u003cimg style=\"width:auto; height:400px;\" src=\"https://github.com/user-attachments/assets/9f0af58c-3d94-4ffd-ad71-079396e77f76\" /\u003e\n\u003c/p\u003e\n\n## Memento\n\n\u003cdiv inline=\"float\" align=\"right\"\u003e\u003csub\u003eMemento Modal - Editing \"Sick\" Memento\u003c/sub\u003e \u0026nbsp;\u003c/div\u003e\n\u003cimg align=\"right\" style=\"width:250px; height:auto;\" src=\"https://github.com/user-attachments/assets/5624fc2f-2b11-40f8-b216-b9f71aa2c50f\" /\u003e\n\nEpisodes or events.\n\nFor example, they can represent vacations, projects, being sick or having headaches. Virtually anything with a \u003cins\u003estart\u003c/ins\u003e and \u003cins\u003eend\u003c/ins\u003e date.\u003cbr\u003e\nMementos can also predict future occurrences, which is useful for tracking recurring events - such as planning vacations at regular intervals or anticipating recurring headaches. Works for tracking periods too.\u003cbr\u003e\nPredictions are displayed on the main calendar.\n\n\u003cp align=\"center\"\u003e\n  \u003csub\u003eJournal - Ongoing Mementos\u003c/sub\u003e\u003cbr\u003e\n  \u003cimg style=\"width:auto; height:120px;\" src=\"https://github.com/user-attachments/assets/aed3a5eb-751d-47f8-a248-77486b4ad92e\" /\u003e\n  \u003cbr\u003e\n  \u003csub\u003eJournal - Memento Prediction\u003c/sub\u003e\u003cbr\u003e\n  \u003cimg style=\"width:auto; height:120px;\" src=\"https://github.com/user-attachments/assets/615bacc3-623e-404f-b7b0-2589b948842e\" /\u003e\n\u003c/p\u003e\n\n\u003e [!NOTE]\n\u003e To add/edit a memento:\n\u003e\n\u003e 1. Tap `Add started`.\n\u003e 2. Select type from the list.\n\u003e 3. Select a `start` date.\n\u003e 4. Optionally, tap the `end` date slot to set the end date.\u003cbr\u003e\n\u003e    (_To remove the end date tap the selected date again_)\n\nThe **History** tab lists all past mementos, along with statistics such as average duration and intervals, either individually or grouped by category.\n\n\u003cp align=\"center\"\u003e\n  \u003csub\u003eHistory - \"Headache\" Memento\u003c/sub\u003e\n  \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\n  \u003csub\u003eHistory - \"Social\" Category\u003c/sub\u003e\n  \u0026nbsp; \u0026nbsp;\n  \u003cbr\u003e\n  \u003cimg style=\"width:auto; height:600px;\" src=\"https://github.com/user-attachments/assets/56ebcdd4-7d0f-4f8e-9584-53c168223356\" /\u003e\n    \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;\n  \u003cimg style=\"width:auto; height:600px;\" src=\"https://github.com/user-attachments/assets/f2558bb3-f4c6-4d21-b859-ed75bf338525\" /\u003e\n\u003c/p\u003e\n\n# Current Status \u0026 Limitations\n\nStitched is functional but currently it's in a paused development state. The following limitations apply to this prototype version.\n\n\u003e [!NOTE]\n\u003e It is not recommended to use this app's current state as is, but rather as inspiration for your own projects.\n\n## Limited Frontend and Non-Dynamic UI\n\nThe frontend lacks several features, such as the ability to adjust moment, memory, or memento settings directly within the UI. These options need to be be modified manually in the database.\n\nAdditionally, the layout was designed specifically for my Android device and will not display correctly on most screen sizes or platforms.\n\n## Notifications\n\nThe app is using Capacitor's `Local Notifications`, which are limited in functionality and did not meet the intended design for the app.\n\nUsing **non-simple** notifications (moment, memory, or memento) is unintuitive - when the app asks if a moment was complete, pressing `Yes` opens the app, loads the data, and then marks it as complete. Pressing `No` also opens the app. Ideally, neither action would open the app, but this isn't possible using `Local Notifications`.\n\n\u003e [!NOTE]\n\u003e This is the reason the \u003cins\u003esimple notifications\u003c/ins\u003e were implemented, sending generic notifications in set times regardless of what was complete or not complete during the day.\n\nThese limitations were a major reason why development on this version was paused and why a future rebuild is planned using `Push Notifications`, which would allow background actions and more advanced features.\n\n## Debugging\n\nThe app is currently in a \"testing\" state. Some features were never finalized, but they remain functional enough to explore the core concepts.\n\n- Multiple files have a `printLogs` boolean at the top, allowing to enable/disable debug logs for that file.\n- A race condition can occur during new entry creation. Although a queue system exists, entries can still be duplicated if multiple fields are updated too quickly on a new day, and some content may be lost.\n- Notifications sometimes fail to schedule on app start, requiring a manual refresh (although it's possibly an emulator only issue and won't happen on proper builds).\n\nThe `History` tab has a `Debug` subpage, allowing to copy the selected day's data to the clipboard and refreshing notifications manually. Both actions print debug information to the console.\n\n# Project Structure\n\nThe `frontend/src/` folder:\n\n- **components/** - The app's components:\n  - **calendar/** - A custom calendar hook \u0026 a calendar reset button.\n  - **history/** - The subpages displayed under the `History` tab:\n    - **debug/** - Debug subpage, allows copying the selected day's data and manually refreshing the notifications.\n    - **memento/** - Memento subpage components.\n    - **memory/** - Memory subpage components.\n    - **moment/** - Moment subpage components.\n    - **DebugPage.tsx** - Debug subpage.\n    - **EmptyCard.tsx** - Component used for empty blocks.\n    - **MementoHistory.tsx** - Memento history subpage.\n    - **MomentHistory.tsx** - Moment history subpage.\n    - **MemoryHistory.tsx** - Memory history subpage.\n  - **journal/** - The components displayed under the `Journal` tab:\n    - **Calendar.tsx** - The app's main calendar.\n    - **Mementos.tsx** - The mementos area at the bottom of the screen.\n    - **MemModal.tsx** - Memento adding/editing modal.\n    - **Memory.tsx** - The memory textbox blocks.\n    - **Moments.tsx** - Moments checkboxes list.\n  - **context/** - The app's context:\n    - **Context.jsx** - Main context provider, fetches data from the backend and initializes other contexts.\n    - **useEntries.jsx** - Keeps track of the selected entry (based on date), updates memories and moments in the database.\n    - **useExtendedMemento.jsx** - Extends memento data: calculates statistics, predicts end dates, and future occurrences.\n    - **useExtendedMoment.jsx** - Extends moment data: calculates `due`/`could do`/`not due` status based on frequency.\n    - **useMementosHistory.jsx** - Keeps track of the selected memento in the `History` tab and its data.\n    - **useMementos.jsx** - Keeps track of current mementos (based on date), updates mementos in the database.\n    - **useMemoryHistory.jsx** - Keeps track of the memory list in the `History` tab and their data.\n    - **useMomentHistory.jsx** - Keeps track of the selected moment in the `History` tab and its data.\n    - **utils.jsx** - Utility functions for the app.\n  - **pages/** - App's main pages:\n    - **History.tsx** - The `History` tab page.\n    - **Journal.tsx** - The `Journal` tab page.\n  - **theme/** - Color presets and custom css files.\n  - **App.tsx** - App main page and tab selection.\n  - **main.tsx** - The app's entry point.\n\n\u003e [!NOTE]\n\u003e Other folders and files were generated by Ionic.\n\nThe `backend/` folder:\n\n- **stitched/**\n  - **api.js** - The API endpoints.\n  - **database.js** - The database schemas and connection.\n- **index.js** - The app's entry point.\n- **Dockerfile** - For containerizing the backend - useful to host on a server. Can be deleted if not in use.\n\n\u003e [!NOTE]\n\u003e The backend is intentionally minimal, so it can be integrated into existing Express apps without requiring a separate deployment.\u003cbr\u003e\n\u003e To attach to an existing app, copy the `stitched/` folder and add the following lines to the existing app's main file:\n\u003e\n\u003e ```js\n\u003e //[Stitched backend]\n\u003e const { stitchedDB } = require(\"./stitched/database\");\n\u003e\n\u003e //[Routes]\n\u003e const stitchedRouter = require(\"./stitched/api\");\n\u003e app.use(\"/api\", stitchedRouter);\n\u003e ```\n\n# Dependencies\n\n1. Node.js 22.14.0\n2. npm 10.1.0\n\nThe app may work with other versions, but these are the versions that were used during development.\n\n# Database\n\nSee [Database](database.md) for detailed information.\n\n# Installation\n\n## Backend\n\n1. Copy the contents of `backend/`.\n2. Open a MongoDB project if you don't already have one.\n3. Rename `.env.example` to `.env` in the root directory of the project and paste your MongoDB connection string inside. It should look like this:\n\n```bash\nSTITCHED_DBURL=mongodb+srv://\u003cUSERNAME\u003e:\u003cPASSWORD\u003e@\u003cCLUSTER\u003e.mongodb.net/\u003cDATABASE\u003e?retryWrites=true\u0026w=majority\nSTITCHED_API=\u003ccustom API key\u003e\n```\n\n4. Create a document in your MongoDB database according to the schema in [Defaults Schema](database.md#defaults-schema).\n5. Run `npm i`.\n6. Start the app using `npm start` (or `npm run prod` for production).\n\n\u003e [!IMPORTANT]\n\u003e For the app to work on mobile, the backend needs to be hosted on a server with a public URL.\n\n## Frontend\n\n1. Copy the contents of `frontend/`.\n2. Rename `.env.example` to `.env` in the root directory of the project and fill it with the following:\n\n```bash\nVITE_API=\u003cbase url of the backend\u003e\nVITE_TOKEN=\u003cbackend custom API key\u003e\n```\n\n3. Run `npm i`.\n\n\u003e [!NOTE]\n\u003e At this point you can run `npm start` or `ionic serve` to open the app in browser.\n\n---\n\nTo run the app on mobile:\n\n### Android\n\n4. Install the package:\n\n```\nnpm install @capacitor/android\n```\n\n5. Build the web app:\n\n```\nnpm run build\n```\n\n6. Add the platform:\n\n```\nnpx cap add android\n```\n\n7. Generate Android app icons and splash screens from the source images in the `resources/` directory:\n\n```\nnpx capacitor-assets generate --android\n```\n\n8. Sync web assets and config:\n\n```\nnpx cap sync android\n```\n\n9. Additional Setup: See [Android Setup](android_setup.md) for additional required changes to the Android project files.\n\n10. Open in Android Studio:\n\n```\nnpx cap open android\n```\n\n11. Build and run the app on your device.\n\n### iOS\n\n\u003e [!IMPORTANT]\n\u003e The app was tested \u003cins\u003eonly\u003c/ins\u003e on an **Android** 13+ device.\n\n4. Install the package:\n\n```\nnpm install @capacitor/ios\n```\n\n5. Build the web app:\n\n```\nnpm run build\n```\n\n6. Add the platform:\n\n```\nnpx cap add ios\n```\n\n7. Generate iOS app icons and splash screens from the source images in the `resources/` directory:\n\n```\nnpx capacitor-assets generate --ios\n```\n\n8. Sync web assets and config:\n\n```\nnpx cap sync ios\n```\n\n9. Additional setup: While I can provide the steps required to run the app on Android, I can’t provide their equivalents for iOS, as I don’t have the setup to test or verify them.\u003cbr\u003e\n   The manual changes applied on Android are:\n   - Enabling `usesCleartextTraffic` in the manifest to allow HTTP connections.\n   - Adding a `POST_NOTIFICATIONS` permission to the manifest.\n   - Adding code to request notification permissions on app start.\n   - Copying the notification icon (`resources/manual/ic_notif_icon.png`) to the resources folder.\n\n10. Open in Xcode:\n\n```\nnpx cap open ios\n```\n\n11. Build and run the app on your device.\n\n# Usage\n\n1. Configure your `Defaults` document in the database to suit your needs, and update it as required.\n2. Use the app to keep track of your moments, memories and mementos.\n\n# Future Plans\n\nTo summarize, the future plans for this app are:\n\n- [ ] Rebuild the app from scratch, moving most of the logic to the backend.\n- [ ] Migrate to Push Notifications.\n- [ ] Improve documentation and provide more detailed usage instructions.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felenaches%2Fionic-react-journaling-app","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Felenaches%2Fionic-react-journaling-app","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felenaches%2Fionic-react-journaling-app/lists"}