diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 4eb57e0..10e5a25 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -5,7 +5,11 @@ - + + + + + diff --git a/Gemfile b/Gemfile index 9efd3bf..d4bb5fa 100644 --- a/Gemfile +++ b/Gemfile @@ -45,6 +45,9 @@ gem "tzinfo-data", platforms: %i[ windows jruby ] gem "bootsnap", require: false +gem 'stimulus-rails' +gem "hotwire_combobox" + # Use Active Storage variants [https://guides.rubyonrails.org/active_storage_overview.html#transforming-images] # gem "image_processing", "~> 1.2" diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 09705d1..8b6a04c 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,2 +1,9 @@ class ApplicationController < ActionController::Base + + private + def set_company + company_id = session.fetch(:company_id, Company.first&.id) + session[:company_id] = company_id + @company = Company.find(session[:company_id]) + end end diff --git a/app/controllers/customers_controller.rb b/app/controllers/customers_controller.rb new file mode 100644 index 0000000..4c7eadf --- /dev/null +++ b/app/controllers/customers_controller.rb @@ -0,0 +1,72 @@ +class CustomersController < ApplicationController + before_action :set_company + before_action :set_customer, only: %i[ show edit update destroy ] + + # GET /customers or /customers.json + def index + @customers = Customer.all + end + + # GET /customers/1 or /customers/1.json + def show + end + + # GET /customers/new + def new + @customer = Customer.new + end + + # GET /customers/1/edit + def edit + end + + # POST /customers or /customers.json + def create + @customer = Customer.new(customer_params) + @customer.company = @company + + respond_to do |format| + if @customer.save + format.html { redirect_to customer_url(@customer), notice: "Customer was successfully created." } + format.json { render :show, status: :created, location: @customer } + else + format.html { render :new, status: :unprocessable_entity } + format.json { render json: @customer.errors, status: :unprocessable_entity } + end + end + end + + # PATCH/PUT /customers/1 or /customers/1.json + def update + respond_to do |format| + if @customer.update(customer_params) + format.html { redirect_to customer_url(@customer), notice: "Customer was successfully updated." } + format.json { render :show, status: :ok, location: @customer } + else + format.html { render :edit, status: :unprocessable_entity } + format.json { render json: @customer.errors, status: :unprocessable_entity } + end + end + end + + # DELETE /customers/1 or /customers/1.json + def destroy + @customer.destroy! + + respond_to do |format| + format.html { redirect_to customers_url, notice: "Customer was successfully destroyed." } + format.json { head :no_content } + end + end + + private + # Use callbacks to share common setup or constraints between actions. + def set_customer + @customer = Customer.find(params[:id]) + end + + # Only allow a list of trusted parameters through. + def customer_params + params.require(:customer).permit(:name, :phone, :notes, :email, :birthyear) + end +end diff --git a/app/controllers/places_controller.rb b/app/controllers/places_controller.rb new file mode 100644 index 0000000..ed7d68c --- /dev/null +++ b/app/controllers/places_controller.rb @@ -0,0 +1,72 @@ +class PlacesController < ApplicationController + before_action :set_company + before_action :set_place, only: %i[ show edit update destroy ] + + # GET /places or /places.json + def index + @places = Place.all + end + + # GET /places/1 or /places/1.json + def show + end + + # GET /places/new + def new + @place = Place.new + end + + # GET /places/1/edit + def edit + end + + # POST /places or /places.json + def create + @place = Place.new(place_params) + @place.company = @company + + respond_to do |format| + if @place.save + format.html { redirect_to place_url(@place), notice: "Place was successfully created." } + format.json { render :show, status: :created, location: @place } + else + format.html { render :new, status: :unprocessable_entity } + format.json { render json: @place.errors, status: :unprocessable_entity } + end + end + end + + # PATCH/PUT /places/1 or /places/1.json + def update + respond_to do |format| + if @place.update(place_params) + format.html { redirect_to place_url(@place), notice: "Place was successfully updated." } + format.json { render :show, status: :ok, location: @place } + else + format.html { render :edit, status: :unprocessable_entity } + format.json { render json: @place.errors, status: :unprocessable_entity } + end + end + end + + # DELETE /places/1 or /places/1.json + def destroy + @place.destroy! + + respond_to do |format| + format.html { redirect_to places_url, notice: "Place was successfully destroyed." } + format.json { head :no_content } + end + end + + private + # Use callbacks to share common setup or constraints between actions. + def set_place + @place = Place.find(params[:id]) + end + + # Only allow a list of trusted parameters through. + def place_params + params.require(:place).permit(:name, :company_id) + end +end diff --git a/app/controllers/reservations_controller.rb b/app/controllers/reservations_controller.rb new file mode 100644 index 0000000..4012eb0 --- /dev/null +++ b/app/controllers/reservations_controller.rb @@ -0,0 +1,73 @@ +class ReservationsController < ApplicationController + before_action :set_company + before_action :set_reservation, only: %i[ show edit update destroy ] + + # GET /reservations or /reservations.json + def index + @reservations = Reservation.all + end + + # GET /reservations/1 or /reservations/1.json + def show + end + + # GET /reservations/new + def new + @reservation = Reservation.new + @reservation.place = @company.places.first + end + + # GET /reservations/1/edit + def edit + end + + # POST /reservations or /reservations.json + def create + @reservation = Reservation.new(reservation_params) + @reservation.company = @company + + respond_to do |format| + if @reservation.save + format.html { redirect_to reservation_url(@reservation), notice: "Reservation was successfully created." } + format.json { render :show, status: :created, location: @reservation } + else + format.html { render :new, status: :unprocessable_entity } + format.json { render json: @reservation.errors, status: :unprocessable_entity } + end + end + end + + # PATCH/PUT /reservations/1 or /reservations/1.json + def update + respond_to do |format| + if @reservation.update(reservation_params) + format.html { redirect_to reservation_url(@reservation), notice: "Reservation was successfully updated." } + format.json { render :show, status: :ok, location: @reservation } + else + format.html { render :edit, status: :unprocessable_entity } + format.json { render json: @reservation.errors, status: :unprocessable_entity } + end + end + end + + # DELETE /reservations/1 or /reservations/1.json + def destroy + @reservation.destroy! + + respond_to do |format| + format.html { redirect_to reservations_url, notice: "Reservation was successfully destroyed." } + format.json { head :no_content } + end + end + + private + # Use callbacks to share common setup or constraints between actions. + def set_reservation + @reservation = Reservation.find(params[:id]) + end + + # Only allow a list of trusted parameters through. + def reservation_params + params.require(:reservation).permit(:company_id, :customer_id, :place_id, :title, :description, :start_time, :end_time) + end +end diff --git a/app/helpers/customers_helper.rb b/app/helpers/customers_helper.rb new file mode 100644 index 0000000..a07ce29 --- /dev/null +++ b/app/helpers/customers_helper.rb @@ -0,0 +1,2 @@ +module CustomersHelper +end diff --git a/app/helpers/places_helper.rb b/app/helpers/places_helper.rb new file mode 100644 index 0000000..7d8d0ac --- /dev/null +++ b/app/helpers/places_helper.rb @@ -0,0 +1,2 @@ +module PlacesHelper +end diff --git a/app/helpers/reservations_helper.rb b/app/helpers/reservations_helper.rb new file mode 100644 index 0000000..f28b699 --- /dev/null +++ b/app/helpers/reservations_helper.rb @@ -0,0 +1,2 @@ +module ReservationsHelper +end diff --git a/app/models/company.rb b/app/models/company.rb index a149860..baff233 100644 --- a/app/models/company.rb +++ b/app/models/company.rb @@ -1,2 +1,5 @@ class Company < ApplicationRecord + has_many :customers, dependent: :destroy + has_many :reservations, dependent: :destroy + has_many :places, dependent: :destroy end diff --git a/app/models/customer.rb b/app/models/customer.rb new file mode 100644 index 0000000..ebc5777 --- /dev/null +++ b/app/models/customer.rb @@ -0,0 +1,7 @@ +class Customer < ApplicationRecord + belongs_to :company + + validates :name, presence: true, uniqueness: { scope: :company_id } + validates :phone, presence: true + validates :company_id, presence: true +end diff --git a/app/models/place.rb b/app/models/place.rb new file mode 100644 index 0000000..ab192e4 --- /dev/null +++ b/app/models/place.rb @@ -0,0 +1,3 @@ +class Place < ApplicationRecord + belongs_to :company +end diff --git a/app/models/reservation.rb b/app/models/reservation.rb new file mode 100644 index 0000000..93c1b16 --- /dev/null +++ b/app/models/reservation.rb @@ -0,0 +1,9 @@ +class Reservation < ApplicationRecord + belongs_to :company + belongs_to :customer + belongs_to :place + + validates :company_id, presence: true + validates :customer_id, presence: true + validates :place_id, presence: true +end diff --git a/app/views/customers/_customer.html.erb b/app/views/customers/_customer.html.erb new file mode 100644 index 0000000..0957736 --- /dev/null +++ b/app/views/customers/_customer.html.erb @@ -0,0 +1,27 @@ +
+

+ Name: + <%= customer.name %> +

+ +

+ Phone: + <%= customer.phone %> +

+ +

+ Notes: + <%= customer.notes %> +

+ +

+ Email: + <%= customer.email %> +

+ +

+ Birthyear: + <%= customer.birthyear %> +

+ +
diff --git a/app/views/customers/_customer.json.jbuilder b/app/views/customers/_customer.json.jbuilder new file mode 100644 index 0000000..910c03d --- /dev/null +++ b/app/views/customers/_customer.json.jbuilder @@ -0,0 +1,2 @@ +json.extract! customer, :id, :name, :phone, :notes, :email, :birthyear, :created_at, :updated_at +json.url customer_url(customer, format: :json) diff --git a/app/views/customers/_form.html.erb b/app/views/customers/_form.html.erb new file mode 100644 index 0000000..63b5b59 --- /dev/null +++ b/app/views/customers/_form.html.erb @@ -0,0 +1,42 @@ +<%= form_with(model: customer, class: "contents") do |form| %> + <% if customer.errors.any? %> +
+

<%= pluralize(customer.errors.count, "error") %> prohibited this customer from being saved:

+ + +
+ <% end %> + +
+ <%= form.label :name %> + <%= form.text_field :name, class: "block shadow rounded-md border border-gray-400 outline-none px-3 py-2 mt-2 w-full" %> +
+ +
+ <%= form.label :phone %> + <%= form.text_field :phone, class: "block shadow rounded-md border border-gray-400 outline-none px-3 py-2 mt-2 w-full" %> +
+ +
+ <%= form.label :notes %> + <%= form.text_area :notes, rows: 4, class: "block shadow rounded-md border border-gray-400 outline-none px-3 py-2 mt-2 w-full" %> +
+ +
+ <%= form.label :email %> + <%= form.text_field :email, class: "block shadow rounded-md border border-gray-400 outline-none px-3 py-2 mt-2 w-full" %> +
+ +
+ <%= form.label :birthyear %> + <%= form.number_field :birthyear, class: "block shadow rounded-md border border-gray-400 outline-none px-3 py-2 mt-2 w-full" %> +
+ +
+ <%= form.submit class: "rounded-lg py-3 px-5 bg-blue-600 text-white inline-block font-medium cursor-pointer" %> +
+<% end %> diff --git a/app/views/customers/edit.html.erb b/app/views/customers/edit.html.erb new file mode 100644 index 0000000..aab356b --- /dev/null +++ b/app/views/customers/edit.html.erb @@ -0,0 +1,8 @@ +
+

Editing customer

+ + <%= render "form", customer: @customer %> + + <%= link_to "Show this customer", @customer, class: "ml-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium" %> + <%= link_to "Back to customers", customers_path, class: "ml-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium" %> +
diff --git a/app/views/customers/index.html.erb b/app/views/customers/index.html.erb new file mode 100644 index 0000000..20d5c7d --- /dev/null +++ b/app/views/customers/index.html.erb @@ -0,0 +1,21 @@ +
+ <% if notice.present? %> +

<%= notice %>

+ <% end %> + + <% content_for :title, "Customers" %> + +
+

Customers

+ <%= link_to "New customer", new_customer_path, class: "rounded-lg py-3 px-5 bg-blue-600 text-white block font-medium" %> +
+ +
+ <% @customers.each do |customer| %> + <%= render customer %> +

+ <%= link_to "Show this customer", customer, class: "ml-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium" %> +

+ <% end %> +
+
diff --git a/app/views/customers/index.json.jbuilder b/app/views/customers/index.json.jbuilder new file mode 100644 index 0000000..328edbd --- /dev/null +++ b/app/views/customers/index.json.jbuilder @@ -0,0 +1 @@ +json.array! @customers, partial: "customers/customer", as: :customer diff --git a/app/views/customers/new.html.erb b/app/views/customers/new.html.erb new file mode 100644 index 0000000..9f3026e --- /dev/null +++ b/app/views/customers/new.html.erb @@ -0,0 +1,7 @@ +
+

New customer

+ + <%= render "form", customer: @customer %> + + <%= link_to "Back to customers", customers_path, class: "ml-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium" %> +
diff --git a/app/views/customers/show.html.erb b/app/views/customers/show.html.erb new file mode 100644 index 0000000..585ba4f --- /dev/null +++ b/app/views/customers/show.html.erb @@ -0,0 +1,15 @@ +
+
+ <% if notice.present? %> +

<%= notice %>

+ <% end %> + + <%= render @customer %> + + <%= link_to "Edit this customer", edit_customer_path(@customer), class: "mt-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium" %> + <%= link_to "Back to customers", customers_path, class: "ml-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium" %> +
+ <%= button_to "Destroy this customer", @customer, method: :delete, class: "mt-2 rounded-lg py-3 px-5 bg-gray-100 font-medium" %> +
+
+
diff --git a/app/views/customers/show.json.jbuilder b/app/views/customers/show.json.jbuilder new file mode 100644 index 0000000..14cfc83 --- /dev/null +++ b/app/views/customers/show.json.jbuilder @@ -0,0 +1 @@ +json.partial! "customers/customer", customer: @customer diff --git a/app/views/places/_form.html.erb b/app/views/places/_form.html.erb new file mode 100644 index 0000000..f51e1c7 --- /dev/null +++ b/app/views/places/_form.html.erb @@ -0,0 +1,22 @@ +<%= form_with(model: place, class: "contents") do |form| %> + <% if place.errors.any? %> +
+

<%= pluralize(place.errors.count, "error") %> prohibited this place from being saved:

+ + +
+ <% end %> + +
+ <%= form.label :name %> + <%= form.text_field :name, class: "block shadow rounded-md border border-gray-400 outline-none px-3 py-2 mt-2 w-full" %> +
+ +
+ <%= form.submit class: "rounded-lg py-3 px-5 bg-blue-600 text-white inline-block font-medium cursor-pointer" %> +
+<% end %> diff --git a/app/views/places/_place.html.erb b/app/views/places/_place.html.erb new file mode 100644 index 0000000..30aa3a9 --- /dev/null +++ b/app/views/places/_place.html.erb @@ -0,0 +1,12 @@ +
+

+ Name: + <%= place.name %> +

+ +

+ Company: + <%= place.company_id %> +

+ +
diff --git a/app/views/places/_place.json.jbuilder b/app/views/places/_place.json.jbuilder new file mode 100644 index 0000000..ff5cba9 --- /dev/null +++ b/app/views/places/_place.json.jbuilder @@ -0,0 +1,2 @@ +json.extract! place, :id, :name, :company_id, :created_at, :updated_at +json.url place_url(place, format: :json) diff --git a/app/views/places/edit.html.erb b/app/views/places/edit.html.erb new file mode 100644 index 0000000..b0ff29d --- /dev/null +++ b/app/views/places/edit.html.erb @@ -0,0 +1,8 @@ +
+

Editing place

+ + <%= render "form", place: @place %> + + <%= link_to "Show this place", @place, class: "ml-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium" %> + <%= link_to "Back to places", places_path, class: "ml-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium" %> +
diff --git a/app/views/places/index.html.erb b/app/views/places/index.html.erb new file mode 100644 index 0000000..3dfe864 --- /dev/null +++ b/app/views/places/index.html.erb @@ -0,0 +1,21 @@ +
+ <% if notice.present? %> +

<%= notice %>

+ <% end %> + + <% content_for :title, "Places" %> + +
+

Places

+ <%= link_to "New place", new_place_path, class: "rounded-lg py-3 px-5 bg-blue-600 text-white block font-medium" %> +
+ +
+ <% @places.each do |place| %> + <%= render place %> +

+ <%= link_to "Show this place", place, class: "ml-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium" %> +

+ <% end %> +
+
diff --git a/app/views/places/index.json.jbuilder b/app/views/places/index.json.jbuilder new file mode 100644 index 0000000..f1d6b30 --- /dev/null +++ b/app/views/places/index.json.jbuilder @@ -0,0 +1 @@ +json.array! @places, partial: "places/place", as: :place diff --git a/app/views/places/new.html.erb b/app/views/places/new.html.erb new file mode 100644 index 0000000..c7048cf --- /dev/null +++ b/app/views/places/new.html.erb @@ -0,0 +1,7 @@ +
+

New place

+ + <%= render "form", place: @place %> + + <%= link_to "Back to places", places_path, class: "ml-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium" %> +
diff --git a/app/views/places/show.html.erb b/app/views/places/show.html.erb new file mode 100644 index 0000000..117e226 --- /dev/null +++ b/app/views/places/show.html.erb @@ -0,0 +1,15 @@ +
+
+ <% if notice.present? %> +

<%= notice %>

+ <% end %> + + <%= render @place %> + + <%= link_to "Edit this place", edit_place_path(@place), class: "mt-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium" %> + <%= link_to "Back to places", places_path, class: "ml-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium" %> +
+ <%= button_to "Destroy this place", @place, method: :delete, class: "mt-2 rounded-lg py-3 px-5 bg-gray-100 font-medium" %> +
+
+
diff --git a/app/views/places/show.json.jbuilder b/app/views/places/show.json.jbuilder new file mode 100644 index 0000000..e038dff --- /dev/null +++ b/app/views/places/show.json.jbuilder @@ -0,0 +1 @@ +json.partial! "places/place", place: @place diff --git a/app/views/reservations/_form.html.erb b/app/views/reservations/_form.html.erb new file mode 100644 index 0000000..0335a9c --- /dev/null +++ b/app/views/reservations/_form.html.erb @@ -0,0 +1,47 @@ +<%= form_with(model: reservation, class: "contents") do |form| %> + <% if reservation.errors.any? %> +
+

<%= pluralize(reservation.errors.count, "error") %> prohibited this reservation from being saved:

+ + +
+ <% end %> + +
+ <%= form.label :customer_id %> + <%= form.collection_select :customer_id, class: "block shadow rounded-md border border-gray-400 outline-none px-3 py-2 mt-2 w-full" %> +
+ +
+ <%= form.label :place_id %> + <%= form.collection_select :place_id, @company.places, :id, :name, prompt: "Select a Place", class:"block shadow rounded-md border border-gray-400 outline-none px-3 py-2 mt-2 w-full" %> +
+ +
+ <%= form.label :title %> + <%= form.text_field :title, class: "block shadow rounded-md border border-gray-400 outline-none px-3 py-2 mt-2 w-full" %> +
+ +
+ <%= form.label :description %> + <%= form.text_area :description, rows: 4, class: "block shadow rounded-md border border-gray-400 outline-none px-3 py-2 mt-2 w-full" %> +
+ +
+ <%= form.label :start_time %>` + <%= form.datetime_field :start_time, class: "block shadow rounded-md border border-gray-400 outline-none px-3 py-2 mt-2 w-full" %> +
+ +
+ <%= form.label :end_time %> + <%= form.datetime_field :end_time, class: "block shadow rounded-md border border-gray-400 outline-none px-3 py-2 mt-2 w-full" %> +
+ +
+ <%= form.submit class: "rounded-lg py-3 px-5 bg-blue-600 text-white inline-block font-medium cursor-pointer" %> +
+<% end %> diff --git a/app/views/reservations/_reservation.html.erb b/app/views/reservations/_reservation.html.erb new file mode 100644 index 0000000..1187b42 --- /dev/null +++ b/app/views/reservations/_reservation.html.erb @@ -0,0 +1,37 @@ +
+

+ Company: + <%= reservation.company_id %> +

+ +

+ Customer: + <%= reservation.customer_id %> +

+ +

+ Place: + <%= reservation.place_id %> +

+ +

+ Title: + <%= reservation.title %> +

+ +

+ Description: + <%= reservation.description %> +

+ +

+ Start time: + <%= reservation.start_time %> +

+ +

+ End time: + <%= reservation.end_time %> +

+ +
diff --git a/app/views/reservations/_reservation.json.jbuilder b/app/views/reservations/_reservation.json.jbuilder new file mode 100644 index 0000000..83db571 --- /dev/null +++ b/app/views/reservations/_reservation.json.jbuilder @@ -0,0 +1,2 @@ +json.extract! reservation, :id, :company_id, :customer_id, :place_id, :title, :description, :start_time, :end_time, :created_at, :updated_at +json.url reservation_url(reservation, format: :json) diff --git a/app/views/reservations/edit.html.erb b/app/views/reservations/edit.html.erb new file mode 100644 index 0000000..05edde3 --- /dev/null +++ b/app/views/reservations/edit.html.erb @@ -0,0 +1,8 @@ +
+

Editing reservation

+ + <%= render "form", reservation: @reservation %> + + <%= link_to "Show this reservation", @reservation, class: "ml-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium" %> + <%= link_to "Back to reservations", reservations_path, class: "ml-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium" %> +
diff --git a/app/views/reservations/index.html.erb b/app/views/reservations/index.html.erb new file mode 100644 index 0000000..9410147 --- /dev/null +++ b/app/views/reservations/index.html.erb @@ -0,0 +1,21 @@ +
+ <% if notice.present? %> +

<%= notice %>

+ <% end %> + + <% content_for :title, "Reservations" %> + +
+

Reservations

+ <%= link_to "New reservation", new_reservation_path, class: "rounded-lg py-3 px-5 bg-blue-600 text-white block font-medium" %> +
+ +
+ <% @reservations.each do |reservation| %> + <%= render reservation %> +

+ <%= link_to "Show this reservation", reservation, class: "ml-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium" %> +

+ <% end %> +
+
diff --git a/app/views/reservations/index.json.jbuilder b/app/views/reservations/index.json.jbuilder new file mode 100644 index 0000000..14b6b3c --- /dev/null +++ b/app/views/reservations/index.json.jbuilder @@ -0,0 +1 @@ +json.array! @reservations, partial: "reservations/reservation", as: :reservation diff --git a/app/views/reservations/new.html.erb b/app/views/reservations/new.html.erb new file mode 100644 index 0000000..9c7b7c5 --- /dev/null +++ b/app/views/reservations/new.html.erb @@ -0,0 +1,7 @@ +
+

New reservation

+ + <%= render "form", reservation: @reservation %> + + <%= link_to "Back to reservations", reservations_path, class: "ml-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium" %> +
diff --git a/app/views/reservations/show.html.erb b/app/views/reservations/show.html.erb new file mode 100644 index 0000000..46c1665 --- /dev/null +++ b/app/views/reservations/show.html.erb @@ -0,0 +1,15 @@ +
+
+ <% if notice.present? %> +

<%= notice %>

+ <% end %> + + <%= render @reservation %> + + <%= link_to "Edit this reservation", edit_reservation_path(@reservation), class: "mt-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium" %> + <%= link_to "Back to reservations", reservations_path, class: "ml-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium" %> +
+ <%= button_to "Destroy this reservation", @reservation, method: :delete, class: "mt-2 rounded-lg py-3 px-5 bg-gray-100 font-medium" %> +
+
+
diff --git a/app/views/reservations/show.json.jbuilder b/app/views/reservations/show.json.jbuilder new file mode 100644 index 0000000..f6e6ba5 --- /dev/null +++ b/app/views/reservations/show.json.jbuilder @@ -0,0 +1 @@ +json.partial! "reservations/reservation", reservation: @reservation diff --git a/config/routes.rb b/config/routes.rb index 373c702..073193e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,4 +1,7 @@ Rails.application.routes.draw do + resources :reservations + resources :places + resources :customers resources :companies # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html diff --git a/db/migrate/20240804052139_create_customers.rb b/db/migrate/20240804052139_create_customers.rb new file mode 100644 index 0000000..7a59569 --- /dev/null +++ b/db/migrate/20240804052139_create_customers.rb @@ -0,0 +1,13 @@ +class CreateCustomers < ActiveRecord::Migration[7.1] + def change + create_table :customers do |t| + t.string :name + t.string :phone + t.text :notes + t.string :email + t.integer :birthyear + + t.timestamps + end + end +end diff --git a/db/migrate/20240804053208_add_company_id_to_customers.rb b/db/migrate/20240804053208_add_company_id_to_customers.rb new file mode 100644 index 0000000..fcc0ce9 --- /dev/null +++ b/db/migrate/20240804053208_add_company_id_to_customers.rb @@ -0,0 +1,5 @@ +class AddCompanyIdToCustomers < ActiveRecord::Migration[7.1] + def change + add_column :customers, :company_id, :integer + end +end diff --git a/db/migrate/20240804060103_create_places.rb b/db/migrate/20240804060103_create_places.rb new file mode 100644 index 0000000..2104f25 --- /dev/null +++ b/db/migrate/20240804060103_create_places.rb @@ -0,0 +1,10 @@ +class CreatePlaces < ActiveRecord::Migration[7.1] + def change + create_table :places do |t| + t.string :name + t.references :company, null: false, foreign_key: true + + t.timestamps + end + end +end diff --git a/db/migrate/20240804060112_create_reservations.rb b/db/migrate/20240804060112_create_reservations.rb new file mode 100644 index 0000000..8298f92 --- /dev/null +++ b/db/migrate/20240804060112_create_reservations.rb @@ -0,0 +1,15 @@ +class CreateReservations < ActiveRecord::Migration[7.1] + def change + create_table :reservations do |t| + t.references :company, null: false, foreign_key: true + t.references :customer, null: false, foreign_key: true + t.references :place, null: false, foreign_key: true + t.string :title + t.text :description + t.datetime :start_time + t.datetime :end_time + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 44c6331..4269b72 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2024_05_18_200749) do +ActiveRecord::Schema[7.1].define(version: 2024_08_04_060112) do create_table "companies", force: :cascade do |t| t.string "name" t.string "id_number" @@ -25,4 +25,42 @@ ActiveRecord::Schema[7.1].define(version: 2024_05_18_200749) do t.datetime "updated_at", null: false end + create_table "customers", force: :cascade do |t| + t.string "name" + t.string "phone" + t.text "notes" + t.string "email" + t.integer "birthyear" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "company_id" + end + + create_table "places", force: :cascade do |t| + t.string "name" + t.integer "company_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["company_id"], name: "index_places_on_company_id" + end + + create_table "reservations", force: :cascade do |t| + t.integer "company_id", null: false + t.integer "customer_id", null: false + t.integer "place_id", null: false + t.string "title" + t.text "description" + t.datetime "start_time" + t.datetime "end_time" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["company_id"], name: "index_reservations_on_company_id" + t.index ["customer_id"], name: "index_reservations_on_customer_id" + t.index ["place_id"], name: "index_reservations_on_place_id" + end + + add_foreign_key "places", "companies" + add_foreign_key "reservations", "companies" + add_foreign_key "reservations", "customers" + add_foreign_key "reservations", "places" end diff --git a/test/controllers/customers_controller_test.rb b/test/controllers/customers_controller_test.rb new file mode 100644 index 0000000..b932686 --- /dev/null +++ b/test/controllers/customers_controller_test.rb @@ -0,0 +1,48 @@ +require "test_helper" + +class CustomersControllerTest < ActionDispatch::IntegrationTest + setup do + @customer = customers(:one) + end + + test "should get index" do + get customers_url + assert_response :success + end + + test "should get new" do + get new_customer_url + assert_response :success + end + + test "should create customer" do + assert_difference("Customer.count") do + post customers_url, params: { customer: { birthyear: @customer.birthyear, email: @customer.email, name: @customer.name, notes: @customer.notes, phone: @customer.phone } } + end + + assert_redirected_to customer_url(Customer.last) + end + + test "should show customer" do + get customer_url(@customer) + assert_response :success + end + + test "should get edit" do + get edit_customer_url(@customer) + assert_response :success + end + + test "should update customer" do + patch customer_url(@customer), params: { customer: { birthyear: @customer.birthyear, email: @customer.email, name: @customer.name, notes: @customer.notes, phone: @customer.phone } } + assert_redirected_to customer_url(@customer) + end + + test "should destroy customer" do + assert_difference("Customer.count", -1) do + delete customer_url(@customer) + end + + assert_redirected_to customers_url + end +end diff --git a/test/controllers/places_controller_test.rb b/test/controllers/places_controller_test.rb new file mode 100644 index 0000000..1e8661b --- /dev/null +++ b/test/controllers/places_controller_test.rb @@ -0,0 +1,48 @@ +require "test_helper" + +class PlacesControllerTest < ActionDispatch::IntegrationTest + setup do + @place = places(:one) + end + + test "should get index" do + get places_url + assert_response :success + end + + test "should get new" do + get new_place_url + assert_response :success + end + + test "should create place" do + assert_difference("Place.count") do + post places_url, params: { place: { company_id: @place.company_id, name: @place.name } } + end + + assert_redirected_to place_url(Place.last) + end + + test "should show place" do + get place_url(@place) + assert_response :success + end + + test "should get edit" do + get edit_place_url(@place) + assert_response :success + end + + test "should update place" do + patch place_url(@place), params: { place: { company_id: @place.company_id, name: @place.name } } + assert_redirected_to place_url(@place) + end + + test "should destroy place" do + assert_difference("Place.count", -1) do + delete place_url(@place) + end + + assert_redirected_to places_url + end +end diff --git a/test/controllers/reservations_controller_test.rb b/test/controllers/reservations_controller_test.rb new file mode 100644 index 0000000..5060b13 --- /dev/null +++ b/test/controllers/reservations_controller_test.rb @@ -0,0 +1,48 @@ +require "test_helper" + +class ReservationsControllerTest < ActionDispatch::IntegrationTest + setup do + @reservation = reservations(:one) + end + + test "should get index" do + get reservations_url + assert_response :success + end + + test "should get new" do + get new_reservation_url + assert_response :success + end + + test "should create reservation" do + assert_difference("Reservation.count") do + post reservations_url, params: { reservation: { company_id: @reservation.company_id, customer_id: @reservation.customer_id, description: @reservation.description, end_time: @reservation.end_time, place_id: @reservation.place_id, start_time: @reservation.start_time, title: @reservation.title } } + end + + assert_redirected_to reservation_url(Reservation.last) + end + + test "should show reservation" do + get reservation_url(@reservation) + assert_response :success + end + + test "should get edit" do + get edit_reservation_url(@reservation) + assert_response :success + end + + test "should update reservation" do + patch reservation_url(@reservation), params: { reservation: { company_id: @reservation.company_id, customer_id: @reservation.customer_id, description: @reservation.description, end_time: @reservation.end_time, place_id: @reservation.place_id, start_time: @reservation.start_time, title: @reservation.title } } + assert_redirected_to reservation_url(@reservation) + end + + test "should destroy reservation" do + assert_difference("Reservation.count", -1) do + delete reservation_url(@reservation) + end + + assert_redirected_to reservations_url + end +end diff --git a/test/fixtures/customers.yml b/test/fixtures/customers.yml new file mode 100644 index 0000000..c5ea622 --- /dev/null +++ b/test/fixtures/customers.yml @@ -0,0 +1,15 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + name: MyString + phone: MyString + notes: MyText + email: MyString + birthyear: 1 + +two: + name: MyString + phone: MyString + notes: MyText + email: MyString + birthyear: 1 diff --git a/test/fixtures/places.yml b/test/fixtures/places.yml new file mode 100644 index 0000000..d01926e --- /dev/null +++ b/test/fixtures/places.yml @@ -0,0 +1,9 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + name: MyString + company: one + +two: + name: MyString + company: two diff --git a/test/fixtures/reservations.yml b/test/fixtures/reservations.yml new file mode 100644 index 0000000..0756506 --- /dev/null +++ b/test/fixtures/reservations.yml @@ -0,0 +1,19 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + company: one + customer: one + place: one + title: MyString + description: MyText + start_time: 2024-08-04 08:01:12 + end_time: 2024-08-04 08:01:12 + +two: + company: two + customer: two + place: two + title: MyString + description: MyText + start_time: 2024-08-04 08:01:12 + end_time: 2024-08-04 08:01:12 diff --git a/test/models/customer_test.rb b/test/models/customer_test.rb new file mode 100644 index 0000000..8c83c4d --- /dev/null +++ b/test/models/customer_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class CustomerTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/place_test.rb b/test/models/place_test.rb new file mode 100644 index 0000000..9f5cd09 --- /dev/null +++ b/test/models/place_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class PlaceTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/reservation_test.rb b/test/models/reservation_test.rb new file mode 100644 index 0000000..1d04a16 --- /dev/null +++ b/test/models/reservation_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class ReservationTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/system/customers_test.rb b/test/system/customers_test.rb new file mode 100644 index 0000000..63885e5 --- /dev/null +++ b/test/system/customers_test.rb @@ -0,0 +1,49 @@ +require "application_system_test_case" + +class CustomersTest < ApplicationSystemTestCase + setup do + @customer = customers(:one) + end + + test "visiting the index" do + visit customers_url + assert_selector "h1", text: "Customers" + end + + test "should create customer" do + visit customers_url + click_on "New customer" + + fill_in "Birthyear", with: @customer.birthyear + fill_in "Email", with: @customer.email + fill_in "Name", with: @customer.name + fill_in "Notes", with: @customer.notes + fill_in "Phone", with: @customer.phone + click_on "Create Customer" + + assert_text "Customer was successfully created" + click_on "Back" + end + + test "should update Customer" do + visit customer_url(@customer) + click_on "Edit this customer", match: :first + + fill_in "Birthyear", with: @customer.birthyear + fill_in "Email", with: @customer.email + fill_in "Name", with: @customer.name + fill_in "Notes", with: @customer.notes + fill_in "Phone", with: @customer.phone + click_on "Update Customer" + + assert_text "Customer was successfully updated" + click_on "Back" + end + + test "should destroy Customer" do + visit customer_url(@customer) + click_on "Destroy this customer", match: :first + + assert_text "Customer was successfully destroyed" + end +end diff --git a/test/system/places_test.rb b/test/system/places_test.rb new file mode 100644 index 0000000..813cce5 --- /dev/null +++ b/test/system/places_test.rb @@ -0,0 +1,43 @@ +require "application_system_test_case" + +class PlacesTest < ApplicationSystemTestCase + setup do + @place = places(:one) + end + + test "visiting the index" do + visit places_url + assert_selector "h1", text: "Places" + end + + test "should create place" do + visit places_url + click_on "New place" + + fill_in "Company", with: @place.company_id + fill_in "Name", with: @place.name + click_on "Create Place" + + assert_text "Place was successfully created" + click_on "Back" + end + + test "should update Place" do + visit place_url(@place) + click_on "Edit this place", match: :first + + fill_in "Company", with: @place.company_id + fill_in "Name", with: @place.name + click_on "Update Place" + + assert_text "Place was successfully updated" + click_on "Back" + end + + test "should destroy Place" do + visit place_url(@place) + click_on "Destroy this place", match: :first + + assert_text "Place was successfully destroyed" + end +end diff --git a/test/system/reservations_test.rb b/test/system/reservations_test.rb new file mode 100644 index 0000000..a718d57 --- /dev/null +++ b/test/system/reservations_test.rb @@ -0,0 +1,53 @@ +require "application_system_test_case" + +class ReservationsTest < ApplicationSystemTestCase + setup do + @reservation = reservations(:one) + end + + test "visiting the index" do + visit reservations_url + assert_selector "h1", text: "Reservations" + end + + test "should create reservation" do + visit reservations_url + click_on "New reservation" + + fill_in "Company", with: @reservation.company_id + fill_in "Customer", with: @reservation.customer_id + fill_in "Description", with: @reservation.description + fill_in "End time", with: @reservation.end_time + fill_in "Place", with: @reservation.place_id + fill_in "Start time", with: @reservation.start_time + fill_in "Title", with: @reservation.title + click_on "Create Reservation" + + assert_text "Reservation was successfully created" + click_on "Back" + end + + test "should update Reservation" do + visit reservation_url(@reservation) + click_on "Edit this reservation", match: :first + + fill_in "Company", with: @reservation.company_id + fill_in "Customer", with: @reservation.customer_id + fill_in "Description", with: @reservation.description + fill_in "End time", with: @reservation.end_time + fill_in "Place", with: @reservation.place_id + fill_in "Start time", with: @reservation.start_time + fill_in "Title", with: @reservation.title + click_on "Update Reservation" + + assert_text "Reservation was successfully updated" + click_on "Back" + end + + test "should destroy Reservation" do + visit reservation_url(@reservation) + click_on "Destroy this reservation", match: :first + + assert_text "Reservation was successfully destroyed" + end +end