Skip to content

A note-taking app built with React, featuring speech recognition, AI-powered auto-formatting and user-generated custom prompts. • React • Django • REST API • OpenAI API

Notifications You must be signed in to change notification settings

timgoalen/transcriber-frontend

Repository files navigation

Transcriber - frontend

mobile-transcriber-home-page.png

View the live site here.

View the backend REST API: GitHub repo - deployed API.

am-i-responsive-blue.png

About

Transcriber is a note-taking app designed with a focus on speech recognition. It features AI-powered auto-formatting, a folders page and a comprehensive search page.

Fast Idea Capture: Especially on mobile devices, where typing with thumbs can be slow, the voice recognition feature allows you to quickly capture your ideas as you speak, speeding up the process compared to manual typing.

Streamline Difficult Writing: Using voice dictation lets you express your thoughts at the natural pace of speech, helping you overcome writer's block and get that first draft out quickly.

Project Goals

The goals for the site’s functionality were:

  • Voice recognition: users can dictate text to the app.
  • User authentication: users can create an account, log in and log out of the app.
  • Notes: users can create, read, update and delete notes.
  • Inbox: the app has an inbox where notes are stored by default.
  • Folders: users can create, read, update and delete folders; and also move notes into folders.
  • Search: users can search for notes and folders they have created.
  • Auto-formatter: users can automatically correct spelling and punctuation when creating a note.
  • Custom prompts: users can create their own prompts to auto-format their notes using AI.
List of the project goals mapped to the user story Epics:
  • Voice recognition: users can dictate text to the app.
  • User authentication: users can create an account, log in and log out of the app.
  • Notes: users can create, read, update and delete notes.
  • Inbox: the app has an inbox where notes are stored by default.
  • Folders: users can create, read, update and delete folders; and also move notes into folders.
  • Search: users can search for notes and folders they have created.
  • Auto-formatter: users can automatically correct spelling and punctuation when creating a note.
  • Custom prompts: users can create their own prompts to auto-format their notes using AI.

Agile Development

A Kanban board in Github projects was used for the Agile development process - see the board here.

‘Epics’ were broken down into ‘User Stories’, which were further broken down into ‘Tasks’.

User Experience & Design

Wireframes

High-fidelity mockups were made in Figma, using a mobile-first approach, to test the design before building the site.

The general approach was to find the simplest and cleanest layout possible, to limit visual distraction and encourage focus.

Home page:

wireframe-homepage.png

Changes to the mockup in the deployed app:

  • Re-designing the header and navigation.
  • Re-labelling the “delete” button as “clear”.
  • Adding a magic wand button for AI auto-formatting.

Inbox:

wireframe-inbox.png

Changes to the mockup in the deployed app:

  • Naming the page “inbox” rather than “notes”.
  • Changing the folder icon to make it clear that the items are clickable.

Folders:

wireframe-folders.png

Note Detail Modal:

wireframe-note-detail-modal.png

Changes to the mockup in the deployed app:

  • Adding the “folder” option to the tool bar.

Log In:

wireframe-login.png

Changes to the mockup in the deployed app:

  • Adding a navigation header.

Sign Up:

wireframe-signup.png

Changes to the mockup in the deployed app:

  • Adding a navigation header.

Colour Scheme

colour-scheme.png

The site’s primary colours - orange and blue - were adjusted from the Figma mockups to achieve a better contrast ratio, using Contrast Ratio feature in the Chrome DevTools colour picker:

dev-tools-color-picker.png

The colour scheme was chosen to be led by a simple white, with the bold orange and blue acting as accent colours.

Typography

google-font.png

Delius was chosen for its relaxed and playful style, adding more character to the design than a standard sans serif font.

Features

Home page

Desktop:

home-page-desktop.png

Mobile:

home-page-mobile.png

Voice Recognition & Audio Analyser

voice-recognition-demo.gif

  • The audio analyser was implemented to give users direct feedback that recording was taking place, along with the change in border colour of the text area and microphone button that shows recording status.
  • Users can verbalise punctuation like “full stop”, “comma” and “exclamation mark”, or use the auto-formatter explained below.

auto-format-demo.gif

  • The auto-format button, powered by the OpenAi API, allows users to instantly correct spelling and punctuation on their written or dictated text.

Custom AI Prompts

custom-prompts.png

  • Users can create and save their own prompts for formatting notes.
  • Click-and-hold on the ‘AI’ button to open the dialogue.

Navigation Menu

navigation-menu.png

User Menu

Logged out:

account-menu-logged-out.png

Logged in:

account-menu-logged-in.png

Inbox

Mobile:

inbox-mobile.png

Desktop:

inbox-desktop.png

Empty inbox:

inbox-empty.png

Note Detail Modal

When users click on a note item, the note detail modal is opened:

note-detail-modal.png

The modal after the ‘Folder’ button is clicked:

move-to-folder-modal.png

Folders

Mobile:

folders-mobile.png

  • The user can click on the folder to see its contained notes in the dropdown.
  • The expand icon in the note item takes on the colour of the parent folder.

Desktop:

folders-desktop.png

Empty folders page:

folders-empty.png

Edit

edit-page.png

Search

search-demo.gif

  • Because all the notes and folder are stored in state, the search filtering is instantaneous, compared to the approach of sending API queries.

Notifications

notifications.png

  • All user actions are confirmed in the notifications on the bottom left of the screen.

Sign Up

signup.png

Log In

login.png

Info Box

info-box.png

404 Error Page

404-error.png

Features to Implement in the Future

  • Upgrade to a paid, and potentially more reliable voice recognition service (like OpenAI ‘Whisper’ or Google ‘speech-to-text’).
  • Add drag and drop functionality to move notes to different folders.
  • Implement React Query or SWR to manage API caching.
  • Consider using Redux or Zustand to manage global state.
  • Add rich text or markdown formatting capability, or perhaps Notion-style, as a series of contenteditable HTML blocks.
  • Allow users to register with email instead of username.
  • Implement email password reset.
  • Implement social signup.
  • Make the OpenAiApi component only available to logged in users, to save on use fees (but good for showreel purposes to let users demo it).
  • Add ‘offline’ warning in header when no internet connection.
  • Enable the voice recognition to append text to where the cursor is (instead of only to the end of the note).
  • Consider changing the custom prompt feature to a list of baked-in prompts, to minimise unpredictable responses from the AI.

React Components

One of the main benefits of using React for this project is the ability to re-use components. Here are examples of the components that were re-used the most:

  • NavItem.js
  • NoteListItem.js
  • FolderListItem.js
  • FolderOptionItem.js
  • NoteDetailModal.js
  • LoadingSpinner.js
  • NewFolderForm.js
  • NotesInfFolderDropdown.js
  • CloseBtn.js
Complete list of pages and components linked to their relevant User Stories.
  • Pages
    • Edit
      • USER STORY: Speech recognition #39
      • USER STORY: Audio visualizer #38
      • USER STORY: Edit notes #11
    • Folders
      • USER STORY: Read notes #29
      • USER STORY: Delete a folder #18
      • USER STORY: View folders #17
      • USER STORY: Edit folder title #15
      • USER STORY: Create a folder #14
      • USER STORY: Delete a note #13
    • Home
      • USER STORY: Speech recognition #39
      • USER STORY: Audio visualizer #38
      • USER STORY: Create a note #10
    • Inbox
      • USER STORY: Read notes #29
      • USER STORY: Delete a note #13
    • LogIn
      • NoPage
    • Search
      • USER STORY: Search #26
    • SignUp
      • NoPage
  • Components
    • AccountNav
      • USER STORY: Sign up & log in #19
    • Header
    • MenuNav
    • NavItem
    • PageMenu
    • AddAuxItemBtn
    • AudioVisualizer
      • USER STORY: Audio visualizer #38
    • Button
    • CloseBtn
    • CustomPrompts
      • USER STORY: Read custom prompts #25
      • USER STORY: Update prompt #40
      • USER STORY: Delete custom prompt #24
    • SearchBar
      • USER STORY: Search #26
    • SignUpForm
      • USER STORY: Sign up & log in #19
    • SpeechRecognition
      • USER STORY: Speech recognition #39
      • USER STORY: Voice punctuation #21
    • TextArea
    • Toolbar
    • Transcriber
      • USER STORY: Create a note #10
      • USER STORY: Speech recognition #39
      • USER STORY: Audio visualizer #38
    • UserMessages

SpeechRecognition

The speech recognition technology being used is part of the built-in browser Web Speech API. The browser support isn’t 100% yet, and it won’t work on Firefox and older browsers. As a future feature, migrating to a speech recognition service like OpenAi’s Whisper would improve compatibility.

Here is the current stats on browser support for the SpeechRecognitionEvent API:

All users:

speech-recognition-api-usage-all.png

Mobile:

speech-recognition-api-usage-mobile.png

Desktop:

speech-recognition-api-usage-desktop.png

Architecture

State Architecture: Centralised vs Distributed API Calls

I decided to make all the API data fetching (of the ‘notes’ and ‘folders’ arrays) happen within the App itself, and to pass down the data as props, to the Inbox, Folders and Search components.

As the application won’t be dealing with large amounts of data, the simpler Centralised approach was preferred, in spite of it meaning there would be some unneeded data sent to the Inbox and Folders pages.

Diagrams of both approaches:

Centralised API Calls

centralised-api-calls.png

Make the call once in the App and pass the retrieved data down as props.

  • Pros:
    • Keep state consistent throughout the app, as a ‘single source of truth’.
    • Less code duplication.
    • Improved performance when navigating through pages where the data is unchanged.
  • Cons**:**
    • Redundant data if some pages require filtered data.
    • It could harm performance if the data set is large.

Distributed API Calls

distributed-api-calls.png

Each page makes its own API call, of just the specific data that it needs.

  • Pros**:**
    • Potentially better performance is the data is different across the pages.
    • More scalable to complex applications.
  • Cons**:**
    • Higher risk of state inconsistency.
    • More code duplication in the API calls.

User Messages

The main user notification system is implemented globally, with UserMessagesContext. Each component can dispatch a message to the context via the addToMessages function.

In two components - Inbox.js and Folders.js - I had to design a workaround, where messages needed to be sent through page redirects. The first approach was to pick up the messages using a useEffect that only runs on page load. But that led to ESLint warning about missing dependencies, which if fixed would lead to infinite loop re-rendering. The fix was to implement a component-scoped state that stored the messages, using the custom hook usePrevLocationNotification . In the future, all components could use the locally-scoped messages system to avoid two different approaches being used in the app.

CRUD Capabilities

A list of CRUD actions and the components from which they’re dispatched:

Notes

  • CREATE
    • <Transcriber />
  • READ
    • <App />
  • UPDATE
    • Update the note text - <Transcriber />
  • UPDATE
    • Move the note to a folder - <FolderOptionItem />
  • DELETE
    • <NoteDetailModal />

Folders

  • CREATE
    • <App />
    • Note: the create function is in the App so that it can be shared with the Inbox and Folder pages, to be used within the <NoteDetailModal /> component.
  • READ
    • <App />
  • UPDATE
    • <Folders />
  • DELETE
    • <FolderListItem />

Prompts

  • CREATE
    • <CustomPrompts />
  • READ
    • <CustomPrompts />
  • UPDATE
    • <CustomPrompts />
  • DELETE
    • <PromptListItem />

Technologies Used

Third-party APIs Used

  • OpenAI API - used as a text formatter and spelling corrector.

React Libraries Used

  • react-router-dom - for page routing and sending data between pages. Improves site responsiveness and User Experience compared to traditional HTML pages.
  • axios - for simplified syntax with the HTTP requests to the API.
  • dotenv - to enable the use of .env files to store the OpenAI API key.
  • font-awesome - for the site icons.
  • framer-motion - enabling the use of animated transitions within React.
  • use-long-press - simplifies the syntax for the press-and-hold button to open the custom prompts dialogue.

Testing

Automated Testing

ESLint

All JavaScript files were tested with ESLint, with all errors fixed apart from one ‘missing dependencies’ error in the component Transcriber.js (line 69), where I left the code as it is and added eslint-disable-next-line. The useEffect in this case handles data passed from other pages and therefore will never change when the component re-renders. Adding the dependency array led to a rendering loop.

CSS Validation

All CSS modules and index.css were validated by W3C CSS Validator, with no errors present.

Lighthouse Testing

All pages were tested with Google Chrome’s Lighthouse.

Home (desktop):

lighthouse-report-home-desktop.png

Home (mobile):

lighthouse-report-home-mobile.png

Inbox (desktop):

lighthouse-report-inbox-desktop.png

Inbox (mobile):

lighthouse-report-inbox-mobile.png

Folders (desktop):

lighthouse-report-folders-desktop.png

Folders(mobile):

lighthouse-report-folders-mobile.png

Edit (desktop):

lighthouse-report-edit-desktop.png

Edit (mobile):

lighthouse-report-edit-mobile.png

Search (desktop):

lighthouse-report-search-desktop.png

Search (mobile):

lighthouse-report-search-mobile.png

Sign Up (desktop):

lighthouse-report-signup-desktop.png

Sign Up (mobile):

lighthouse-report-signup-mobile.png

Log In (desktop):

lighthouse-report-login-desktop.png

Log In (mobile):

lighthouse-report-login-mobile.png

404 (desktop):

lighthouse-report-404-desktop.png

404 (mobile):

lighthouse-report-404-mobile.png

Based on the recommendations from the initial round of Lighthouse testing, the following changes were made:

  • Update colours for greater contrast.
  • Add aria-labels to buttons that don’t have labels.
  • Add aria-label to form input.
  • Add meta description in head.

WebAIM WAVE Accessibility Testing

All pages were tested with the WAVE tool.

The single alert refers to the Create-React-App boilerplate code that includes a tag, and was left unchanged.

webaim-wave-summary.png

webaim-wave-details.png

webaim-noscript-alert.png

User Stories Testing

All user stories were tested to confirm that they meet their Acceptance Criteria. The following have all PASSED.

(View the EPICS, User Stories, Acceptance Criteria and Tasks on the GitHub Kanban Board).


EPIC: USER ACCOUNTS


As a user I can create an account and log in so that I can use the application.

  • Acceptance Criteria - PASSED:
    • Sign up form
    • Log in form
    • User can create an account with a username and password
    • User can log in with that information and stay logged in until they log out on the device

As a user I can log out of my account so that application data isn't visible to others on my computer.

  • Acceptance Criteria - PASSED:
    • User can log out of the application
    • The browser-stored user token is deleted
    • Log out confirmation message displayed
    • Notes, folder and prompts are cleared form state

EPIC: NOTES CRUD


As a user I can create a note using my voice or by typing so that I can capture my thoughts quickly and efficiently.

  • Acceptance Criteria - PASSED:
    • User can write in a text form
    • User can dictate into the form
    • User receives visual feedback when the voice recognition component if listening.
    • Save button to save the form content

As a user I can view a list of my notes so that I can save thoughts and information.

  • Acceptance Criteria - PASSED:
    • User can view a list of their notes
    • Default notes list is inbox

As a user I can edit my notes so that I can work on my notes on multiple occasions.

  • Acceptance Criteria - PASSED:
    • User can update the text of a note
    • User is taken back to the voice recognition page

As a user I can move my note to a folder so that I can organise my notes.

  • Acceptance Criteria - PASSED:
    • User can move a note from the inbox to a folder

As a user I can delete my notes so that I can keep my inbox and folder clear of unneeded items.

  • Acceptance Criteria - PASSED:
    • User can delete a note

EPIC: FOLDERS CRUD


As a user I can create folders so that my notes can be organised.

  • Acceptance Criteria - PASSED:
    • User can save folders

As a user I can view a list of my folders so that I can see the notes inside of them.

  • Acceptance Criteria - PASSED:
    • Display list of a user's folders
    • User can click on the folder to view the contained notes

As a user I can edit the title of my folders so that I can clarify my intentions.

  • Acceptance Criteria - PASSED:
    • User can edit a folder's title

As a user I can delete folders so that I can remove unneeded folders and notes from my workspace.

  • Acceptance Criteria - PASSED:
    • User can delete folders
    • Delete contained notes when folder is deleted (after "delete notes in side folder" warning message)

EPIC: PROMPTS CRUD


As a user I can create an custom prompt for the AI model so that I can have assistance with my note editing.

  • Acceptance Criteria - PASSED:
    • User can create and save a prompt with a form

As a user I can view a list of my custom prompts so that I can select one to use.

  • Acceptance Criteria - PASSED:
    • User can view a list of their previously saved prompts

As a user I can update my prompt so that I can correct typos or adjust my intention.

  • Acceptance Criteria - PASSED:
    • User can update prompt

As a user I can delete my custom prompts so that I can keep the interface clear of unneeded information.

  • Acceptance Criteria - PASSED:
    • User can delete a custom prompt

EPIC: SPEECH RECOGNITION


As a user I can dictate notes with my voice so that I can get my thoughts down quickly.

  • Acceptance Criteria - PASSED:
    • Users can dictate into the main text area in the home page
    • Users can dictate into the main text area in the edit page
    • Prominent microphone icon

As a user I can view visual feedback when I'm dictating a note so that I can tell that the application is working.

  • Acceptance Criteria - PASSED:
    • Display audio visualizer when user clicks record
    • Hide visualizer when user stops recording

As a use I can add punctuation to a note by using my voice so that I can work quickly.

  • Acceptance Criteria - PASSED:
    • Users can dictate: full stop, comma, question mark, exclamation mark, colon, new line, new paragraph and hyphen

EPIC: AI FORMATTING


As a user I can quickly format my notes or correct the punctuation and spelling so that I can work quickly.

  • Acceptance Criteria - PASSED:
    • 'AI button' that auto-formats the text area, correcting spelling and punctuation
    • The ability to undo formatting

EPIC: SEARCH


As a user I can search for my notes and folders so that I can quickly and easily find them.

  • Acceptance Criteria - PASSED:
    • Search input form
    • Search results display notes and folders, with headings
    • Results dynamically filter as the user types
    • User can click on notes and have CRUD capability

Manual Testing

The following devices and browsers were used for manual & responsive UI testing.

  • iPhone SE (2020)
    • Safari (v16)
    • Chrome (v114)
  • iPad (6th Generation)
    • Chrome (v111)
    • Safari (v15)
  • Mac Pro (Mid 2012)
    • Chrome (v116)
    • Firefox (v115)
  • Dell Chromebook 3120
    • Chrome (v103)

Bugs

Fixed Bugs

Bug Fix
New paragraphs don’t show correctly on the note detail view. CSS: Add white-space: pre-line to the containing <div>.

Unfixed Bugs

Bug
There are sometimes unpredictable results from the OpenAI API response, especially with long text.
Voice recognition can give inconsistent results, especially with “new line” and “new paragraph” voice commands, that sometimes insert a leading whitespace on the following word.
The click-and-hold functionality for opening the custom prompts box doesn’t work reliably in Chrome DevTools.
The audio visualiser is only half-width on mobile (but fine in the DevTools mobile view).
The browser still displays a media stream red light in the tab when the audio analyser unmounts, in the local dev server (it’s fine in the deployed version)
Speech recognition doesn’t capitalise the next character after voice added punctuation (”full stop”, “comma” etc.) when continuously recording, only when the recording has been started and stopped again.

Deployment

Forking the GitHub Repository

By forking the GitHub Repository we make a copy of the original repository on our GitHub account to view and/or make changes without affecting the original repository by using the following steps...

  1. Log in to GitHub and locate the GitHub Repository
  2. At the top right of the Repository, just below the GitHub navbar, click on the "Fork" Button.
  3. You should now have a copy of the original repository in your GitHub account.

Making a Local Clone

  1. Log in to GitHub and locate the GitHub Repository
  2. Above the list of files, click "Code".
  3. To clone the repository using HTTPS, under "Clone with HTTPS", copy the link.
  4. Open Git Bash
  5. Change the current working directory to the location where you want the cloned directory to be made.
  6. Type git clone, and then paste the URL you copied in Step 3.
$ git clone https://github.com/YOUR-USERNAME/YOUR-REPOSITORY

  1. Press Enter. Your local clone will be created.
$ git clone https://github.com/YOUR-USERNAME/YOUR-REPOSITORY
> Cloning into `CI-Clone`...
> remote: Counting objects: 10, done.
> remote: Compressing objects: 100% (8/8), done.
> remove: Total 10 (delta 1), reused 10 (delta 1)
> Unpacking objects: 100% (10/10), done.

Click Here to retrieve pictures for some of the buttons and more detailed explanations of the above process.

  1. For changes you've made to reflect on the live site*:
    • Type git add <files changed>
    • Type git commit -m <description of change>
    • Type git push
    • In Heroku, after pushing to Github - if 'automatic deploys' aren't enabled, manually deploy by clicking 'Deploy Branch' in the Manual Deploy section.

Set up the OpenAI API

  1. Follow the steps outlined in the OpenAI documentation, to obtain an API key.
  2. Set a spending limit in the usage page [login required] if desired.
  3. Create a .env file in your local repo and enter:
REACT_APP_OPENAI_API_KEY = "<your-api-key>”

Deploy to Heroku

  1. Create a Heroku account.
  2. In the dashboard, click on ‘Create new app’ from the ‘New’ dropdown menu in the top right.
  3. Name the app and choose a region.
  4. In the ‘Settings’ tab, click on 'Reveal Config Vars’.
  5. Enter you OpenAi API details:
    • KEY = REACT_APP_OPENAI_API_KEY
    • VALUE = <your-api-key>
  6. In the 'Buildpacks' section click 'Add buildpack'.
  7. Select ‘nodejs’, and click 'save changes'.
  8. In the 'Deploy' tab, select GitHub as the deployment method, and click 'Connect to GitHub'.
  9. In the 'App Connected to GitHub' section, search for the GitHub repository name, select it then click 'connect'.
  10. Finally, either click ‘Enable Automatic Deploys’, or ‘Deploy Branch’ in the ‘Manual deploy’ section.

Credits

Content

The SVG used for the empty page placeholder is from:

https://freesvgillustration.com/product/banana-tree/

With customised colours chosen from the site palette, and passed as props to the component.

Code

The following docs and tutorials were consulted.

React

Official react docs

Colt Steele Udemy course

Guide to React Refs - Logrocket

React notes app with local storage tutorial - Logrocket

React todo list tutorial - MDN Web Docs

How to use an ‘env’ file in React - Medium

Using font awesome in React - dev.to

Speech Recognition API

API Docs - Chrome for developers

API Guide - MDN

Speech recognition tutorial - freeCodeCamp

Speech recognition tutorial - tutorialzine.com

Audio Visualiser

Audio visualiser tutorial - Logrocket

Audio visualiser tutorial - Wes Bos

OpenAI API

Official OpenAI docs

Testing the API with Postman - sap.com

Using OpenAI with React - Medium

Acknowledgements

  • My mentor Lauren-Nicole Popich for her invaluable guidance.

About

A note-taking app built with React, featuring speech recognition, AI-powered auto-formatting and user-generated custom prompts. • React • Django • REST API • OpenAI API

Topics

Resources

Stars

Watchers

Forks

Languages