What a journey it has been, 10 months of coding from building a Command Line Interface (CLI), Sinatra, Ruby on Rails, Vanilla JavaScript and now, ReactJS/Redux. I have grown so much, and am truly excited to learn more languages, frameworks and libraries upon graduation. While my previous mod projects encompass personal interests of mine (from space exploration, Street Fighter, tele-health platform to trivia game app), I have kept this particular idea until the very end.
I have been a long-advocate for having a meaningful connection through self-reflection. Having a digital journaling app to log events, places, moods, and self-reflections from different points of view would fulfill my personal pursuits of journaling experience. While some journal apps I have seen simply record special memories and events, some focus more on mental health, mindfulness and self-care. I have decided to approach this app build with basic features of recorded events and necessary attributes. Future improvements can possibly include mood tracker with A.I. collecting info on how the user is doing. After dedicating sometime to research on a few journal apps such as Reflectly, Diaro, Daylio, and others, I emulate most of my app build features following Day One and Notion. I love the overall user flow from Day One, and the postulation of all-in-one workspace from Notion. There are a couple of technical challenges I would like to pursue personally such as working with Google Maps API.
I brainstormed my app through building wireframes at first. The exercise helped me to collect some understanding of model relationships, necessary attributes, components and overall user interface. I realized that my wireframing exercise eventually became an overarching goal. ๐ฅบ
As the user begins their journaling experience, the user will be prompted to fill out a form of an entry event. Each entry event carries event title, date, time, location, vibe, description and photo. The user can personalize each entry by assigning a category. After several entries and categories propagated over some time, when the user selects a category, it should list its respective event entries. For example, under category 'restaurants', the user will see all of their food ventures entries. As the user selects a specific entry, it will prompt a show page specific to the selected event id. The user can reflect all of their journal entries through various points of view: calendar, map and photos. For example, if the user selects a map view, it will show all pinpoints of recorded places. The user can select each pinpoint, and it should also display event details in correspond to the selected entry id.
There are 4 main models User, Category, Event and Image with their associations as follows.
I have built Rails API previously, and surprisingly... I have only a small memory recollection. ๐
I initiated the prompt command rails new Storybook_backend --database=postgresql --api --no-test-framework. The --api will remove unnecessary features and middleware with controllers inheriting from ActionController::API, and --no-test-framework will remove any testing framework. PostgreSQL database is helpful when I need to deploy on Heroku. Make sure to include gem rack-cors and bcrypt when bundle install. The next step is to generate Active Record Models for User, Category, Event and Image, and execute rails db:create && rails db:migrate.
Moving on to my controllers, I spent most of my time applying JWT(JSON Web Tokens) in my ApplicationController, Api::V1::UsersController and Api::V1::AuthController. The ApplicationController defines JWT.encode, JWT.decode and most importantly authorized instance method to barricade access to the other controllers. Only an authorized user can access other controllers. The AuthControllercreate action will provide authentication for users logging in, and the UsersControllercreate action allows a new user signing up.
I had many byebug exercises on create and update actions in Api::V1::EventsController. Not only a new event will be created, but also its respective category and image. I have an event entry form on my front-end to accommodate user inputs. I utilize Cloudinary in order to manipulate images with a URL-based API. The rest of my controllers' actions are mostly index and show. This is where Active Model Serializers helps with displaying any intended attributes to pass information necessary over to front-end's Redux state management. Including model relationships helps to display arrays of event's category and image in one single Object.
The Minimum Viable Product (MVP) of Storybook app is to allow the user to log events, places, moods and self-reflect from various points of views (calendar, map, photos).
Storybook
Domain Modeling :: Digital Journaling
Welcome to my simplistic version of digital journaling app.
I have been a long-advocate for having meaningful connection through self-reflection. While some journal apps I have seen simply record special memories and events, some focus more on mental health, mindfulness and self-care. I have decided to approach this app build with basic features of recorded events and necessary attributes.
The Minimum Viable Product (MVP) of Storybook app is to allow the user to log events, places, moods and self-reflect from various points of views (calendar, map, photos).
I started with npx create-react-app storybook and npm install redux && npm install react-redux as for Redux state management. I learned that NPM packages do not allow upper case characters because unix filesystems are case-sensitive (as I previously tried Storybook, and ๐คจ it failed). For whatever reason, I froze for quite sometime, not knowing where to get a start with my React app. I have decided to step back and brainstorm a file structuring diagram, which helped tremendously as I progressed through my code.
I started with my index.js file, and set up my Provider and store. Following best practice, I kept actions, reducers and store.js inside of the Redux folder. The App.js carries the first parent container for my ProfileContainer. This component becomes a portal once a user successfully signs in, and it will navigate the user to 3 container components, NavBar, EventViewList and DisplayContainer. The rests are presentational components and most of them are built as functional components which rely mainly on props. With all that said, I definitely spent a good chunk of time with file-naming, aligning file structures and folder hierarchy. On another note, Redux DevTools is a great tool that I set up in order to view Redux state.
5. Action โ Reducer โ New State
connect() and Provider play a big role as part of React Redux middleware. Provider ensures that my React app can access data from the store, and connect() allows whichever component to specify which state and actions the app needs access to. I implemented combineReducers to consolidate all reducers and set the Redux state management.
I should be able to access the object value of event with mapStateToProps in any desirable component to display the current state of event entry. I have a total of 8 reducers from category, error, user, token and others under one rootReducer.
6. Nested Routes in React Router
ReactJS relies upon Client-Side routing to handle routing, fetching and displaying data in the browser. It is after all a Single-Page Application (SPA). While it benefits in speed, it also presents more design challenges. I tried my best to achieve proper RESTful routing.
The EventViewList component is my middle presentational component that displays various UI components in correspond to the left navigation bar. I would refer my EventViewList as an intermediary. As the user navigates through, my right presentational component, EventDisplay, will exhibit detailed information. Snippet below represents Route path ${url}/calendar/:eventId where calendar view displays propagated entry dates the user had previously recorded, and eventId will fetch the associated event entry from provided events state from Redux store.
7. Google Maps Platform APIs
I have decided to utilize google-maps-react and react-google-autocomplete NPM packages. Their documentation is pretty solid and provides a straightforward code implementation to my Storybook MVP needs. API can be retrieved from Google Developers Console, and I include Geocoding API, Maps JavaScript API and Places API. Once GoogleApiWrapper from 'google-maps-react' and PlacesAutocomplete from 'react-places-autocomplete' are imported to my Form component, the user can automatically submit an address and/or location from the autocomplete textfield. It should automatically send an API request to retrieve the location's latitude and longitude. Each location and its respective coordinates will be saved in the PostgreSQL database, and that's how I was able to collect an array of various coordinates and propagate them to a map view. I also learned how to save an API_KEY by adding REACT_APP_ to my API key in the .env file.
8. Material-UI and Lessons Learned
I had much fun perusing through Material-UI library. If given more time, I would love to develop Storybook mobile UI. Current project build is focused on browser desktop UI. There are a lot of customization theming that piques my design interest.
Anyhow... I am glad I had the chance to learn ReactJS/Redux, and it definitely speaks on its own popularity and demand. React provides a modular way to separate code and functionality in declarative writing structure, producing highly reusable and independent entities. I now feel comfortable with JSX syntax, container vs. presentational components, Redux state management, Client Routing and finally, implementing Google Maps API. Check out my GitHub repo!
The Minimum Viable Product (MVP) of Storybook app is to allow user to log events, places, moods and self-reflect from various points of views (calendar, map, photos).
Storybook
Domain Modeling :: Digital Journaling
Welcome to my simplistic version of digital journaling app.
I have been a long-advocate for having meaningful connection through self-reflection. While some journal apps I have seen simply record special memories and events, some focus more on mental health, mindfulness and self-care. I have decided to approach this app build with basic features of recorded events and necessary attributes.
The Minimum Viable Product (MVP) of Storybook app is to allow the user to log events, places, moods and self-reflect from various points of views (calendar, map, photos).
Storybook was completed in a 2-week timeframe from implementing Rails back-end, ReactJS front-end, Cloudinary API, Google Maps API and Material-UI library. I have several ideas as I progressed through building my MVP (Minimum Viable Product). Future cycle of product development as follows:
Search Bar. Over the time, the user will have many events, and it gets troublesome when the user needs to immediately access a specific event entry. A search bar to quickly type event title and access the journal entry would be useful.
Add Friend to model associations. I envision my app to emulate similar concept such as Instagram. Instead of creating a simple journaling app, what about a social journaling platform. Each user can personalize their privacy whether or not they'd like to share with their friends.
Adding mood tracker. Current attribute vibe to capture my preliminary attempt of gathering user mood data on each event entry. I found a mood tracker API that I would love to integrate in future project build. User can view their journal entries based on Mood under View NavBar.
Current event entry only allows one image upload. User should be able to upload multiple images, insert GIF and video upload.
Create a toggle track for dark mode. ๐
Post Scriptum:
This is my Module 5 capstone project with Flatiron School. I believe one of the catalyst to becoming a good programmer is to welcome constructive criticism. Feel free to drop a message. ๐