diff --git a/.DS_Store b/.DS_Store
new file mode 100644
index 000000000..7a3538865
Binary files /dev/null and b/.DS_Store differ
diff --git a/.gitignore b/.gitignore
index e16dc71d2..4476d4e13 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,7 +6,7 @@
# Ignore bundler config.
/.bundle
-
+/coverage
# Ignore all logfiles and tempfiles.
/log/*
/tmp/*
@@ -27,5 +27,8 @@
/public/assets
+# Ignore simplecov generated files
+/coverage
+
# Ignore master key for decrypting credentials and more.
/config/master.key
diff --git a/.rspec b/.rspec
new file mode 100644
index 000000000..c99d2e739
--- /dev/null
+++ b/.rspec
@@ -0,0 +1 @@
+--require spec_helper
diff --git a/.rubocop.yml b/.rubocop.yml
new file mode 100644
index 000000000..ac2c35581
--- /dev/null
+++ b/.rubocop.yml
@@ -0,0 +1,6 @@
+Metrics/BlockLength:
+ IgnoredMethods:
+ - RSpec.describe
+ - describe
+ - it
+ - context
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 000000000..4de4c5c6b
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,8 @@
+{
+ "cSpell.words": [
+ "Habenula",
+ "Sooyung",
+ "tahmid",
+ "tmdb"
+ ]
+}
\ No newline at end of file
diff --git a/Gemfile b/Gemfile
index a8a68a722..e645a5ec7 100644
--- a/Gemfile
+++ b/Gemfile
@@ -26,7 +26,8 @@ gem "stimulus-rails"
# Build JSON APIs with ease [https://github.com/rails/jbuilder]
gem "jbuilder"
-
+gem "faraday"
+gem 'bootstrap-datepicker-rails'
# Use Redis adapter to run Action Cable in production
# gem "redis", "~> 4.0"
@@ -34,7 +35,7 @@ gem "jbuilder"
# 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 ]
@@ -51,6 +52,12 @@ gem "bootsnap", require: false
group :development, :test do
# See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem
gem "pry"
+ gem "rspec-rails"
+ gem "capybara"
+ gem "launchy"
+ gem "simplecov"
+ gem "shoulda-matchers"
+
end
group :development do
@@ -66,8 +73,6 @@ group :development do
end
group :test do
- gem "rspec-rails"
- gem "capybara"
- gem "launchy"
- gem "simplecov"
+ gem "webmock"
+ gem "vcr"
end
\ No newline at end of file
diff --git a/Gemfile.lock b/Gemfile.lock
index b54ee32ad..380797565 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -69,9 +69,13 @@ GEM
addressable (2.8.4)
public_suffix (>= 2.0.2, < 6.0)
ast (2.4.2)
+ base64 (0.2.0)
+ bcrypt (3.1.20)
bindex (0.8.1)
bootsnap (1.16.0)
msgpack (~> 1.2)
+ bootstrap-datepicker-rails (1.10.0.1)
+ railties (>= 3.0)
builder (3.2.4)
capybara (3.39.2)
addressable
@@ -84,13 +88,21 @@ GEM
xpath (~> 3.2)
coderay (1.1.3)
concurrent-ruby (1.2.2)
+ crack (0.4.5)
+ rexml
crass (1.0.6)
date (3.3.3)
diff-lcs (1.5.0)
docile (1.4.0)
erubi (1.12.0)
+ faraday (2.7.12)
+ base64
+ faraday-net_http (>= 2.0, < 3.1)
+ ruby2_keywords (>= 0.0.4)
+ faraday-net_http (3.0.2)
globalid (1.1.0)
activesupport (>= 5.0)
+ hashdiff (1.0.1)
i18n (1.14.1)
concurrent-ruby (~> 1.0)
importmap-rails (1.2.1)
@@ -213,6 +225,9 @@ GEM
rack (>= 1.1)
rubocop (>= 1.33.0, < 2.0)
ruby-progressbar (1.13.0)
+ ruby2_keywords (0.0.5)
+ shoulda-matchers (5.3.0)
+ activesupport (>= 5.2.0)
simplecov (0.22.0)
docile (~> 1.1)
simplecov-html (~> 0.11)
@@ -237,11 +252,16 @@ GEM
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
unicode-display_width (2.4.2)
+ vcr (6.2.0)
web-console (4.2.0)
actionview (>= 6.0.0)
activemodel (>= 6.0.0)
bindex (>= 0.4.0)
railties (>= 6.0.0)
+ webmock (3.19.1)
+ addressable (>= 2.8.0)
+ crack (>= 0.3.2)
+ hashdiff (>= 0.4.0, < 2.0.0)
websocket-driver (0.7.5)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5)
@@ -254,8 +274,11 @@ PLATFORMS
x86_64-darwin-21
DEPENDENCIES
+ bcrypt (~> 3.1.7)
bootsnap
+ bootstrap-datepicker-rails
capybara
+ faraday
importmap-rails
jbuilder
launchy
@@ -265,12 +288,15 @@ DEPENDENCIES
rails (~> 7.0.4, >= 7.0.4.2)
rspec-rails
rubocop-rails
+ shoulda-matchers
simplecov
sprockets-rails
stimulus-rails
turbo-rails
tzinfo-data
+ vcr
web-console
+ webmock
RUBY VERSION
ruby 3.2.2p53
diff --git a/README.md b/README.md
index d3e4d498d..614480f84 100644
--- a/README.md
+++ b/README.md
@@ -20,3 +20,12 @@ Viewing Party Lite is an application in which users can explore movie options an
- Rails 7.0.6
Example wireframes to follow are found [here](https://backend.turing.edu/module3/projects/viewing_party_lite/wireframes)
+
+
+## Contributors
+
+- Brendan Bondurant
+- Paul Bennett
+- Sooyung Kim
+
+
diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css
index 288b9ab71..c17da1acf 100644
--- a/app/assets/stylesheets/application.css
+++ b/app/assets/stylesheets/application.css
@@ -13,3 +13,144 @@
*= require_tree .
*= require_self
*/
+
+body {
+ background-image: url("https://wallpapercave.com/wp/uQNQiZW.jpg");
+ background-repeat: no-repeat;
+ background-attachment: fixed;
+ background-size: cover;
+ margin: 0; /* Optional: Remove default body margin */
+ height: 100vh;
+}
+
+.content {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ color: rgb(46, 30, 29);
+ height: 100vh;
+ margin: 0;
+}
+
+.show_content {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ color: rgb(46, 30, 29);
+ height: 160vh;
+ margin: 0;
+}
+
+table {
+ width: 100%;
+ border: 1px solid;
+}
+
+html * {
+ font-family: monospace;
+}
+
+ul {
+ list-style-type: none;
+ margin: 0;
+ padding: 0;
+ overflow: hidden;
+ background-color: #333;
+}
+
+li {
+ float: left;
+}
+
+li a {
+ display: block;
+ color: white;
+ text-align: center;
+ padding: 14px 16px;
+ text-decoration: none;
+}
+
+li a:hover {
+ background-color: #111;
+}
+.register-container {
+ max-width: 600px; /* Adjust the maximum width as needed */
+ justify-content: center;
+ margin-left: 290px;
+}
+
+.register-form {
+ display: grid;
+ gap: 10px;
+ grid-template-columns: repeat(2, 1fr);
+}
+
+.register-form h2 {
+ grid-column: span 2; /* Make the heading span both columns */
+ text-align: center;
+}
+
+.register-form label {
+ display: block;
+}
+
+.register-form input {
+ width: 100%;
+ padding: 8px;
+ box-sizing: border-box;
+}
+
+.register-form br {
+ display: none; /* Hide line breaks to make styling consistent */
+}
+
+.register-form button {
+ grid-column: span 2; /* Make the button span both columns */
+ background-color: #4caf50;
+ color: white;
+ padding: 10px;
+ border: none;
+ border-radius: 5px;
+ cursor: pointer;
+}
+
+.flash_message {
+ font-size: 15px;
+ border: 2px solid #030303;
+ font-weight: bold;
+ padding: 5px;
+ text-align: center;
+}
+
+.error {
+ background-color: #f68080;
+ border-color: #f50a0a;
+}
+
+.success {
+ background-color: #80f6a3;
+ border-color: #0af54d;
+}
+
+.column {
+ margin: 0 auto; /* Center the column horizontally */
+ width: 50%;
+ padding: 1rem;
+}
+
+.row {
+ display: flex;
+ justify-content: space-between; /* Adjust as needed */
+ align-items: center; /* Adjust as needed */
+ padding: 10px;
+}
+
+.row > * {
+ margin-right: 10px; /* Adjust the margin as needed */
+}
+
+.row > *:last-child {
+ margin-right: 0; /* Remove margin for the last child to avoid unnecessary spacing */
+}
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 09705d12a..050f99773 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -1,2 +1,11 @@
class ApplicationController < ActionController::Base
+ helper_method :current_user
+
+ def index
+ @users = User.all
+ end
+
+ def current_user
+ @_current_user ||= User.find(session[:user_id]) if session[:user_id]
+ end
end
diff --git a/app/controllers/movies_controller.rb b/app/controllers/movies_controller.rb
new file mode 100644
index 000000000..aef0a6d9a
--- /dev/null
+++ b/app/controllers/movies_controller.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+class MoviesController < ApplicationController
+ def index # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
+ @user = User.find(params[:user_id])
+
+ if params[:top_movies] == 'top rated'
+ @facade = Top20Facade.new(params[:top_movies])
+ elsif params[:commit] == 'Find Movies'
+ if !params[:search].empty?
+ @facade = MovieSearchFacade.new(params[:search])
+ elsif params[:search].empty?
+ redirect_to discover_user_path(@user)
+ flash[:error] = "Please fill in with a movie title"
+ end
+ end
+ end
+
+ def show
+ @facade = MovieDetailsFacade.new(params[:id])
+ @user = User.find(params[:user_id])
+ end
+end
diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb
new file mode 100644
index 000000000..63fd0fe21
--- /dev/null
+++ b/app/controllers/sessions_controller.rb
@@ -0,0 +1,7 @@
+class SessionsController < ApplicationController
+ def destroy
+ session.clear
+ redirect_to root_path
+ flash[:success] = 'Logged Out'
+ end
+end
\ No newline at end of file
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
new file mode 100644
index 000000000..5faec42cc
--- /dev/null
+++ b/app/controllers/users_controller.rb
@@ -0,0 +1,71 @@
+class UsersController < ApplicationController
+ before_action :require_login, only: :show
+
+ def new
+ @user = User.new
+ end
+
+ def discover
+ @user = User.find(params[:id])
+ end
+
+ def show
+ @facade = UserFacade.new(params[:id])
+ @user = User.find(params[:id])
+ end
+
+ def create
+ new_user = User.new(user_params)
+
+ if new_user.save
+ session[:user_id] = new_user.id
+ create_welcome(new_user)
+ else
+ redirect_to register_path
+ flash[:error] = new_user.errors.full_messages.to_sentence
+ end
+ end
+
+ def login_form
+ end
+
+ def login_user
+ user = User.find_by(email: params[:email])
+ if user == nil
+ no_user
+ elsif user.authenticate(params[:password])
+ session[:user_id] = user.id
+ create_welcome(user)
+ else
+ bad_credential
+ end
+ end
+
+ private
+
+ def user_params
+ params.require(:user).permit(:name, :email, :password, :password_confirmation)
+ end
+
+ def create_welcome(user)
+ flash[:success] = "Welcome, #{user.name.titleize}!"
+ redirect_to user_path(user.id)
+ end
+
+ def bad_credential
+ redirect_to '/login'
+ flash[:error] = "Sorry, your credentials are bad."
+ end
+
+ def no_user
+ redirect_to '/login'
+ flash[:error] = "Please enter correct email and password"
+ end
+
+ def require_login
+ unless current_user
+ flash[:error] = 'You must be logged in or registered to access the dashboard'
+ redirect_to '/'
+ end
+ end
+end
\ No newline at end of file
diff --git a/app/controllers/viewing_party_controller.rb b/app/controllers/viewing_party_controller.rb
new file mode 100644
index 000000000..938a4997e
--- /dev/null
+++ b/app/controllers/viewing_party_controller.rb
@@ -0,0 +1,47 @@
+class ViewingPartyController < ApplicationController
+ before_action :require_login, only: :new
+
+ def new
+ @facade = MovieDetailsFacade.new(params[:movie_id])
+ @user = User.find(params[:user_id])
+ @users = User.all
+ end
+
+ def create
+ host = User.find(params[:id])
+ party = Party.new(party_params)
+ if party.save
+ host_of_party(host, party)
+ attendees_of_party(party)
+ redirect_to user_path(host)
+ else
+ redirect_to new_user_movie_viewing_party_path(host, params[:movie_id])
+ flash[:error] = 'Please fill out all field, duration, time and date of the party'
+ end
+ end
+
+ private
+
+ def party_params
+ params.permit(:movie_id, :duration_of_party, :party_date, :start_time)
+ end
+
+ def host_of_party(host, party)
+ PartyUser.create!(user_id: host.id, party_id: party.id, is_host: true)
+ end
+
+ def attendees_of_party(party)
+ unless params[:invites].nil?
+ params[:invites].map do |invite|
+ PartyUser.create!(user_id: invite, party_id: party.id)
+ end
+ end
+ end
+
+ def require_login
+ unless current_user
+ flash[:error] = 'You must be logged in or registered to create a movie party'
+ redirect_to "/users/#{params[:user_id]}/movies/#{params[:movie_id]}"
+ end
+ end
+end
\ No newline at end of file
diff --git a/app/facades/movie_details_facade.rb b/app/facades/movie_details_facade.rb
new file mode 100644
index 000000000..4c4dd0255
--- /dev/null
+++ b/app/facades/movie_details_facade.rb
@@ -0,0 +1,20 @@
+class MovieDetailsFacade
+
+ def initialize(movie_id)
+ @movie_id = movie_id
+ end
+
+ def full_details
+ service = MovieService.new
+ details = service.movie_details(@movie_id)
+ credits = service.get_credits(@movie_id)
+ reviews = service.get_reviews(@movie_id)
+ MovieDetails.new(details, credits, reviews)
+ end
+
+ def single_movie_details
+ service = MovieService.new
+ details = service.movie_details(@movie_id)
+ SingleMovieDetails.new(details)
+ end
+end
\ No newline at end of file
diff --git a/app/facades/movie_search_facade.rb b/app/facades/movie_search_facade.rb
new file mode 100644
index 000000000..04e824f7f
--- /dev/null
+++ b/app/facades/movie_search_facade.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+# Facade for movie search functionality
+
+class MovieSearchFacade
+ attr_reader :search_term, :movies
+
+ def initialize(search_term)
+ @search_term = search_term
+ @movies = search_results
+ end
+
+ def search_results
+ service = MovieSearchService.new
+ json = service.movie_search(@search_term)
+ json[:results].take(20).map do |movie|
+ MovieSearch.new(movie)
+ end
+ end
+end
diff --git a/app/facades/top20_facade.rb b/app/facades/top20_facade.rb
new file mode 100644
index 000000000..76831ca48
--- /dev/null
+++ b/app/facades/top20_facade.rb
@@ -0,0 +1,17 @@
+
+class Top20Facade
+ attr_reader :top_movies
+
+ def initialize(top_movies)
+ @top_movies = top_movies
+ @top20 = top20
+ end
+
+ def top20
+ service = Top20Service.new
+ json = service.top20
+ json[:results].map do |movie|
+ MovieSearch.new(movie)
+ end
+ end
+end
diff --git a/app/facades/user_facade.rb b/app/facades/user_facade.rb
new file mode 100644
index 000000000..93ae82761
--- /dev/null
+++ b/app/facades/user_facade.rb
@@ -0,0 +1,18 @@
+class UserFacade
+ attr_reader :user
+
+ def initialize(user_id)
+ @user = User.find(user_id)
+ end
+
+ def movie_poster_link(movie_id)
+ response = MovieService.new.movie_images(movie_id)
+ url = response[:posters].first[:file_path]
+ "https://image.tmdb.org/t/p/w185#{url}"
+ end
+
+ def get_movie_title(movie_id)
+ response = MovieService.new.movie_details(movie_id)
+ response[:title]
+ end
+end
diff --git a/app/models/party.rb b/app/models/party.rb
new file mode 100644
index 000000000..1e40d57ae
--- /dev/null
+++ b/app/models/party.rb
@@ -0,0 +1,19 @@
+class Party < ApplicationRecord
+ validates_presence_of :start_time, :party_date, :duration_of_party
+ has_many :party_users
+ has_many :users, through: :party_users
+
+ def get_host_name
+ Party.joins(:users)
+ .select('users.name')
+ .where('party_users.party_id = ? AND party_users.is_host = true', id)
+ .first.name
+ end
+
+ def get_guest_names
+ Party.joins(:users)
+ .select('users.name')
+ .where('party_users.party_id = ? AND party_users.is_host = false', id)
+ .pluck(:name)
+ end
+end
diff --git a/app/models/party_user.rb b/app/models/party_user.rb
new file mode 100644
index 000000000..6ffa96ee3
--- /dev/null
+++ b/app/models/party_user.rb
@@ -0,0 +1,6 @@
+class PartyUser < ApplicationRecord
+ validates_presence_of :party,
+ :user
+ belongs_to :party
+ belongs_to :user
+end
diff --git a/app/models/user.rb b/app/models/user.rb
new file mode 100644
index 000000000..4e6f300e3
--- /dev/null
+++ b/app/models/user.rb
@@ -0,0 +1,25 @@
+class User < ApplicationRecord
+ validates_presence_of :name
+ validates :email, presence: true, uniqueness: { case_sensitive: false }
+ validates_presence_of :password
+ validates_presence_of :password_confirmation
+
+ has_secure_password
+
+ has_many :party_users
+ has_many :parties, through: :party_users
+
+ def hosted_parties
+ Party.joins(:party_users)
+ .where('party_users.user_id = ? AND party_users.is_host = true', id)
+ end
+
+ def invited_parties
+ Party.joins(:party_users)
+ .where('party_users.user_id = ? AND party_users.is_host = false', id)
+ end
+
+ def self.all_excluding_id(id)
+ User.where.not('id = ?', id)
+ end
+end
diff --git a/app/poros/movie_details.rb b/app/poros/movie_details.rb
new file mode 100644
index 000000000..673e7917c
--- /dev/null
+++ b/app/poros/movie_details.rb
@@ -0,0 +1,25 @@
+class MovieDetails
+ attr_reader :title,
+ :vote_average,
+ :runtime,
+ :genres,
+ :summary,
+ :cast,
+ :total_reviews,
+ :reviews
+
+ def initialize(details, credits, reviews)
+ @title = details[:title]
+ @vote_average = details[:vote_average]
+ @runtime = details[:runtime]
+ @genres = details[:genres]
+ @summary = details[:overview]
+ @cast = credits[:cast].take(10)
+ @total_reviews = reviews[:total_results]
+ @reviews = reviews[:results]
+ end
+
+ def format_runtime
+ "#{@runtime / 60}h #{@runtime % 60}m"
+ end
+end
diff --git a/app/poros/movie_search.rb b/app/poros/movie_search.rb
new file mode 100644
index 000000000..395fe5857
--- /dev/null
+++ b/app/poros/movie_search.rb
@@ -0,0 +1,9 @@
+class MovieSearch
+ attr_reader :search_term, :title, :vote_average, :id
+ def initialize(search_term)
+ @search_term = search_term
+ @title = search_term[:title]
+ @vote_average = search_term[:vote_average]
+ @id = search_term[:id]
+ end
+end
diff --git a/app/poros/single_movie_details.rb b/app/poros/single_movie_details.rb
new file mode 100644
index 000000000..e3752c75e
--- /dev/null
+++ b/app/poros/single_movie_details.rb
@@ -0,0 +1,11 @@
+class SingleMovieDetails
+ attr_reader :movie_title,
+ :runtime,
+ :id
+
+ def initialize(attributes)
+ @movie_title = attributes[:title]
+ @runtime = attributes[:runtime]
+ @id = attributes[:id]
+ end
+end
diff --git a/app/poros/top20.rb b/app/poros/top20.rb
new file mode 100644
index 000000000..135b57192
--- /dev/null
+++ b/app/poros/top20.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class Top20
+ def initialize(movie)
+ @movie = movie
+ end
+end
diff --git a/app/services/movie_search_service.rb b/app/services/movie_search_service.rb
new file mode 100644
index 000000000..981cb0eb0
--- /dev/null
+++ b/app/services/movie_search_service.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+class MovieSearchService
+ def movie_search(search_term)
+ get_url("/3/search/movie?query=#{search_term}")
+ end
+
+ def conn
+ Faraday.new(url: 'https://api.themoviedb.org') do |faraday|
+ faraday.params['api_key'] = Rails.application.credentials.tmdb[:key]
+ end
+ end
+
+ def get_url(url)
+ response = conn.get(url)
+ JSON.parse(response.body, symbolize_names: true)
+ end
+end
diff --git a/app/services/movie_service.rb b/app/services/movie_service.rb
new file mode 100644
index 000000000..2ae8ec541
--- /dev/null
+++ b/app/services/movie_service.rb
@@ -0,0 +1,29 @@
+class MovieService
+
+ def get_url(url)
+ response = conn.get(url)
+ JSON.parse(response.body, symbolize_names: true)
+ end
+
+ def conn
+ Faraday.new(url: 'https://api.themoviedb.org') do |faraday|
+ faraday.params['api_key'] = Rails.application.credentials.tmdb[:key]
+ end
+ end
+
+ def movie_details(id)
+ get_url("/3/movie/#{id}")
+ end
+
+ def get_credits(id)
+ get_url("/3/movie/#{id}/credits")
+ end
+
+ def get_reviews(id)
+ get_url("/3/movie/#{id}/reviews")
+ end
+
+ def movie_images(id)
+ get_url("/3/movie/#{id}/images")
+ end
+end
diff --git a/app/services/top20_service.rb b/app/services/top20_service.rb
new file mode 100644
index 000000000..0f6c619e6
--- /dev/null
+++ b/app/services/top20_service.rb
@@ -0,0 +1,17 @@
+
+class Top20Service
+ def top20
+ get_url('/3/movie/top_rated')
+ end
+
+ def conn
+ Faraday.new(url: 'https://api.themoviedb.org') do |faraday|
+ faraday.params['api_key'] = Rails.application.credentials.tmdb[:key]
+ end
+ end
+
+ def get_url(url)
+ response = conn.get(url)
+ JSON.parse(response.body, symbolize_names: true)
+ end
+end
diff --git a/app/views/application/index.html.erb b/app/views/application/index.html.erb
new file mode 100644
index 000000000..d97fb16eb
--- /dev/null
+++ b/app/views/application/index.html.erb
@@ -0,0 +1,20 @@
+
+
+
+
Viewing Party
+ <% if current_user %>
+ <%= link_to "Log Out", logout_path, method: :delete, data: {turbo_method: :delete} %>
+
Existing Users
+ <% @users.each do |user| %>
+
<%= user.email %>
+ <% end %>
+ <% elsif current_user.nil? %>
+ <%= button_to "Create a New User", register_path, method: :get %>
or
<%= button_to "Log In", login_path, method: :get %>
+ <% end %>
+
\ No newline at end of file
diff --git a/app/views/application/login_form.html.erb b/app/views/application/login_form.html.erb
new file mode 100644
index 000000000..cc93659a2
--- /dev/null
+++ b/app/views/application/login_form.html.erb
@@ -0,0 +1,15 @@
+
+
+
+
+
Log In
+ <%= form_with url: login_path, method: :post do |form| %>
+ <%= form.label :email, "Email:" %>
+ <%= form.text_field :email %>
+ <%= form.label :password, "Password:" %>
+ <%= form.password_field :password %>
+ <%= form.submit "Log In" %>
+ <% end %>
+
\ No newline at end of file
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index 552042a39..b9d6706e8 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -8,9 +8,16 @@
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
<%= javascript_importmap_tags %>
+
+
+ <% flash.each do |type, msg| %>
+
+ <%= msg %>
+
+ <% end %>
<%= yield %>