For my Phase 2 final project at the Flatiron School’s Software Engineering program, I developed an online journal that integrated a user’s Spotify history so they could write about the music they listen to.
In this project, I used Vite and React to create the online journal. The key functionalities were implemented using axios for making asynchronous HTTP requests to Spotify’s API endpoints, as well as the json-server. I used Material UI for the styling and used Yup as the form provider.
For the sake of code organization, I made a file that handled all of the API calls and would make each of the GET requests easy to run. This file would specifically make calls to Spotify API endpoints and to the json-server. The code looked like the following:
import axios from "axios"; export async function getUserId(token) { const endpoint = `https://api.spotify.com/v1/me`; const response = await axios.get(endpoint, { headers: { Authorization: `Bearer ${token}`, } }); return response.data;
} export async function getUserFavorites(type, time_range, limit = 20, token) { const endpoint = `https://api.spotify.com/v1/me/top/${type}`; const response = await axios.get(endpoint, { headers: { Authorization: `Bearer ${token}`, }, params: { time_range: time_range, limit: limit, }, }); return response.data.items;
} export async function getRecentTracks(token) { const endpoint = "https://api.spotify.com/v1/me/player/recently-played"; const response = await axios.get(endpoint, { headers: { Authorization: `Bearer ${token}`, }, params: { limit: 50, }, }); const filtered = response.data.items.map((track) => track.track); return filtered;
} export async function getTrack(token, id) { const endpoint = `https://api.spotify.com/v1/tracks/${id}`; const response = await axios.get(endpoint, { headers: { Authorization: `Bearer ${token}` } }); return response.data;
} export async function getJournalEntries(id) { const endpoint = `http://localhost:4000/entries?user_id=${id}`; const response = await axios.get(endpoint); return response.data;
}
To enable user login without an Express server, we implemented a straightforward process. Users accessed a specific URL for authentication, which then provided an access token upon successful authentication. To streamline accessibility across all pages, we stored this access token in a centralized context, eliminating the need to pass it individually to each page or component.
The web application consists of a structured navigation system facilitated by a Router, enabling seamless transition between its four distinct pages. Certain pages share a unified layout, a feat made possible through the utilization of useRoutes.
The application’s components are methodically organized within designated folders, ensuring clarity and maintainability within the project structure.
Among these components, the most intricate are those composing the Journal Entry form. Leveraging tools like Yup for form validation and custom components tailored for specific requirements, we crafted a sophisticated form. Each field in the form is restricted to a maximum character limit, while a specialized component facilitates the selection of precise dates, enhancing the form’s functionality and user experience.