/calendar-reminder-react

Simple Calendar Reminder React App

Primary LanguageTypeScriptGNU General Public License v3.0GPL-3.0

A Simple Calendar Reminder React App

This project implements a simple calendar reminder. Written in TypeScript using React and Redux, it uses Luxon internally to provide support to the calendar component.

The Calendar component intend to encapsulate the reminder. The component handles the reminders visualization and provide support to the CRUD actions through callback props.

The App component uses the Calendar component and stores the reminders in the Session Storage, using Redux-Saga.

This project was bootstrapped with Create React App and upgraded to include Luxon, Sass, Redux Saga, Material UI, React Icons, and Cypress for E2E testing.

Features

Monthly view:

Displays the current month with all the reminders. It allows navigating between the months using the arrows beside the current month and year on the calendar header.

calendar-view

Reminders view:

The reminders are listed chronologically on the day section of the calendar. Each reminder displays its time, description, and optionally a city and weather data. The weather data is provided by Open Weather Map Free API. Note: the Free account provides historical data for 5 previous days and forecast for 7 days, outside of this range the weather data won't available.

reminders-view

New Reminder:

The reminders can be added by the "New Reminder" button on the top right corner, or by clicking on a specific day in the calendar. For the "New Reminder" the date and time are set by default as the current, when it's open by clicking on a day the date is set accordingly and the time is the current. The description (1 to 30 characters), date and time are the required fields. The city and color are optional. The fields are labelled as What?, When?, Where?, and Select Color.

new-reminder

Validation: Only the What? field is required, as the date and time always have a default value. It should have 1 to 30 character only.

new-remider-what-required

new-remider-what-max30

Date and Time: The When? field displays a calendar with time selection, to open it the user need to click on the canledar icon in the right corner of the field.

new-remider-date-time

City: The Where? is an autocomplete field, using Google Place Autocomplete API, it lists the predictions highlighting the character matches. The user must select one options from the list.

new-remider_where

Color: The color has a default value, the user can click on the color to select another from the colors palette.

new-remider_color

Edit & Remove: The reminders can be edited by clicking over them. There is a delete option in the edit mode.

edit-remove-remider

Limitations

This project was developed as a 5 days challenge. Some paths were taken to deliver all the features stable in time. As future enhancements we have:

User Experience:

  • Delete confirmation: The delete options are done in one click, there is no confirmation dialog.
  • Layout enhancements: The reminder view layout and color need to be polished, borders, spacing and contrast must be reviewed.

Code:

  • Consolidate styles: The CSS isn't unified, it's spread over the components.
  • Custom styles: The styles cannot be customized, provide style props to override the default colors.
  • City autocomplete field was bootstrapped from the Material UI Google Maps Places Autocomplete, the adaptations were basically on the API parameter to fetch only cities and on the library loading, that it's already loaded in the index.html file using an API Key for this project. This component needs to be polished, the API service moved to the api/.

Testing:

  • Increase unit test coverage: the unit tests provided are minimal. There aren't specific unit tests for the CityAutocompleteField component, testing Material UI Autocomplete is complex, there are some challenges to control the component on unit tests. It needs more efforts, another options would be to create the autocomplete component from the scratch making sure it'll be easily testable.
  • Increase e2e test coverage: only two acceptance tests were written: "should not create a reminder without the description" and "should create a reminder with description, date, time, city and color". All the acceptance criteria can be mapped and covered easily using Cypress scripts.

Project directory layout

.
├── public                  # Static files (index.html,...)
├── src                     # Sources and Unit Tests
│   ├── api                 # External APIs (openweather, google geocoder)
│   ├── components          # React components (Calendar.tsx, Reminder.tsx, ...)
│   ├── redux               # Redux, Redux-saga, Reducers, and Store
│   └── ...                 
├── cypress                 # Cypress (E2E tests)
|   ├── integration         # E2E scripts (Calendar.js)
|   └── ...                 
└─...

How to use

In the project directory, you can run:

yarn

Install the app.

yarn start

Runs the app in the development mode.
Open http://localhost:3000 to view it in the browser.

The page will reload if you make edits.
You will also see any lint errors in the console.

yarn test

Unit Tests: Launches the test runner in the interactive watch mode.
See the section about running tests for more information.

yarn test:e2e

E2E Tests: Launches the cypress test runner.
Here's a sample video:

Calendar.Remainder.-.E2E.Tests.Cypress.mp4

yarn build

Builds the app for production to the build folder.
It correctly bundles React in production mode and optimizes the build for the best performance.

The build is minified and the filenames include the hashes.
Your app is ready to be deployed!

See the section about deployment for more information.