ruoroj / thuro

Thuro is a full stack clone of Turo, a peer-to-peer carsharing company.

Home Page:https://thuro.herokuapp.com/#/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Thuro Logo

Thuro Splash

Thuro is a full stack web application inspired by Turo, a peer-to-peer carsharing company.

Live Link

Technologies:

Backend

  • Ruby on Rails
  • PostgreSQL
  • AWS

Frontend

  • React
  • Redux
  • Javascript

APIs

  • Google Maps

Libraries

  • React Dates
  • Moment.js

Features:

User Authentication

Users are required to sign up in order to create cars and book rentals. User credentials are stored as a password digest after being hashed and salted:

# user.rb
class User < ApplicationRecord
 validates :fname, :lname, presence: true
 validates :email, :password_digest, :session_token, presence: true
 validates :email, uniqueness: true
 validates :password, length: { minimum: 6 }, allow_nil: true

 ...

 after_initialize :ensure_session_token

 attr_reader :password

 def self.find_by_credentials(email, password)
     user = User.find_by(email: email)
     return nil unless user && user.is_password?(password)
     user
 end

 def password=(password)
     @password = password
     self.password_digest = BCrypt::Password.create(password)
 end

 def is_password?(password)
     BCrypt::Password.new(self.password_digest).is_password?(password)
 end

 def reset_session_token
     self.session_token = SecureRandom.urlsafe_base64
     self.save!
     self.session_token
 end

 def ensure_session_token
     self.session_token ||= SecureRandom.urlsafe_base64
 end
end

An automated demo login button can be found on the login modal for quicker access to the UX.

Car Create, Update, & Delete

Car owners can post their cars for rent, selecting optional features such as heated seats, GPS, or bluetooth. Mandatory fields such as transmission are also included for potential renter decision-making.

In addition to creation, owners can make edits and delete their listings. Edit and delete options are displayed on the car show page if the current user is recognized as an owner. As an added security measure, any attempt to access another owner's car edit page URL forcefully redirects to the index:

// car_show.jsx
render() {
...  
  if (this.props.car.owner_id === this.props.currentUserId) {
    showEditDel = 
    <>
      <Link to={`/cars/${this.props.car.id}/edit`}>
        <button>Edit this car</button>
      </Link>
      <br />
      <button onClick={this.handleDelete}>Delete this car</button>
    </>
  }

Thuro car edit demo

Rentals

Once a potential customer finds a car they like, a rental can be booked on the right side of the car show page. After accepting the confirmation dialog, a new <div> will appear in the same pane giving the user the option to navigate to their rentals page for review.

Thuro booking demo

Interactive Notifications

Owners will see a toast-tyle notification on the upper right-hand corner of their screen, just below the navbar. The goal of this feature is to let cars owners know upon login that a customer has booked a rental for one of their vehicles. To enable a dynamic transition in the CSS, a styled-components module was used to update position properties based on state changes.

Thuro booking notification

// toast.jsx
  clearToast() {
    for (let i = 0; i < this.props.myPendingRentals.length; i++) {
      let rental = this.props.myPendingRentals[i];
      let rentalId = rental.id;
      this.props.editRental({
        start_date: rental.start_date,
        end_date: rental.end_date,
        renter_id: rental.renter_id,
        car_id: rental.car_id,
        status: 'approved'
      }, rentalId)
        .then(this.setState({
          myPendingRentals: []
        }))
        .then(this.closeToast);
        this.props.fetchCars();
    }
  }

Additionally, once the notification is consumed by the owner by clicking the notification, the notification will not show again when logging out/back in.

Thuro booking demo

// notifications_container.js
const mSTP = (state) => {
  let myPendingRentals = Object.values(state.entities.cars)
    .filter(c => c.rentals.length && c.owner_id === state.session.id)
    .map(c => c.rentals).flat().filter(r => r.status === 'pending');
  return {
    myPendingRentals
  };
};

Future Releases:

  • Reviews
  • Image Carousels
  • Search
  • User Dashboards
  • Add to Favorites

About

Thuro is a full stack clone of Turo, a peer-to-peer carsharing company.

https://thuro.herokuapp.com/#/


Languages

Language:JavaScript 47.0%Language:Ruby 26.4%Language:CSS 23.5%Language:HTML 2.6%Language:CoffeeScript 0.6%