Skip to content

Gbarra9/React-Portfolio

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

42 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Gene's React Portfolio

Table of Contents

  1. Description
  2. Website
  3. Programming Languages / Libraries / Frameworks / Technologies / Tools
  4. Design / Wireframes
  5. Features
  6. Opportunity / Difficulty
  7. Upcoming Future Improvement / Features

Description

The following project is my personal portfolio. My motivation for creating the portfolio was to create a new portfolio for myself and for future employers to view. The portfolio was made using React and has Google Analytics implemented to track visitors, primarily hiring managers.


Website

Live Website

Programming Languages / Libraries / Frameworks / Technologies / Tools

Programming Languages / Libraries / Frameworks

ReactReact

SASSSASS

CSSCSS

Technologies / Tools

Create react appCreate React App

FigmaFigma

VSCodeVSCode

NetlifyFont Awesome

Font-AwesomeIonicons


Dependencies

react-router-dom

react-ga4

node-sass


Design / Wireframes


Dark Theme Desktop

dark-theme-desktop


Light Theme Desktop

light-theme-desktop


Dark Theme Mobile

dark-theme-mobile


Light Theme Mobile

light-theme-mobile



Features

Light/Dark Theme Toggle

There is a trend with websites or applications providing users the ability to change the layout based on a dark or light theme. React Context was used for state mangement and local storage to maintain the theme on refresh. The theme was set to dark theme by default due to my partial preference of dark theme over light theme layouts

theme-toggle-gif

refresh-theme-toggle-gif

React Router DOM for Routes

Using a Single Page Application and receiving resources upon a request from the server, React Router is able to change the appearance based on components.

When switching to a route, the client does not need to refresh and send multiple requests to the server for each route. In short, react router helps the user to navigate to different parts of the application without the need of reloads or server requests.

React Router was also used to protect my url routes. By defining routes, you are able to control where users are allowed to not allowed to visit. In the instances of non-existent routes, I was able to set up a 404 page.

404-redirect-gif

Google Analytics

The main motivator for implementing Google Analytics was to view visitor tracking. Google Analytics requires a bit of tweeking if you are using a single page application. Below is an audience report by Google Analytics.

404-redirect

Opportunity / Difficulty


Figma

I was given the opportunity to learn Figma by creating my own layouts and wireframing my website. Figma is tool allowing designers or developers to plan the design of a website or app. Although new to Figma, I am satisfied with the design, how the design was translated to code, and the final product. Sections of the final product based on the pre-designs were altered while I was coding. The main alteration was done for the projects page.


React Context

In the past, I had experience using redux for centralising state management and managing props among components. I learned React Context to maintain my website's theme. Using React Context was a suitable choice. Context allows sharing state between components and avoids prop drilling.

I was left with two options when implementing my theme context. The first option was to make a separate file with an object of all the color values for light and dark theme. I would insert the the object array of colors to context. I would have to drill down the array of objects based on dark or light theme when theme changed.

The second option was to have the color values as root values in my sass files. By changing the class theme of various react elements the element's color would change. I had to assign the color values to elements leaving more flexibility in the future.

Ultimately, the decision of how to assign and structure my color values was the most problematic. In the end second option was chosen to avoid multiple object destructuring.

React Context Code

//ThemeContexProvider.js
import React, { useState, createContext, useEffect } from 'react';

// Create a context object and allows children components to have access to context values
export const ThemeContext = createContext();

const ThemeContextProvider = (props) => {
  // Reads local storage for key darkTheme and assigns value to data
  const dataTheme = localStorage.getItem('currentTheme');
  // If there is data in local storage parse stingified data and assign to initialTheme

  // If there is no data assign initialTheme 'darkTheme'
  const initialTheme = dataTheme ? JSON.parse(dataTheme) : 'darkTheme';

  // React Hooks, set initial state to intialTheme value
  const [theme, setTheme] = useState(initialTheme);

  // If theme in state is 'darkTheme' assign currentTheme to 'lightTheme' value
  // If theme in state is 'lightTheme' assign currentTheme to 'darkTheme' value
  const currentTheme = theme === 'darkTheme' ? 'lightTheme' : 'darkTheme';

  // Event toggle
  const toggleTheme = () => {
    // updates theme in state
    setTheme(currentTheme);
  };

  // UseEffect runs when a component first mounts,and render after any update of initial "theme" state
  // localStorage.setItem sets the key in local storage to currentTheme and sets value to the intial theme's value in a stringified value
  useEffect(() => localStorage.setItem('currentTheme', JSON.stringify(theme)), [
    theme,
  ]);

  return (
    // Provider allows components to consume values and subscribes to context changes
    // Consumers or subscribed components when the Provider's value prop changes
    <ThemeContext.Provider value={{ theme, toggleTheme }}>
      {props.children}
    </ThemeContext.Provider>
  );
};

export default ThemeContextProvider;
}

ThemeContext was created with the logic of grabbing the localStorage theme. If there was no value set the currentTheme value to 'darkTheme' default. Include methods to toggle state. Set a Provider and assign value to props of theme and toggleTheme for subscribed children components to consume.

//App.js

//Wrap Components with ThemeContextProvider to provide value props
<ThemeContextProvider>
  <Switch>
    <Route path='/about' exact component={About}></Route>
    <Route path='/work' exact component={Work}></Route>
    <Route path='/contact' exact component={Contact}></Route>
    <Route path='/' exact component={Home}></Route>
    <Route path='/404' exact component={NoMatch}></Route>
    <Route path='*'>
      <Redirect to='/404' />
    </Route>
  </Switch>
</ThemeContextProvider>

Wrap ThemeContextProviider to be available to children components. Allows children components to receive prop values and rerender if components are subscribed to context.

import React, { useContext } from 'react';
import { ThemeContext } from '../contexts/ThemeContextProvider';
import '../styles/ThemeToggleButton.scss';

const ThemeToggleButton = () => {
  // Use destructuring and provides ThemeToggleButton with prop values from ThemeContext
  const { theme, toggleTheme } = useContext(ThemeContext);

  // If theme is lightTheme assign sun icon else moon icon
  // Conditional rendering of icons
  const toggleIcon =
    theme === 'lightTheme' ? (
      <svg
        aria-hidden='true'
        focusable='false'
        data-prefix='fas'
        data-icon='sun'
        className='svg-inline--fa fa-sun fa-w-16 sun-icon'
        role='img'
        xmlns='http://www.w3.org/2000/svg'
        viewBox='0 0 512 512'
      >
        <title>Sun Icon Theme Toggle</title>
        <path
          fill='currentColor'
          d='M256 160c-52.9 0-96 43.1-96 96s43.1 96 96 96 96-43.1 96-96-43.1-96-96-96zm246.4 80.5l-94.7-47.3 33.5-100.4c4.5-13.6-8.4-26.5-21.9-21.9l-100.4 33.5-47.4-94.8c-6.4-12.8-24.6-12.8-31 0l-47.3 94.7L92.7 70.8c-13.6-4.5-26.5 8.4-21.9 21.9l33.5 100.4-94.7 47.4c-12.8 6.4-12.8 24.6 0 31l94.7 47.3-33.5 100.5c-4.5 13.6 8.4 26.5 21.9 21.9l100.4-33.5 47.3 94.7c6.4 12.8 24.6 12.8 31 0l47.3-94.7 100.4 33.5c13.6 4.5 26.5-8.4 21.9-21.9l-33.5-100.4 94.7-47.3c13-6.5 13-24.7.2-31.1zm-155.9 106c-49.9 49.9-131.1 49.9-181 0-49.9-49.9-49.9-131.1 0-181 49.9-49.9 131.1-49.9 181 0 49.9 49.9 49.9 131.1 0 181z'
        ></path>
      </svg>
    ) : (
      <svg
        aria-hidden='true'
        focusable='false'
        data-prefix='fas'
        data-icon='moon'
        className='svg-inline--fa fa-moon fa-w-16 moon-icon'
        role='img'
        xmlns='http://www.w3.org/2000/svg'
        viewBox='0 0 512 512'
      >
        <title>Moon Icon Theme Toggle</title>
        <path d='M283.211 512c78.962 0 151.079-35.925 198.857-94.792 7.068-8.708-.639-21.43-11.562-19.35-124.203 23.654-238.262-71.576-238.262-196.954 0-72.222 38.662-138.635 101.498-174.394 9.686-5.512 7.25-20.197-3.756-22.23A258.156 258.156 0 0 0 283.211 0c-141.309 0-256 114.511-256 256 0 141.309 114.511 256 256 256z'></path>
      </svg>
    );

  return (
    <button
      className='toggle-button'
      // toggleTheme when buutton is clicked changing state
      onClick={toggleTheme}
      aria-pressed={true}
      aria-label='Theme Toggle Button Icon'
    >
      {toggleIcon}
    </button>
  );
};

export default ThemeToggleButton;

ThemeToggleButton component is subscribed to ThemeContext using the useContext(ThemeContext). Pass toggleTheme value to button's onClick event handler.

Google Analytics

I relied on react-ga4 to handle the information being sent to my personal google analytics. This took a bit of time to setup but will be beneficial to see if hiring managers are visiting my site and their interactions.


Upcoming Future Improvement / Features

Every project has areas to be improved upon. My portfolio project can see improvements in its error handling for local storage. I can also decrease image file size using new image formats.

A future feature I am excited to add on to my website is a contact form. This contact form would be built using node.js, express, Nodemailer and Formik for form handling.


Back to top

About

React Portfolio

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published