diff --git a/.idea/tailwind_rails.iml b/.idea/tailwind_rails.iml index de55e51..aea217d 100644 --- a/.idea/tailwind_rails.iml +++ b/.idea/tailwind_rails.iml @@ -37,6 +37,7 @@ + diff --git a/Gemfile b/Gemfile index 7338cc4..cd95528 100644 --- a/Gemfile +++ b/Gemfile @@ -36,6 +36,9 @@ gem "bootsnap", require: false # Use Active Storage variants [https://guides.rubyonrails.org/active_storage_overview.html#transforming-images] # gem "image_processing", "~> 1.2" +# Ordering of SQL relations +gem "acts_as_list" + group :development, :test do # See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem gem "debug", platforms: %i[ mri windows ], require: "debug/prelude" diff --git a/Gemfile.lock b/Gemfile.lock index 01242c2..e0a8421 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -71,6 +71,9 @@ GEM minitest (>= 5.1) securerandom (>= 0.3) tzinfo (~> 2.0, >= 2.0.5) + acts_as_list (1.2.2) + activerecord (>= 6.1) + activesupport (>= 6.1) addressable (2.8.7) public_suffix (>= 2.0.2, < 7.0) ast (2.4.2) @@ -313,6 +316,7 @@ PLATFORMS x86_64-linux-musl DEPENDENCIES + acts_as_list bootsnap brakeman capybara diff --git a/app/assets/images/hotel_images/a_tp_01_240808.jpg.webp b/app/assets/images/hotel_images/a_tp_01_240808.jpg.webp new file mode 100644 index 0000000..b56dfd6 Binary files /dev/null and b/app/assets/images/hotel_images/a_tp_01_240808.jpg.webp differ diff --git a/app/assets/images/hotel_images/a_tp_02_240808.jpg.webp b/app/assets/images/hotel_images/a_tp_02_240808.jpg.webp new file mode 100644 index 0000000..308539d Binary files /dev/null and b/app/assets/images/hotel_images/a_tp_02_240808.jpg.webp differ diff --git a/app/assets/images/hotel_images/a_tp_03a_220622.jpg.webp b/app/assets/images/hotel_images/a_tp_03a_220622.jpg.webp new file mode 100644 index 0000000..992d4ee Binary files /dev/null and b/app/assets/images/hotel_images/a_tp_03a_220622.jpg.webp differ diff --git a/app/assets/images/hotel_images/a_tpc01_190909.jpg.webp b/app/assets/images/hotel_images/a_tpc01_190909.jpg.webp new file mode 100644 index 0000000..fc09f54 Binary files /dev/null and b/app/assets/images/hotel_images/a_tpc01_190909.jpg.webp differ diff --git a/app/assets/images/hotel_images/b_ss1_02_240808.jpg.webp b/app/assets/images/hotel_images/b_ss1_02_240808.jpg.webp new file mode 100644 index 0000000..8526e19 Binary files /dev/null and b/app/assets/images/hotel_images/b_ss1_02_240808.jpg.webp differ diff --git a/app/assets/images/hotel_images/b_ss2_01_240808.jpg.webp b/app/assets/images/hotel_images/b_ss2_01_240808.jpg.webp new file mode 100644 index 0000000..066f52a Binary files /dev/null and b/app/assets/images/hotel_images/b_ss2_01_240808.jpg.webp differ diff --git a/app/assets/images/hotel_images/b_ss3_01_240808.jpg.webp b/app/assets/images/hotel_images/b_ss3_01_240808.jpg.webp new file mode 100644 index 0000000..c840f30 Binary files /dev/null and b/app/assets/images/hotel_images/b_ss3_01_240808.jpg.webp differ diff --git a/app/assets/images/hotel_images/b_ss4_01_240808.jpg.webp b/app/assets/images/hotel_images/b_ss4_01_240808.jpg.webp new file mode 100644 index 0000000..811382a Binary files /dev/null and b/app/assets/images/hotel_images/b_ss4_01_240808.jpg.webp differ diff --git a/app/assets/images/iphone_images/iphone-15-pro-finish-select-202309-6-1inch-blacktitanium.webp b/app/assets/images/iphone_images/iphone-15-pro-finish-select-202309-6-1inch-blacktitanium.webp new file mode 100644 index 0000000..0c6fe02 Binary files /dev/null and b/app/assets/images/iphone_images/iphone-15-pro-finish-select-202309-6-1inch-blacktitanium.webp differ diff --git a/app/assets/images/iphone_images/iphone-15-pro-finish-select-202309-6-1inch-bluetitanium.webp b/app/assets/images/iphone_images/iphone-15-pro-finish-select-202309-6-1inch-bluetitanium.webp new file mode 100644 index 0000000..43df853 Binary files /dev/null and b/app/assets/images/iphone_images/iphone-15-pro-finish-select-202309-6-1inch-bluetitanium.webp differ diff --git a/app/assets/images/iphone_images/iphone-15-pro-finish-select-202309-6-1inch-naturaltitanium.webp b/app/assets/images/iphone_images/iphone-15-pro-finish-select-202309-6-1inch-naturaltitanium.webp new file mode 100644 index 0000000..e229e2e Binary files /dev/null and b/app/assets/images/iphone_images/iphone-15-pro-finish-select-202309-6-1inch-naturaltitanium.webp differ diff --git a/app/assets/images/iphone_images/iphone-15-pro-finish-select-202309-6-1inch-whitetitanium.webp b/app/assets/images/iphone_images/iphone-15-pro-finish-select-202309-6-1inch-whitetitanium.webp new file mode 100644 index 0000000..6c5e3c4 Binary files /dev/null and b/app/assets/images/iphone_images/iphone-15-pro-finish-select-202309-6-1inch-whitetitanium.webp differ diff --git a/app/assets/images/iphone_images/iphone-15-pro-finish-select-202309-6-7inch-blacktitanium.webp b/app/assets/images/iphone_images/iphone-15-pro-finish-select-202309-6-7inch-blacktitanium.webp new file mode 100644 index 0000000..32f1888 Binary files /dev/null and b/app/assets/images/iphone_images/iphone-15-pro-finish-select-202309-6-7inch-blacktitanium.webp differ diff --git a/app/assets/images/iphone_images/iphone-15-pro-finish-select-202309-6-7inch-bluetitanium.webp b/app/assets/images/iphone_images/iphone-15-pro-finish-select-202309-6-7inch-bluetitanium.webp new file mode 100644 index 0000000..a1c9c64 Binary files /dev/null and b/app/assets/images/iphone_images/iphone-15-pro-finish-select-202309-6-7inch-bluetitanium.webp differ diff --git a/app/assets/images/iphone_images/iphone-15-pro-finish-select-202309-6-7inch-naturaltitanium.webp b/app/assets/images/iphone_images/iphone-15-pro-finish-select-202309-6-7inch-naturaltitanium.webp new file mode 100644 index 0000000..0ba1b94 Binary files /dev/null and b/app/assets/images/iphone_images/iphone-15-pro-finish-select-202309-6-7inch-naturaltitanium.webp differ diff --git a/app/assets/images/iphone_images/iphone-15-pro-finish-select-202309-6-7inch-whitetitanium.webp b/app/assets/images/iphone_images/iphone-15-pro-finish-select-202309-6-7inch-whitetitanium.webp new file mode 100644 index 0000000..42c3e7a Binary files /dev/null and b/app/assets/images/iphone_images/iphone-15-pro-finish-select-202309-6-7inch-whitetitanium.webp differ diff --git a/app/controllers/features_controller.rb b/app/controllers/features_controller.rb new file mode 100644 index 0000000..f3b794a --- /dev/null +++ b/app/controllers/features_controller.rb @@ -0,0 +1,70 @@ +class FeaturesController < ApplicationController + before_action :set_feature, only: %i[ show edit update destroy ] + + # GET /features or /features.json + def index + @features = Feature.all + end + + # GET /features/1 or /features/1.json + def show + end + + # GET /features/new + def new + @feature = Feature.new + end + + # GET /features/1/edit + def edit + end + + # POST /features or /features.json + def create + @feature = Feature.new(feature_params) + + respond_to do |format| + if @feature.save + format.html { redirect_to feature_url(@feature), notice: "Feature was successfully created." } + format.json { render :show, status: :created, location: @feature } + else + format.html { render :new, status: :unprocessable_entity } + format.json { render json: @feature.errors, status: :unprocessable_entity } + end + end + end + + # PATCH/PUT /features/1 or /features/1.json + def update + respond_to do |format| + if @feature.update(feature_params) + format.html { redirect_to feature_url(@feature), notice: "Feature was successfully updated." } + format.json { render :show, status: :ok, location: @feature } + else + format.html { render :edit, status: :unprocessable_entity } + format.json { render json: @feature.errors, status: :unprocessable_entity } + end + end + end + + # DELETE /features/1 or /features/1.json + def destroy + @feature.destroy! + + respond_to do |format| + format.html { redirect_to features_url, notice: "Feature was successfully destroyed." } + format.json { head :no_content } + end + end + + private + # Use callbacks to share common setup or constraints between actions. + def set_feature + @feature = Feature.find(params[:id]) + end + + # Only allow a list of trusted parameters through. + def feature_params + params.require(:feature).permit(:tagline, :descrption, :category, :image_path, :position, :hotel_id) + end +end diff --git a/app/controllers/hotels/descriptions_controller.rb b/app/controllers/hotels/descriptions_controller.rb deleted file mode 100644 index 4631116..0000000 --- a/app/controllers/hotels/descriptions_controller.rb +++ /dev/null @@ -1,11 +0,0 @@ -class Hotels::DescriptionsController < HotelBaseController - before_action :set_hotel - def show - end - - private - - def set_hotel - @hotel = Hotel.find(params[:hotel_id]) - end -end diff --git a/app/controllers/hotels/features_controller.rb b/app/controllers/hotels/features_controller.rb new file mode 100644 index 0000000..371f8fe --- /dev/null +++ b/app/controllers/hotels/features_controller.rb @@ -0,0 +1,16 @@ +class Hotels::FeaturesController < HotelBaseController + before_action :set_hotel + def index + @features = @hotel.topic_features.order(:position) + end + + def room + @features = @hotel.room_features.order(:position) + end + + private + + def set_hotel + @hotel = Hotel.find(params[:hotel_id]) + end +end diff --git a/app/controllers/iphones_controller.rb b/app/controllers/iphones_controller.rb new file mode 100644 index 0000000..eebdc5f --- /dev/null +++ b/app/controllers/iphones_controller.rb @@ -0,0 +1,19 @@ +class IphonesController < ApplicationController + layout "iphone" + before_action :set_iphone + def show + end + + def create + @iphone.model = params[:model] if params[:model] + @iphone.color = params[:color] if params[:color] + redirect_to iphone_path + end + + private + + def set_iphone + session[:iphone] ||= {} + @iphone = Iphone.new(session[:iphone]) + end +end diff --git a/app/helpers/features_helper.rb b/app/helpers/features_helper.rb new file mode 100644 index 0000000..1a5e6b2 --- /dev/null +++ b/app/helpers/features_helper.rb @@ -0,0 +1,2 @@ +module FeaturesHelper +end diff --git a/app/javascript/controllers/image_switcher_controller.js b/app/javascript/controllers/image_switcher_controller.js new file mode 100644 index 0000000..69edb15 --- /dev/null +++ b/app/javascript/controllers/image_switcher_controller.js @@ -0,0 +1,20 @@ +import { Controller } from "@hotwired/stimulus" + +// Connects to data-controller="image-switcher" +export default class extends Controller { + static values = {iphone: Object} + static targets = ["colorText"] + + connect() { + } + + setColorTitle(event) { + const colorName = event.params.colorName + this.colorTextTargets.forEach(target => target.textContent = colorName) + } + + resetColorTitle(event) { + this.colorTextTargets.forEach(target => target.textContent = this.iphoneValue.color_name) + } + +} diff --git a/app/javascript/controllers/index.js b/app/javascript/controllers/index.js index d689252..42d7ff0 100644 --- a/app/javascript/controllers/index.js +++ b/app/javascript/controllers/index.js @@ -19,6 +19,9 @@ application.register("hamburger", HamburgerController) import HelloController from "./hello_controller" application.register("hello", HelloController) +import ImageSwitcherController from "./image_switcher_controller" +application.register("image-switcher", ImageSwitcherController) + import NavbarController from "./navbar_controller" application.register("navbar", NavbarController) diff --git a/app/models/feature.rb b/app/models/feature.rb new file mode 100644 index 0000000..7515305 --- /dev/null +++ b/app/models/feature.rb @@ -0,0 +1,4 @@ +class Feature < ApplicationRecord + belongs_to :hotel + enum :category, [ :topic, :room, :restaurant, :service, :basic_info ] +end diff --git a/app/models/hotel.rb b/app/models/hotel.rb index 7b5c8d7..5f69880 100644 --- a/app/models/hotel.rb +++ b/app/models/hotel.rb @@ -1,2 +1,5 @@ class Hotel < ApplicationRecord + has_many :features + has_many :topic_features, -> { where(category: :topic) }, class_name: "Feature" + has_many :room_features, -> { where(category: :room) }, class_name: "Feature" end diff --git a/app/models/iphone.rb b/app/models/iphone.rb new file mode 100644 index 0000000..d56b8b7 --- /dev/null +++ b/app/models/iphone.rb @@ -0,0 +1,43 @@ +class Iphone + def initialize(iphone_session) + @iphone_session = iphone_session + end + + def model=(string) + @iphone_session['model'] = string + end + + def model + @iphone_session['model'] || "6-1inch" + end + + def color=(string) + @iphone_session['color'] = string + end + + def color + @iphone_session["color"] || "naturaltitanium" + end + + def color_name + color_name_for_value(color) + end + + def color_name_for_value(value) + table = { + "naturaltitanium" => "Color – Natural Titanium", + "bluetitanium" => "Color – Blue Titanium", + "whitetitanium" => "Color – White Titanium", + "blacktitanium" => "Color – Black Titanium", + } + table[value] + end + + def image_path + "iphone_images/iphone-15-pro-finish-select-202309-#{model}-#{color}.webp" + end + + def to_hash + {model:, color:, color_name:} + end +end diff --git a/app/views/features/_feature.html.erb b/app/views/features/_feature.html.erb new file mode 100644 index 0000000..e9a6574 --- /dev/null +++ b/app/views/features/_feature.html.erb @@ -0,0 +1,32 @@ +
+

+ Tagline: + <%= feature.tagline %> +

+ +

+ Descrption: + <%= feature.descrption %> +

+ +

+ Category: + <%= feature.category %> +

+ +

+ Image path: + <%= feature.image_path %> +

+ +

+ Position: + <%= feature.position %> +

+ +

+ Hotel: + <%= feature.hotel_id %> +

+ +
diff --git a/app/views/features/_feature.json.jbuilder b/app/views/features/_feature.json.jbuilder new file mode 100644 index 0000000..af080a7 --- /dev/null +++ b/app/views/features/_feature.json.jbuilder @@ -0,0 +1,2 @@ +json.extract! feature, :id, :tagline, :descrption, :category, :image_path, :position, :hotel_id, :created_at, :updated_at +json.url feature_url(feature, format: :json) diff --git a/app/views/features/_form.html.erb b/app/views/features/_form.html.erb new file mode 100644 index 0000000..39f8273 --- /dev/null +++ b/app/views/features/_form.html.erb @@ -0,0 +1,47 @@ +<%= form_with(model: feature) do |form| %> + <% if feature.errors.any? %> +
+

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

+ +
    + <% feature.errors.each do |error| %> +
  • <%= error.full_message %>
  • + <% end %> +
+
+ <% end %> + +
+ <%= form.label :tagline, style: "display: block" %> + <%= form.text_field :tagline %> +
+ +
+ <%= form.label :descrption, style: "display: block" %> + <%= form.text_field :descrption %> +
+ +
+ <%= form.label :category, style: "display: block" %> + <%= form.text_field :category %> +
+ +
+ <%= form.label :image_path, style: "display: block" %> + <%= form.text_field :image_path %> +
+ +
+ <%= form.label :position, style: "display: block" %> + <%= form.number_field :position %> +
+ +
+ <%= form.label :hotel_id, style: "display: block" %> + <%= form.text_field :hotel_id %> +
+ +
+ <%= form.submit %> +
+<% end %> diff --git a/app/views/features/edit.html.erb b/app/views/features/edit.html.erb new file mode 100644 index 0000000..4ca88be --- /dev/null +++ b/app/views/features/edit.html.erb @@ -0,0 +1,12 @@ +<% content_for :title, "Editing feature" %> + +

Editing feature

+ +<%= render "form", feature: @feature %> + +
+ +
+ <%= link_to "Show this feature", @feature %> | + <%= link_to "Back to features", features_path %> +
diff --git a/app/views/features/index.html.erb b/app/views/features/index.html.erb new file mode 100644 index 0000000..5b2eb5d --- /dev/null +++ b/app/views/features/index.html.erb @@ -0,0 +1,16 @@ +

<%= notice %>

+ +<% content_for :title, "Features" %> + +

Features

+ +
+ <% @features.each do |feature| %> + <%= render feature %> +

+ <%= link_to "Show this feature", feature %> +

+ <% end %> +
+ +<%= link_to "New feature", new_feature_path %> diff --git a/app/views/features/index.json.jbuilder b/app/views/features/index.json.jbuilder new file mode 100644 index 0000000..9ecc33e --- /dev/null +++ b/app/views/features/index.json.jbuilder @@ -0,0 +1 @@ +json.array! @features, partial: "features/feature", as: :feature diff --git a/app/views/features/new.html.erb b/app/views/features/new.html.erb new file mode 100644 index 0000000..4d031bd --- /dev/null +++ b/app/views/features/new.html.erb @@ -0,0 +1,11 @@ +<% content_for :title, "New feature" %> + +

New feature

+ +<%= render "form", feature: @feature %> + +
+ +
+ <%= link_to "Back to features", features_path %> +
diff --git a/app/views/features/show.html.erb b/app/views/features/show.html.erb new file mode 100644 index 0000000..9b4b6b1 --- /dev/null +++ b/app/views/features/show.html.erb @@ -0,0 +1,10 @@ +

<%= notice %>

+ +<%= render @feature %> + +
+ <%= link_to "Edit this feature", edit_feature_path(@feature) %> | + <%= link_to "Back to features", features_path %> + + <%= button_to "Destroy this feature", @feature, method: :delete %> +
diff --git a/app/views/features/show.json.jbuilder b/app/views/features/show.json.jbuilder new file mode 100644 index 0000000..d144cb7 --- /dev/null +++ b/app/views/features/show.json.jbuilder @@ -0,0 +1 @@ +json.partial! "features/feature", feature: @feature diff --git a/app/views/hotels/descriptions/show.html.erb b/app/views/hotels/descriptions/show.html.erb deleted file mode 100644 index 8d4dc56..0000000 --- a/app/views/hotels/descriptions/show.html.erb +++ /dev/null @@ -1,16 +0,0 @@ -<%= turbo_frame_tag :slide_drawer do %> -
-
-

宿の紹介

-
-
- -
-
-<% end %> diff --git a/app/views/hotels/features/index.html.erb b/app/views/hotels/features/index.html.erb new file mode 100644 index 0000000..4c01d71 --- /dev/null +++ b/app/views/hotels/features/index.html.erb @@ -0,0 +1,38 @@ +<%= turbo_frame_tag :slide_drawer do %> +
+
+

宿の紹介

+
+
+ +
+ <% @features[0..1].each do |feature| %> +
+ <%= image_tag "hotel_images/#{feature.image_path}" %> +
+

<%= feature.tagline %>

+
<%= sanitize feature.description %>
+
+
+ <% end %> +
+ <% (@features[2..] || []).each do |feature| %> +
+ <%= image_tag "hotel_images/#{feature.image_path}" %> +
+

<%= feature.tagline %>

+
<%= sanitize feature.description %>
+
+
+ <% end %> +
+
+
+
+<% end %> diff --git a/app/views/hotels/features/room.html.erb b/app/views/hotels/features/room.html.erb new file mode 100644 index 0000000..d2f87e2 --- /dev/null +++ b/app/views/hotels/features/room.html.erb @@ -0,0 +1,27 @@ +<%= turbo_frame_tag :slide_drawer do %> +
+
+

宿の紹介

+
+
+ +
+ <% @features.each do |feature| %> +
+ <%= image_tag "hotel_images/#{feature.image_path}" %> +
+

<%= feature.tagline %>

+
<%= sanitize feature.description %>
+
+
+ <% end %> +
+
+
+<% end %> diff --git a/app/views/hotels/show.html.erb b/app/views/hotels/show.html.erb index a8fe752..e57b86b 100644 --- a/app/views/hotels/show.html.erb +++ b/app/views/hotels/show.html.erb @@ -42,7 +42,7 @@ > <%= link_to "部屋・プラン", "", class: "px-4 inline-block py-4 h-16 text-lg border-b-4 border-blue-500" %> - <%= link_to "宿の紹介", hotel_description_path(@hotel), + <%= link_to "宿の紹介", hotel_features_path(@hotel), data: {action: "click->drawer-trigger#show", turbo_frame: :slide_drawer}, class: "px-4 inline-block py-4 h-16 text-lg" %> <%= link_to "クチコミ", "", diff --git a/app/views/iphones/_color_option.html.erb b/app/views/iphones/_color_option.html.erb new file mode 100644 index 0000000..c8a8186 --- /dev/null +++ b/app/views/iphones/_color_option.html.erb @@ -0,0 +1,13 @@ +<%# locals: (value:, color:, iphone:) %> +<%= label_tag [:color, value].join('_'), + data: { + action: "mouseenter->image-switcher#setColorTitle mouseleave->image-switcher#resetColorTitle", + image_switcher_color_name_param: iphone.color_name_for_value(value) + }, + class: "#{color} inline-block w-8 h-8 border-2 rounded-full cursor-pointer outline-2 outline outline-offset-0.5 outline-transparent has-[:checked]:outline-blue-500" do %> + <%= radio_button_tag :color, value, iphone.color == value, + class: "hidden", + onchange: "this.form.requestSubmit()" + %> +   +<% end %> diff --git a/app/views/iphones/_option.html.erb b/app/views/iphones/_option.html.erb new file mode 100644 index 0000000..565c7eb --- /dev/null +++ b/app/views/iphones/_option.html.erb @@ -0,0 +1,18 @@ +<%# locals: (name:, value:, selected: false, title:, subtitle: nil, pricing_lines:[]) %> +<%= label_tag [name, value].join('_'), class: "mt-4 flex justify-between p-4 block border-2 rounded-lg w-full cursor-pointer has-[:checked]:border-blue-500" do %> + <%= radio_button_tag name, value, selected, + class: "hidden", + onchange: "this.form.requestSubmit()" + %> +
+
<%= title %>
+ <% if subtitle %> +
<%= subtitle %>
+ <% end %> +
+
+ <% pricing_lines.each do |line| %> +
<%= line %>
+ <% end %> +
+<% end %> diff --git a/app/views/iphones/show.html.erb b/app/views/iphones/show.html.erb new file mode 100644 index 0000000..9493af3 --- /dev/null +++ b/app/views/iphones/show.html.erb @@ -0,0 +1,75 @@ +<% turbo_refreshes_with(method: :morph, scroll: :preserve) %> + +
+

Buy iPhone 15 Pro

+
From $1399 or $58.29/mo. for 24 mo.*
+
+ +<%= tag.div class: "flex" do %> +
+ <% if @iphone.image_path %> + <%= image_tag @iphone.image_path, + class: "object-cover w-[592px] h-[460px] rounded-[20px]" %> + <% end %> +
+
+
+

Model. Which is best for you?

+
+ <%= form_with url: iphone_path, method: :post do %> + <%= render 'option', + name: :model, + value: "6-1inch", + selected: @iphone.model == "6-1inch", + title: "iPhone 15 Pro", + subtitle: "6.1-inch display", + pricing_lines: ["From $999", "or $41.62/mo.", "for 24 mo."] %> + <%= render 'option', + name: :model, + value: "6-7inch", + selected: @iphone.model == "6-7inch", + title: "iPhone 15 Pro Max", + subtitle: "6.7-inch display", + pricing_lines: ["From $1199", "or $49.95/mo.", "for 24 mo."] %> + <% end %> +
+
+
Need help choosing a model?
+
Explore the differences in screen size and battery life
+
+
+ + + +
+
+
+
+ +
+

Finish. Pick your favorite

+ <%= tag.div data: {controller: "image-switcher", image_switcher_iphone_value: @iphone} do %> +
<%= @iphone.color_name %>
+ + <%= form_with url: iphone_path, method: :post do %> + <%= render 'color_option', + value: "naturaltitanium", + color: "bg-gray-400", + iphone: @iphone %> + <%= render 'color_option', + value: "bluetitanium", + color: "bg-indigo-800", + iphone: @iphone %> + <%= render 'color_option', + value: "whitetitanium", + color: "bg-white", + iphone: @iphone %> + <%= render 'color_option', + value: "blacktitanium", + color: "bg-black", + iphone: @iphone %> + <% end %> + <% end %> +
+
+<% end %> diff --git a/app/views/layouts/iphone.html.erb b/app/views/layouts/iphone.html.erb new file mode 100644 index 0000000..fe95937 --- /dev/null +++ b/app/views/layouts/iphone.html.erb @@ -0,0 +1,42 @@ + + + + <%= content_for(:title) || "Tailwind Rails" %> + + + <%= csrf_meta_tags %> + <%= csp_meta_tag %> + + <%= yield :head %> + + + + + + <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %> + <%= javascript_include_tag "application", "data-turbo-track": "reload", type: "module" %> + + + +
+ +
<%= content_for(:breadcrumbs) %>
+ <%= yield %> +
+ + diff --git a/config/routes.rb b/config/routes.rb index ca2a0d9..dc4ef49 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,4 +1,5 @@ Rails.application.routes.draw do + resources :features # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html # Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500. @@ -14,14 +15,14 @@ resources :components, only: [ :index, :show ] resources :hotels do - resource :description, module: :hotels do - member do + resources :features, module: :hotels do + collection do get :room get :restaurant - get :amenities + get :service get :basic_info end end end - + resource :iphone end diff --git a/db/migrate/20240907075950_create_features.rb b/db/migrate/20240907075950_create_features.rb new file mode 100644 index 0000000..7b3f41a --- /dev/null +++ b/db/migrate/20240907075950_create_features.rb @@ -0,0 +1,14 @@ +class CreateFeatures < ActiveRecord::Migration[7.2] + def change + create_table :features do |t| + t.string :tagline + t.string :description + t.string :category + t.string :image_path + t.integer :position + t.references :hotel, null: false, foreign_key: true + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 08819da..5670f3b 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,19 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.2].define(version: 2024_09_07_025333) do +ActiveRecord::Schema[7.2].define(version: 2024_09_07_075950) do + create_table "features", force: :cascade do |t| + t.string "tagline" + t.string "description" + t.string "category" + t.string "image_path" + t.integer "position" + t.integer "hotel_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["hotel_id"], name: "index_features_on_hotel_id" + end + create_table "hotels", force: :cascade do |t| t.string "name" t.string "prefecture" @@ -20,4 +32,6 @@ t.datetime "created_at", null: false t.datetime "updated_at", null: false end + + add_foreign_key "features", "hotels" end diff --git a/test/controllers/features_controller_test.rb b/test/controllers/features_controller_test.rb new file mode 100644 index 0000000..791f128 --- /dev/null +++ b/test/controllers/features_controller_test.rb @@ -0,0 +1,48 @@ +require "test_helper" + +class FeaturesControllerTest < ActionDispatch::IntegrationTest + setup do + @feature = features(:one) + end + + test "should get index" do + get features_url + assert_response :success + end + + test "should get new" do + get new_feature_url + assert_response :success + end + + test "should create feature" do + assert_difference("Feature.count") do + post features_url, params: { feature: { category: @feature.category, descrption: @feature.descrption, hotel_id: @feature.hotel_id, image_path: @feature.image_path, position: @feature.position, tagline: @feature.tagline } } + end + + assert_redirected_to feature_url(Feature.last) + end + + test "should show feature" do + get feature_url(@feature) + assert_response :success + end + + test "should get edit" do + get edit_feature_url(@feature) + assert_response :success + end + + test "should update feature" do + patch feature_url(@feature), params: { feature: { category: @feature.category, descrption: @feature.descrption, hotel_id: @feature.hotel_id, image_path: @feature.image_path, position: @feature.position, tagline: @feature.tagline } } + assert_redirected_to feature_url(@feature) + end + + test "should destroy feature" do + assert_difference("Feature.count", -1) do + delete feature_url(@feature) + end + + assert_redirected_to features_url + end +end diff --git a/test/fixtures/features.yml b/test/fixtures/features.yml new file mode 100644 index 0000000..1e35a5b --- /dev/null +++ b/test/fixtures/features.yml @@ -0,0 +1,79 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +halekulani_topic1: + tagline: 天国の名にもっともふさわしい楽園へ + description: + ハワイの言葉で「天国にふさわしい館」を意味するハレクラニは、ワイキキビーチで100年以上にわたる歴史を重ね、世代を超えて多くのお客さまに愛されてきたホテルブランドです。その2つめのホテルとなるハレクラニ沖縄は、沖縄海岸国定公園として守られてきた恩納村の優雅な海辺で、新たな時代のラグジュアリーをご提供します。 + category: topic + image_path: a_tpc01_190909.jpg.webp + position: 1 + hotel: halekulani + +halekulani_topic2: + tagline: すべての客室がオーシャンビュー + description: + ハレクラニ沖縄では、ご滞在するすべてのお客様にオーシャンビューと沖縄の自然を満喫できる客室をご用意しております。
+ 全室50平米以上の白を基調としたリラックスした空間と、心地よい時間を過ごせるテラス付き。
+ ハレクラニのアイデンティティである「Seven Shades of White(7色の白)」のコンセプトを + 受け継ぎ、優美な白に満たされた滞在空間は、窓の外に広がる青く美しい世界をいっそう鮮やかに映し出します。 + category: topic + image_path: a_tp_01_240808.jpg.webp + position: 2 + hotel: halekulani + +halekulani_topic3: + tagline: 美しい空間デザイン + description: + リゾート内のあらゆる空間が、「ハレクラニ」の世界観をそのまま体現しています。陽気な楽園ムードに心が華やぐオールデイダイニング、落ち着きと風格を醸すステーキ&ワイン、ドラマティックなサンセットを満喫するバーなど、それぞれインテリアの趣は異なりますが、どの空間においても「優雅なおもてなし」を体感いただけるハレクラニスピリットが息づいています。 + category: topic + image_path: a_tp_02_240808.jpg.webp + position: 3 + hotel: halekulani + +halekulani_topic4: + tagline: スタッフの心からのホスピタリティ + description: + ハレクラニ沖縄で過ごすラグジュアリーな1日。この奇跡の楽園においては、あらゆるシーンに特別な時間が流れています。
+ ヴァカンス、ハネムーン、一人旅などお越しになる目的はさまざまでも、一貫して変わらないのは、スタッフの心からのホスピタリティ。ハレクラニの伝統的なおもてなしを大切にしながら、パーソナルでプロフェッショナルなサービスを体感いただけます。ハレクラニに愛着をもち、誇りと情熱を心に抱いて、お客さまをお迎えします。 + category: topic + image_path: a_tp_03a_220622.jpg.webp + position: 4 + hotel: halekulani + +halekulani_room1: + tagline: VILLAS + description: + 青い海が間近に広がるクリフトップには、プライベートプール(温水)と天然温泉を備えた5棟のヴィラがございます。
+ 頂点の贅沢を満喫しながら、まるで我が家のようなくつろぎを感じていただけます。 + category: room + image_path: b_ss1_02_240808.jpg.webp + position: 1 + hotel: halekulani + +halekulani_room2: + tagline: SUITES + description: + 絶佳の眺望を誇る広さ76平米のエグゼクティブオーシャン スイートから、贅沢の頂点を極めたペントハウスタイプのプライベートプールも備えた広さ294㎡のオーキッド スイートまで、まさに天国にふさわしい滞在をご提供します。 + category: room + image_path: b_ss2_01_240808.jpg.webp + position: 2 + hotel: halekulani + +halekulani_room3: + tagline: STANDARD ROOMS + description: + 新たなラグジュアリーのスタンダードとなるテラス付き広さ50平米のゲストルームは、ビーチフロントウイング、サンセットウイングに7つのタイプをご用意しました。お客さまの求める滞在スタイルに合わせて、お選びいただけます。 + category: room + image_path: b_ss3_01_240808.jpg.webp + position: 3 + hotel: halekulani + +halekulani_room4: + tagline: CLUB LOUNGE + description: + サンセットウィング5階には、クラブラウンジをご用意しました。プレミアクラブオーシャンフロント、ヴィラにご宿泊のお客さまが、ご利用いただけます。クラブラウンジレセプションには専任スタッフが常駐し、快適な滞在のお手伝いをいたします。
+ 心地よいテラス席も設けたラウンジ内では、終日シャンパンサービスをご堪能いただけます。また、朝食をお召し上がりいただけるほか、アフタヌーンティーやカクテルなどをご自由にお楽しみください。 + category: room + image_path: b_ss4_01_240808.jpg.webp + position: 4 + hotel: halekulani diff --git a/test/fixtures/hotels.yml b/test/fixtures/hotels.yml index ce16161..4e0d285 100644 --- a/test/fixtures/hotels.yml +++ b/test/fixtures/hotels.yml @@ -1,6 +1,6 @@ # Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html -haleclani: +halekulani: name: ハレクラニ沖縄 prefecture: 沖縄県 city: 恩納村 diff --git a/test/models/feature_test.rb b/test/models/feature_test.rb new file mode 100644 index 0000000..f805a7f --- /dev/null +++ b/test/models/feature_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class FeatureTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/system/features_test.rb b/test/system/features_test.rb new file mode 100644 index 0000000..f28a26e --- /dev/null +++ b/test/system/features_test.rb @@ -0,0 +1,51 @@ +require "application_system_test_case" + +class FeaturesTest < ApplicationSystemTestCase + setup do + @feature = features(:one) + end + + test "visiting the index" do + visit features_url + assert_selector "h1", text: "Features" + end + + test "should create feature" do + visit features_url + click_on "New feature" + + fill_in "Category", with: @feature.category + fill_in "Descrption", with: @feature.descrption + fill_in "Hotel", with: @feature.hotel_id + fill_in "Image path", with: @feature.image_path + fill_in "Position", with: @feature.position + fill_in "Tagline", with: @feature.tagline + click_on "Create Feature" + + assert_text "Feature was successfully created" + click_on "Back" + end + + test "should update Feature" do + visit feature_url(@feature) + click_on "Edit this feature", match: :first + + fill_in "Category", with: @feature.category + fill_in "Descrption", with: @feature.descrption + fill_in "Hotel", with: @feature.hotel_id + fill_in "Image path", with: @feature.image_path + fill_in "Position", with: @feature.position + fill_in "Tagline", with: @feature.tagline + click_on "Update Feature" + + assert_text "Feature was successfully updated" + click_on "Back" + end + + test "should destroy Feature" do + visit feature_url(@feature) + click_on "Destroy this feature", match: :first + + assert_text "Feature was successfully destroyed" + end +end