diff --git a/.vs/slnx.sqlite b/.vs/slnx.sqlite new file mode 100644 index 000000000..e69de29bb diff --git a/Gemfile b/Gemfile index 5efe339e6..6bfc1f339 100644 --- a/Gemfile +++ b/Gemfile @@ -37,7 +37,7 @@ gem "redis", "~> 4.0" # gem "kredis" # Use Active Model has_secure_password [https://guides.rubyonrails.org/active_model_basics.html#securepassword] -# gem "bcrypt", "~> 3.1.7" +gem "bcrypt", "~> 3.1.7" # Windows does not include zoneinfo files, so bundle the tzinfo-data gem gem "tzinfo-data", platforms: %i[ mingw mswin x64_mingw jruby ] @@ -83,3 +83,8 @@ gem 'dotenv-rails' # gem 'paperclip # gem 'uniquify' # gem 'will_paginate' + +gem "geocoder", "~> 1.8" + +# dynamic map +gem "mapkick-rb" diff --git a/Gemfile.lock b/Gemfile.lock index c3e104938..cc0b2c248 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -68,6 +68,7 @@ GEM tzinfo (~> 2.0) addressable (2.8.1) public_suffix (>= 2.0.2, < 6.0) + bcrypt (3.1.19) bindex (0.8.1) bootsnap (1.13.0) msgpack (~> 1.2) @@ -93,6 +94,7 @@ GEM dotenv (= 2.8.1) railties (>= 3.2) erubi (1.11.0) + geocoder (1.8.2) globalid (1.0.0) activesupport (>= 5.0) i18n (1.12.0) @@ -111,6 +113,7 @@ GEM nokogiri (>= 1.5.9) mail (2.7.1) mini_mime (>= 0.1.1) + mapkick-rb (0.1.5) marcel (1.0.2) matrix (0.4.2) method_source (1.0.0) @@ -223,15 +226,20 @@ GEM PLATFORMS arm64-darwin-20 + arm64-darwin-21 + arm64-darwin-22 x86_64-linux DEPENDENCIES + bcrypt (~> 3.1.7) bootsnap capybara debug dotenv-rails + geocoder (~> 1.8) importmap-rails jbuilder + mapkick-rb mysql2 (~> 0.5) puma (~> 5.0) rails (~> 7.0.3, >= 7.0.3.1) diff --git a/README.md b/README.md index 85f6c86ae..17e00d2d9 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ # ValetBike - +Paola Smith College CSC223: Software Engineering\ Starter App for ValetBike project +This is a change that I am making to valetbike! ## Environment Configuration diff --git a/app/assets/images/logo.svg b/app/assets/images/logo.svg new file mode 100644 index 000000000..7f4121c43 --- /dev/null +++ b/app/assets/images/logo.svg @@ -0,0 +1,14 @@ + \ No newline at end of file diff --git a/app/assets/stylesheets/button.css b/app/assets/stylesheets/button.css new file mode 100644 index 000000000..9d2756567 --- /dev/null +++ b/app/assets/stylesheets/button.css @@ -0,0 +1,5 @@ + + +.button{ + background-color: rgb(132 204 22); +} \ No newline at end of file diff --git a/app/assets/stylesheets/error-messages.css b/app/assets/stylesheets/error-messages.css new file mode 100644 index 000000000..86738f4e4 --- /dev/null +++ b/app/assets/stylesheets/error-messages.css @@ -0,0 +1,20 @@ +/* Error Messages CSS */ +.error-explanation { + background-color: #fed7d7; + border: 1px solid #f98080; + color: #c53030; + padding: 1rem; + border-radius: 0.375rem; + margin-top: 1rem; + } + +.error-list { +list-style-type: disc; +padding-left: 1.25rem; +margin-top: 0.5rem; +} + +.error-message { +font-weight: bold; +} + \ No newline at end of file diff --git a/app/assets/stylesheets/flash.css b/app/assets/stylesheets/flash.css new file mode 100644 index 000000000..7279ddfdc --- /dev/null +++ b/app/assets/stylesheets/flash.css @@ -0,0 +1,19 @@ +.flash{ + padding: 20px; + color: white; + width: 90%; /* Set width to 100% of the parent element */ + opacity: 90%; + margin-left: auto; + margin-right: auto; + +} + +#notice { + background-color: var(--green-color); /* Override color for notice */ + border-color: 3px, solid, var(--dark-green-color); +} + +#alert { + background-color: var(--red-color); /* Red for alert, green for notice */ + border-color: 3px, solid, var(--dark-green-color); +} diff --git a/app/assets/stylesheets/form.css b/app/assets/stylesheets/form.css new file mode 100644 index 000000000..0c9e01034 --- /dev/null +++ b/app/assets/stylesheets/form.css @@ -0,0 +1,34 @@ +.form-container { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 20px; + } + +.form-group { + margin-bottom: 15px; +} + +label { + display: block; + margin-bottom: 5px; + color: var(--light-black-color); + font-weight: bold; +} + +input[type="text"], input[type="password"] { + /* Inherits styles from previous CSS */ + width: 100%; /* Adjust as necessary */ + color: black; +} + +.form-buttons { + display: flex; + justify-content: center; + margin-top: 20px; +} + +input#search_by_address { + color: black; +} \ No newline at end of file diff --git a/app/assets/stylesheets/navbar.css b/app/assets/stylesheets/navbar.css new file mode 100644 index 000000000..2d92d3ae5 --- /dev/null +++ b/app/assets/stylesheets/navbar.css @@ -0,0 +1,42 @@ +/* currently does not work...not invoked or something - ryan */ +/* change navbar background color to custom */ +#navbar { + padding-top: 2%; + padding-bottom: 4%; + z-index: 100; + background-color: var(--blue-color); + height: 5em; +} + +#navbar-content { + height: 3em; + width: 100%; +} + +@media (min-width: 80em){ + #navbar-content { + width: 70em; + } + + .logo { + + } +} + + +.white-fill { + fill: var(--medium-white-color); + +} + +.logo { + margin-left: 1em; +} + +.dropdown-menu { + z-index: 1000; /* Adjust the value as needed */ + position: relative; +} + +} + diff --git a/app/assets/stylesheets/pages.css b/app/assets/stylesheets/pages.css index 16bd64b55..f2e85b948 100644 --- a/app/assets/stylesheets/pages.css +++ b/app/assets/stylesheets/pages.css @@ -26,14 +26,38 @@ line-height: 1.75em; } +.record-row.header { + background: var(--black-color); + color:aliceblue; +} + + .record-row.even { background: var(--medium-white-color); } +.record-row.even.flexbox:hover{ + background: var(--light-black-color); + color:aliceblue; +} + .record-row.odd { background: var(--dark-white-color); } +.record-row.odd.flexbox:hover{ + background: var(--light-black-color); + color:aliceblue; +} + +.fill-block { + display: block; + height: 100%; + width: 100%; + text-decoration: none; +} + + /***********************************/ /* Responsiveness */ diff --git a/app/assets/stylesheets/popup.css b/app/assets/stylesheets/popup.css new file mode 100644 index 000000000..edc30b656 --- /dev/null +++ b/app/assets/stylesheets/popup.css @@ -0,0 +1,32 @@ +.modal { + position: fixed; + z-index: 1000; + padding: 2em; + + /* Centering */ + left: 50%; + top: 50%; + transform: translate(-50%, -50%); + + overflow: auto; + background-color: rgb(0,0,0); + background-color: rgba(255, 255, 255, 0.1); + border-radius: 5px; + /* Add the drop shadow */ + box-shadow: 0 0 10px 0 rgba(0,0,0,0.2), 0 5px 10px 0 rgba(0,0,0,0.19); +} + +.cancel-button { + background-color: #1530ff; + font-size: 12px; + color: white; + padding: 4px 8px; + border: none; + border-radius: 4px; + cursor: pointer; + float: right; + text-decoration: none; +} +.cancel-button:hover { + background-color: #2640fe; +} \ No newline at end of file diff --git a/app/assets/stylesheets/variables.css b/app/assets/stylesheets/variables.css index 915c14dd3..ee122e37e 100644 --- a/app/assets/stylesheets/variables.css +++ b/app/assets/stylesheets/variables.css @@ -10,4 +10,10 @@ --medium-white-color: #FDFCFD; --white-color: #FFFFFF; + --green-color: #3BD6AF; + --dark-green-color: rgb(23, 84, 4); + --orange-color: #F89356; + --blue-color: #4B719D; + --red-color: #db6363; + --dark-red-color: #7e0303; } \ No newline at end of file diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 09705d12a..fe3bdfe9e 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,2 +1,13 @@ class ApplicationController < ActionController::Base + #declare as helper so accessable to all views + before_action :require_login + + def require_login + redirect_to new_session_path unless session.include? :user_id + end + + private + def current_user + @current_user ||= User.find(session[:user_id]) if session[:user_id] + end end diff --git a/app/controllers/bikes_controller.rb b/app/controllers/bikes_controller.rb new file mode 100644 index 000000000..a424682e2 --- /dev/null +++ b/app/controllers/bikes_controller.rb @@ -0,0 +1,10 @@ +class BikesController < ApplicationController + def index + if params[:reverse].blank? || params[:reverse] == "0" + @bikes = Bike.all.order(identifier: :asc) + else + @bikes = Bike.all.order(identifier: :desc) + end + end + +end diff --git a/app/controllers/categories_controller.rb b/app/controllers/categories_controller.rb new file mode 100644 index 000000000..bd5653d1e --- /dev/null +++ b/app/controllers/categories_controller.rb @@ -0,0 +1,23 @@ +class CategoriesController < ApplicationController + def index + end + + def show + end + + def edit + end + + def create + end + + def delete + end + + def destroy + end + + def new + end + +end diff --git a/app/controllers/home_controller.rb b/app/controllers/home_controller.rb new file mode 100644 index 000000000..95f29929c --- /dev/null +++ b/app/controllers/home_controller.rb @@ -0,0 +1,4 @@ +class HomeController < ApplicationController + def index + end +end diff --git a/app/controllers/locations_controller.rb b/app/controllers/locations_controller.rb new file mode 100644 index 000000000..3febffef6 --- /dev/null +++ b/app/controllers/locations_controller.rb @@ -0,0 +1,78 @@ +class LocationsController < ApplicationController + before_action :set_location, only: %i[ show edit update destroy ] + + # GET /locations or /locations.json + def index + if params[:place].present? + @locations = Location.near(params[:place], params[:distance] || 5, order: :distance) + else + @locations = Location.all + end + if !@location.nil? + puts "hello there " + params[:count] = @location.count + end + end + + # GET /locations/1 or /locations/1.json + def show + end + + # GET /locations/new + def new + @location = Location.new + end + + # GET /locations/1/edit + def edit + end + + # POST /locations or /locations.json + def create + @location = Location.new(location_params) + + respond_to do |format| + if @location.save + format.html { redirect_to location_url(@location), notice: "Location was successfully created." } + format.json { render :show, status: :created, location: @location } + else + format.html { render :new, status: :unprocessable_entity } + format.json { render json: @location.errors, status: :unprocessable_entity } + end + end + end + + # PATCH/PUT /locations/1 or /locations/1.json + def update + respond_to do |format| + if @location.update(location_params) + format.html { redirect_to location_url(@location), notice: "Location was successfully updated." } + format.json { render :show, status: :ok, location: @location } + else + format.html { render :edit, status: :unprocessable_entity } + format.json { render json: @location.errors, status: :unprocessable_entity } + end + end + end + + # DELETE /locations/1 or /locations/1.json + def destroy + @location.destroy + + respond_to do |format| + format.html { redirect_to locations_url, notice: "Location was successfully destroyed." } + format.json { head :no_content } + end + end + + private + # Use callbacks to share common setup or constraints between actions. + def set_location + @location = Location.find(params[:id]) + end + + # Only allow a list of trusted parameters through. + def location_params + params.require(:location).permit(:name, :address, :latitude, :longitude) + end +end diff --git a/app/controllers/memberships_controller.rb b/app/controllers/memberships_controller.rb new file mode 100644 index 000000000..1ef59ac32 --- /dev/null +++ b/app/controllers/memberships_controller.rb @@ -0,0 +1,29 @@ +class MembershipsController < ApplicationController + def index + @membership = Membership.order(:price) + end + + def show + @membership = Membership.find(params[:id]) + end + + def new + @membership = Membership.new + end + + def edit + @membership = Membership.find(params[:id]) + end + + def update + + end + + def delete + + end + + def destroy + + end +end diff --git a/app/controllers/payments_controller.rb b/app/controllers/payments_controller.rb new file mode 100644 index 000000000..dc7585d7b --- /dev/null +++ b/app/controllers/payments_controller.rb @@ -0,0 +1,39 @@ +class PaymentsController < ApplicationController + def index + if params[:reverse].blank? || params[:reverse] == "0" + @payments = Payment.all.order(id: :asc) + else + @payments = Payment.all.order(id: :desc) + end + render :index + end + + def new + @payment = Payment.new + render :new + end + + def create + @payment = Payment.new(params.require(:payment).permit(:credit_card_info, :amount)) + if @payment.save + flash[:success] = "Payment completed" + redirect_to payments_url + else + flash[:error] = "Payment failed" + redirect_to new_payment_path + end + end + + def show + end + + def update + end + + def edit + end + + def destroy + end + +end diff --git a/app/controllers/rentals_controller.rb b/app/controllers/rentals_controller.rb new file mode 100644 index 000000000..8e473b847 --- /dev/null +++ b/app/controllers/rentals_controller.rb @@ -0,0 +1,73 @@ +class RentalsController < ApplicationController + def index + if params[:reverse].blank? || params[:reverse] == "0" + @rentals = Rental.all.order(id: :asc) + else + @rentals = Rental.all.order(id: :desc) + end + render :index + end + + def new + @rental = Rental.new + render :new + end + + def create + @rental = Rental.new(params.require(:rental).permit(:rental_period, :return_by)) + @current_user = User.find(session[:user_id]) + if @current_user.has_bike.nil? + flash[:error] = "Your account has a nil rental currently...setting to false. try again" + @current_user.has_bike=false + @current_user.save + redirect_to new_rental_path + elsif @current_user.has_bike? #if has bike is true + flash[:error] = "You already have an active rental. Cannot rent multiple bikes before returning...that feature soon to be released" + redirect_to rentals_url + elsif !@current_user.has_bike #if has bike is false + @current_user.has_bike=true + @current_user.current_rental=@rental + @current_user.save + @current_user.has_bike = true + @current_user.save + puts @current_user.has_bike? + puts @current_user + puts session[:user_id] + @rental.user = @current_user + puts @rental.user + if @rental.save + flash[:success] = "Rental created" + redirect_to rentals_url + else + flash[:error] = "Rental creation failed" + redirect_to new_rental_path + end + else + flash[:error] = "Rental creation failed...your rental status is not nil, true, or false. something is majorly wrong" + end + end + + def show + @rental = Rental.find(params[:id]) + render :show + end + + def update + puts "returning rental..." + @current_user = User.find(session[:user_id]) + Rental.find(id: @current_user.current_rental.to_i).returned_at=DateTime.now + puts @current_user.current_rental.returned_at + @current_user.current_rental=nil + puts @current_user.current_rental + @current_rental.has_bike=false + puts @current_rental.has_bike + puts "rental returned...hopefully" + end + + def edit + end + + def destroy + end + +end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb new file mode 100644 index 000000000..8257114c7 --- /dev/null +++ b/app/controllers/sessions_controller.rb @@ -0,0 +1,32 @@ +class SessionsController < ApplicationController + skip_before_action :require_login, only: [:create, :new] + + def new + + end + + def create + session_params = params.permit(:email_address, :password) + @user = User.find_by(email_address: session_params[:email_address]) + if @user && @user.authenticate(session_params[:password]) + session[:user_id] = @user.id + flash[:notice] = "You've successfully Logged In. Thank you." + redirect_to users_show_path + else + flash.now[:alert] = "Login information invalid" + render :new, status: 500 + end + end + + def destroy + logger.info("*** Logged out #{cookies[:email_address]}") + flash[:notice] = "You are now signed out" + + # do logout process here + session[:user_id] = nil + cookies[:user_name] = nil + @current_user = nil + + redirect_to login_path + end +end diff --git a/app/controllers/stations_controller.rb b/app/controllers/stations_controller.rb index 88090af16..dffb0fbf2 100644 --- a/app/controllers/stations_controller.rb +++ b/app/controllers/stations_controller.rb @@ -1,7 +1,24 @@ class StationsController < ApplicationController def index + @stations = Station.all.order(identifier: :asc) + + if params[:search_by_address] && params[:search_by_address] != "" + @stations = @stations.where("address LIKE ?", "%#{params[:search_by_address]}%") + end + puts @stations + end + + def show + @station = Station.find_by(identifier: params[:id]) + render :show + + if params[:reverse].blank? || params[:reverse] == "0" + @stations = Station.all.order(identifier: :asc) + else + @stations = Station.all.order(identifier: :desc) + end + end - end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb new file mode 100644 index 000000000..11852874d --- /dev/null +++ b/app/controllers/users_controller.rb @@ -0,0 +1,45 @@ +class UsersController < ApplicationController + + skip_before_action :require_login, only: [:create, :new] + + #keep login + def show + @current_user = User.find(session[:user_id]) + render :show + end + + def index + @current_user = User.find(session[:user_id]) + end + + + #Sign-up + def create + # logger.info("\n\n*****attempting to create new user\n\n") + # logger.info("\n\n*****In new #{user_params}\n\n") + @user = User.new(user_params) + # logger.info("\n\n*****Set new\n\n") + if @user.save + session[:user_id] = @user.id + @user.has_bike = false + @user.save + flash[:notice] = "Welcome to your new account." + redirect_to rentals_path + else + puts "Can not create user" + flash.now[:alert] ||= "" + @user.errors.full_messages.each do |message| + flash.now[:alert] << message + ". " + end + render :new, status: 500 + end + end + + private + + def user_params + logger.info("\n\n*****attempting to create new user\n\n") + params.permit(:email_address, :password, :password_confirmation, :first_name, :last_name) + end + +end \ No newline at end of file diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index de6be7945..ed572c74d 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,2 +1,9 @@ module ApplicationHelper + def logged_in? + + end + + def current_user + + end end diff --git a/app/helpers/bikes_helper.rb b/app/helpers/bikes_helper.rb new file mode 100644 index 000000000..a2645e4e1 --- /dev/null +++ b/app/helpers/bikes_helper.rb @@ -0,0 +1,2 @@ +module BikesHelper +end diff --git a/app/helpers/categories_helper.rb b/app/helpers/categories_helper.rb new file mode 100644 index 000000000..e06f31554 --- /dev/null +++ b/app/helpers/categories_helper.rb @@ -0,0 +1,2 @@ +module CategoriesHelper +end diff --git a/app/helpers/home_helper.rb b/app/helpers/home_helper.rb new file mode 100644 index 000000000..23de56ac6 --- /dev/null +++ b/app/helpers/home_helper.rb @@ -0,0 +1,2 @@ +module HomeHelper +end diff --git a/app/helpers/layout_helper.rb b/app/helpers/layout_helper.rb new file mode 100644 index 000000000..bb9b712c7 --- /dev/null +++ b/app/helpers/layout_helper.rb @@ -0,0 +1,35 @@ +module LayoutHelper + def display_alerts + if flash[:alert].present? + puts "there are alerts" + content_tag(:div, class: "flash", id: "alert") do + a = flash[:alert] + puts "The alert is/are " + a + content_tag(:div, a, class: "text") + end + end + end + + def display_notices + if flash[:notice].present? + content_tag(:div, class: "flash", id: "notice") do + content_tag(:div, flash[:notice], class: "text") + end + end + end + def display_errors + if flash[:error].present? + content_tag(:div, class: "flash", id: "error") do + content_tag(:div, flash[:error], class: "text") + end + end + end + + def display_successes + if flash[:success].present? + content_tag(:div, class: "flash", id: "success") do + content_tag(:div, flash[:success], class: "text") + end + end + end + end \ No newline at end of file diff --git a/app/helpers/locations_helper.rb b/app/helpers/locations_helper.rb new file mode 100644 index 000000000..46f94288a --- /dev/null +++ b/app/helpers/locations_helper.rb @@ -0,0 +1,2 @@ +module LocationsHelper +end diff --git a/app/helpers/memberships_helper.rb b/app/helpers/memberships_helper.rb new file mode 100644 index 000000000..eaf43c733 --- /dev/null +++ b/app/helpers/memberships_helper.rb @@ -0,0 +1,2 @@ +module MembershipsHelper +end diff --git a/app/helpers/payments_helper.rb b/app/helpers/payments_helper.rb new file mode 100644 index 000000000..c1b884f80 --- /dev/null +++ b/app/helpers/payments_helper.rb @@ -0,0 +1,2 @@ +module PaymentsHelper +end diff --git a/app/helpers/rentals_helper.rb b/app/helpers/rentals_helper.rb new file mode 100644 index 000000000..5a8b81508 --- /dev/null +++ b/app/helpers/rentals_helper.rb @@ -0,0 +1,2 @@ +module RentalsHelper +end diff --git a/app/helpers/sessions_helper.rb b/app/helpers/sessions_helper.rb new file mode 100644 index 000000000..309f8b2eb --- /dev/null +++ b/app/helpers/sessions_helper.rb @@ -0,0 +1,2 @@ +module SessionsHelper +end diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb new file mode 100644 index 000000000..2310a240d --- /dev/null +++ b/app/helpers/users_helper.rb @@ -0,0 +1,2 @@ +module UsersHelper +end diff --git a/app/javascript/application.js b/app/javascript/application.js index 0d7b49404..946ac8d66 100644 --- a/app/javascript/application.js +++ b/app/javascript/application.js @@ -1,3 +1,8 @@ // Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails import "@hotwired/turbo-rails" import "controllers" +//map +import "mapkick/bundle" + + + diff --git a/app/javascript/controllers/flash_messages.js b/app/javascript/controllers/flash_messages.js new file mode 100644 index 000000000..db8d762e8 --- /dev/null +++ b/app/javascript/controllers/flash_messages.js @@ -0,0 +1,11 @@ +// window.onload = function() { +// setTimeout(function() { +// var noticeElement = document.getElementById('notice'); +// if (alertElement) { +// alertElement.style.display = 'none'; +// } +// if (noticeElement) { +// noticeElement.style.display = 'none'; +// } +// }, 5000); // 5000 milliseconds = 5 seconds +// }; \ No newline at end of file diff --git a/app/javascript/controllers/geolocation_controller.js b/app/javascript/controllers/geolocation_controller.js new file mode 100644 index 000000000..3f3a647e3 --- /dev/null +++ b/app/javascript/controllers/geolocation_controller.js @@ -0,0 +1,33 @@ +import { Controller } from "@hotwired/stimulus" + +const options = { + enableHighAccuracy: true, + timeout: 5000, + maximumAge: 0 +}; + +// Connects to data-controller="geolocation" +export default class extends Controller { + connect() { + } + + success(pos) { + const crd = pos.coords; + + console.log('Your current position is:'); + console.log(`Latitude : ${crd.latitude}`); + console.log(`Longitude: ${crd.longitude}`); + console.log(`More or less ${crd.accuracy} meters.`); + location.assign(`/locations?place=${crd.latitude},${crd.longitude}`) + } + + error(err) { + console.warn(`ERROR(${err.code}): ${err.message}`); + } + + search () { + navigator.geolocation.getCurrentPosition(this.success, this.error, options); + } + + +} \ No newline at end of file diff --git a/app/models/category.rb b/app/models/category.rb new file mode 100644 index 000000000..ac2224535 --- /dev/null +++ b/app/models/category.rb @@ -0,0 +1,5 @@ +class Category < ApplicationRecord + has_many :memberships + + +end diff --git a/app/models/location.rb b/app/models/location.rb new file mode 100644 index 000000000..d86a3a5c9 --- /dev/null +++ b/app/models/location.rb @@ -0,0 +1,4 @@ +class Location < ApplicationRecord + geocoded_by :address + after_validation :geocode, if: :address_changed? +end diff --git a/app/models/membership.rb b/app/models/membership.rb new file mode 100644 index 000000000..8ae5cdf86 --- /dev/null +++ b/app/models/membership.rb @@ -0,0 +1,4 @@ +class Membership < ApplicationRecord + belongs_to :category #annual, weekly, day, monthly + +end diff --git a/app/models/payment.rb b/app/models/payment.rb new file mode 100644 index 000000000..7dacef605 --- /dev/null +++ b/app/models/payment.rb @@ -0,0 +1,4 @@ +class Payment < ApplicationRecord + validates :credit_card_info, length: { minimum: 16, maximum: 16 } + validates_presence_of :amount +end diff --git a/app/models/rental.rb b/app/models/rental.rb new file mode 100644 index 000000000..52f6c325f --- /dev/null +++ b/app/models/rental.rb @@ -0,0 +1,5 @@ +class Rental < ApplicationRecord + validates_presence_of :rental_period, + :return_by + belongs_to :user, class_name: :User, foreign_key: :id, optional:true +end diff --git a/app/models/station.rb b/app/models/station.rb index 64b9eaada..58b6f9df4 100644 --- a/app/models/station.rb +++ b/app/models/station.rb @@ -2,8 +2,12 @@ class Station < ApplicationRecord validates_presence_of :identifier, :name, :address + validates_uniqueness_of :identifier has_many :docked_bikes, class_name: :Bike, foreign_key: :current_station_id end + + + diff --git a/app/models/user.rb b/app/models/user.rb new file mode 100644 index 000000000..15974200d --- /dev/null +++ b/app/models/user.rb @@ -0,0 +1,17 @@ +class User < ApplicationRecord + include ActiveModel::SecurePassword + # EMAIL_REGEX = /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/ + has_secure_password + has_secure_password :recovery_password, validations: false + + validates_presence_of :first_name, + :last_name, + :email_address + + validates_uniqueness_of :email_address + + has_one :current_rental, class_name: :Rental, foreign_key: :id + has_many :rentals, class_name: :Rental, foreign_key: :id + + # validates :email_address, format: {with: EMAIL_REGEX, message: "Email invalid" } +end diff --git a/app/views/bikes/_row.html.erb b/app/views/bikes/_row.html.erb new file mode 100644 index 000000000..352b43842 --- /dev/null +++ b/app/views/bikes/_row.html.erb @@ -0,0 +1,4 @@ +
Find me in app/views/categories/delete.html.erb
+Find me in app/views/categories/edit.html.erb
+Find me in app/views/categories/index.html.erb
+Find me in app/views/categories/show.html.erb
+This is where we should put some About info...or searching for a bike on the map
+ <%= link_to "Refer to the Figma visualization (click here)", "https://www.figma.com/file/jLAscgKzd4HPAfotfuieGu/ValetBike?type=design&node-id=0%3A1&mode=design&t=op9OSiDs7IVGALMT-1" %>There were problems with the following fields:
+