[51]メッセージと会話| コメントへのファイル添付 << [ホームに戻る] >> [53]デプロイ | herokuアカウント
yarnを使ってインストールします。
コマンド
一文です。
yarn add @fullcalendar/core@4.2.0 @fullcalendar/daygrid@4.2.0 @fullcalendar/list@4.2.0
「app\assets\stylesheets\application.scss」ファイルを編集します。
1.13行目と14行目の記述をひっくり返して次のようにします。
*= require_self *= require_tree .
2.記述追加 app\assets\stylesheets\application.scss(29行目)
@import '@fullcalendar/core/main.css'; @import '@fullcalendar/daygrid/main.css'; @import '@fullcalendar/list/main.css';
app\assets\stylesheets\application.scss
/* * This is a manifest file that'll be compiled into application.css, which will include all the files * listed below. * * Any CSS and SCSS file within this directory, lib/assets/stylesheets, or any plugin's * vendor/assets/stylesheets directory can be referenced here using a relative path. * * You're free to add application-wide styles to this file and they'll appear at the bottom of the * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS * files in this directory. Styles in this file should be added after the last require_* statement. * It is generally better to create a new file per style scope. * *= require_self *= require_tree . */ @import 'bulma'; @import 'bulma-extensions'; @import 'bulma-extensions/bulma-carousel/dist/css/bulma-carousel.min'; @import 'noty/lib/noty'; @import 'noty/lib/themes/sunset'; @import 'dropzone/dist/basic.css'; @import 'dropzone/dist/dropzone.css'; @import 'raty-js/lib/jquery.raty'; @import '@fullcalendar/core/main.css'; @import '@fullcalendar/daygrid/main.css'; @import '@fullcalendar/list/main.css';
「app\javascript\packs\application.js」ファイルを編集します。
記述追加 app\javascript\packs\application.js(16行目)
window.Calendar = require("@fullcalendar/core").Calendar; window.DayGridPlugin = require("@fullcalendar/daygrid").default; window.ListPlugin = require("@fullcalendar/list").default;
app\javascript\packs\application.js
// This file is automatically compiled by Webpack, along with any other files // present in this directory. You're encouraged to place your actual application logic in // a relevant structure within app/javascript and only use these pack files to reference // that code so it'll be compiled. require("@rails/ujs").start() require("turbolinks").start() require("@rails/activestorage").start() require("channels") require("raty-js") window.Noty = require("noty") window.Dropzone = require("dropzone") window.BulmaCarousel = require("bulma-extensions/bulma-carousel/dist/js/bulma-carousel") window.Calendar = require("@fullcalendar/core").Calendar; window.DayGridPlugin = require("@fullcalendar/daygrid").default; window.ListPlugin = require("@fullcalendar/list").default; $(document).on('turbolinks:load', () => { $('.toggle').on('click', (e) => { e.stopPropagation(); e.preventDefault(); $('#' + e.target.getAttribute('aria-controls')).toggleClass('is-hidden'); }) }) // Uncomment to copy all static images under ../images to the output folder and reference // them with the image_pack_tag helper in views (e.g <%= image_pack_tag 'rails.png' %>) // or the `imagePath` JavaScript helper below. // // const images = require.context('../images', true) // const imagePath = (name) => images(name, true) require("trix") require("@rails/actiontext")
「app\controllers\pages_controller.rb」ファイルに記述を追加します。
記述追加 app\controllers\pages_controller.rb(47行目)
def calendar params[:start_date] ||= Date.current.to_s start_date = Date.parse(params[:start_date]) first_of_month = (start_date - 1.month).beginning_of_month end_of_month = (start_date + 1.month).end_of_month @orders = Order.where("seller_id = ? AND status = ? AND due_date BETWEEN ? AND ?", current_user.id, Order.statuses[:inprogress], first_of_month, end_of_month) end
app\controllers\pages_controller.rb
class PagesController < ApplicationController def home end def search @categories = Category.all @category = Category.find(params[:category]) if params[:category].present? @q = params[:q] @min = params[:min] @max = params[:max] @delivery = params[:delivery].present? ? params[:delivery] : "0" @sort = params[:sort].present? ? params[:sort] : "price asc" query_condition = [] query_condition[0] = "gigs.active = true" query_condition[0] += " AND ((gigs.has_single_pricing = true AND pricings.pricing_type = 0) OR (gigs.has_single_pricing = false))" if !@q.blank? query_condition[0] += " AND gigs.title ILIKE ?" query_condition.push "%#{@q}%" end if !params[:category].blank? query_condition[0] += " AND category_id = ?" query_condition.push params[:category] end if !params[:min].blank? query_condition[0] += " AND pricings.price >= ?" query_condition.push @min end if !params[:max].blank? query_condition[0] += " AND pricings.price <= ?" query_condition.push @max end if !params[:delivery].blank? && params[:delivery] != "0" query_condition[0] += " AND pricings.delivery_time <= ?" query_condition.push @delivery end @gigs = Gig .select("gigs.id, gigs.title, gigs.user_id, MIN(pricings.price) AS price") .joins(:pricings) .where(query_condition) .group("gigs.id") .order(@sort) .page(params[:page]) .per(6) end def calendar params[:start_date] ||= Date.current.to_s start_date = Date.parse(params[:start_date]) first_of_month = (start_date - 1.month).beginning_of_month end_of_month = (start_date + 1.month).end_of_month @orders = Order.where("seller_id = ? AND status = ? AND due_date BETWEEN ? AND ?", current_user.id, Order.statuses[:inprogress], first_of_month, end_of_month) end end
ルートの設定をします。
記述追加 config\routes.rb
26行目に「get '/calendar', to: 'pages#calendar'」の記述を追加します。
Rails.application.routes.draw do # ルートを app\views\pages\home.html.erb に設定 root 'pages#home' devise_for :users, path: '', path_names: {sign_up: 'register', sign_in: 'login', edit: 'profile', sign_out: 'logout'}, controllers: {omniauth_callbacks: 'omniauth_callbacks', registrations: 'registrations'} get 'pages/home' get '/dashboard', to: 'users#dashboard' get '/users/:id', to: 'users#show', as: 'users' get '/selling_orders', to: 'orders#selling_orders' get '/buying_orders', to: 'orders#buying_orders' get '/all_requests', to: 'requests#list' get '/request_offers/:id', to: 'requests#offers', as: 'request_offers' get '/my_offers', to: 'requests#my_offers' get '/search', to: 'pages#search' get 'settings/payment', to: 'users#payment', as: 'settings_payment' get 'settings/payout', to: 'users#payout', as: 'settings_payout' get '/gigs/:id/checkout/:pricing_type', to: 'gigs#checkout', as: 'checkout' get '/conversations', to: 'conversations#list', as: "conversations" get '/conversations/:id', to: 'conversations#show', as: "conversation_detail" get '/orders/:id', to: 'orders#show', as: "order_detail" get '/calendar', to: 'pages#calendar' post '/users/edit', to: 'users#update' post '/offers', to: 'offers#create' post '/reviews', to: 'reviews#create' post '/settings/payment', to: 'users#update_payment', as: "update_payment" post 'messages', to: 'messages#create' post '/comments', to: 'comments#create' put '/orders/:id/complete', to: 'orders#complete', as: 'complete_order' put '/offers/:id/accept', to: 'offers#accept', as: 'accept_offer' put '/offers/:id/reject', to: 'offers#reject', as: 'reject_offer' mount ActionCable.server => '/cable' resources :gigs do member do delete :delete_photo post :upload_photo end resources :orders, only: [:create] end resources :requests # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html end
「app\views\pages」フォルダに「calendar.html.erb」ファイルを新規作成して下さい。
app\views\pages\calendar.html.erb(新規作成したファイル)
<section class="section"> <div class="container m-t-20"> <div id="calendar"></div> </div> </section> <script> orders = <%= raw @orders.to_json %> function showOrders(orders) { return orders.map(function(o) { let code = '#ffdd57'; if (new Date(o.due_date) < new Date()) { code = '#ff3860'; } else if (new Date(o.due_date) > new Date(new Date().getTime() + (2*24*60*60*1000))) { code = '#23d160'; } return { id: o.id, title: o.buyer_name, start: o.due_date, end: o.due_date, backgroundColor: code } }) } var getQueryParam = function(param) { var found, item = window.location.search.substr(1).split("="); if (param == item[0]) { found = item[1] } return found; } $(function() { var start_date = getQueryParam('start_date') ? new Date(getQueryParam('start_date')) : new Date() var calendarEl = document.getElementById('calendar'); var calendar = new Calendar(calendarEl, { header: { left: 'prev,next', center: 'title', right: 'dayGridMonth,listMonth' }, // ボタン文字列 buttonText: { month: '月', list: '申し込みリスト', }, locale: 'ja', defaultDate: start_date, plugins: [DayGridPlugin, ListPlugin], events: showOrders(orders), eventClick: function(info) { window.location.href = "/orders/" + info.event.id }, defaultView: 'dayGridMonth' }); calendar.render(); $('.fc-prev-button').on('click', function() { window.location.search = 'start_date=' + calendar.state.currentDate.toISOString().split("T")[0] }); $('.fc-next-button').on('click', function() { window.location.search = 'start_date=' + calendar.state.currentDate.toISOString().split("T")[0] }); }) </script>
ナビゲーションバーにリンクを追加します。
記述追加 app\views\shared\_navbar.html.erb
83行目に「<%= link_to 'カレンダー', calendar_path, class: "navbar-item" %>」の記述を追加しています。
<nav class="navbar is-danger" role="navigation" aria-label="main navigation"> <div class="navbar-brand"> <a class="navbar-item" href="/"> <h1>テストサイトOshigoto</h1> </a> <a role="button" class="navbar-burger burger" aria-label="menu" aria-expanded="false" data-target="navbarBasicExample"> <span aria-hidden="true"></span> <span aria-hidden="true"></span> <span aria-hidden="true"></span> </a> </div> <div id="navbarBasicExample" class="navbar-menu"> <div class="navbar-start"> <div class="navbar-item"> <%= form_tag search_path, method: :get do %> <div class="field has-addons <%= 'is-hidden' if current_page?(root_path) %>"> <div class="control has-icons-left"> <span class="icon is-small is-left"> <i class="fa fa-search"></i> </span> <%= text_field_tag 'q', '', class: "input", placeholder: "どんなお仕事を?" %> </div> <div class="control"> <button class="button is-success" type="submit">検索</button> </div> </div> <% end %> </div> </div> <div class="navbar-end"> <a class="navbar-item"></a> <a class="navbar-item"></a> <!-- もしログインしていなかったら--> <% if (!user_signed_in?) %> <div class="navbar-item"> <div class="buttons"> <%= link_to "新規ユーザ登録", new_user_registration_path, class: "button is-primary" %> <%= link_to "ログイン", new_user_session_path, class: "button is-light" %> </div> </div> <!-- ログインしていたら --> <% else %> <div class="navbar-item has-dropdown is-hoverable"> <a class="navbar-link"> <figure class="image is-48x48 m-r-5 avatar <%= current_user.status ? "online" : "offline" %>"> <div style="margin-top: 0.6rem;"> <%= image_tag avatar_url(current_user), class: "is-rounded" %> </div> </figure> <%= current_user.full_name %> </a> <div class="navbar-dropdown"> <%= link_to 'ダッシュボード', dashboard_path, class: "navbar-item" %> <%= link_to "ユーザ登録情報編集", edit_user_registration_path, class: "navbar-item" %> <hr class="navbar-divider"> <%= link_to "ログアウト", destroy_user_session_path, method: :delete, class: "navbar-item" %> </div> </div> <% end %> </div> </div> </nav> <% if (user_signed_in?) && !current_page?(root_path) && !current_page?(search_path) && !current_page?("/gigs/#{params[:id]}") && !current_page?("/users/#{params[:id]}") %> <nav class="navbar has-shadow" style="z-index: 5;"> <div class="container"> <div class="navbar"> <%= link_to 'ダッシュボード', dashboard_path, class: "navbar-item" %> <%= link_to 'メッセージの確認', conversations_path, class: "navbar-item", data: { turbolinks: false} %> <div class="navbar-item has-dropdown is-hoverable"> <a class="navbar-link">お仕事を売る人</a> <div class="navbar-dropdown"> <%= link_to 'お仕事を登録する', new_gig_path, class: "navbar-item" %> <%= link_to '売れた注文の確認', selling_orders_path, class: "navbar-item" %> <%= link_to 'リクエストを見る', all_requests_path, class: "navbar-item" %> <%= link_to '申込みの確認', my_offers_path, class: "navbar-item" %> <%= link_to '振込口座の登録', settings_payout_path, class: "navbar-item" %> <%= link_to 'カレンダー', calendar_path, class: "navbar-item" %> </div> </div> <div class="navbar-item has-dropdown is-hoverable"> <a class="navbar-link">お仕事を買う人</a> <div class="navbar-dropdown"> <%= link_to '買った注文の確認', buying_orders_path, class: "navbar-item" %> <%= link_to 'お仕事をリクエストする', new_request_path, class: "navbar-item" %> <%= link_to 'リクエストの確認', requests_path, class: "navbar-item" %> <%= link_to 'クレジットカード登録', settings_payment_path, class: "navbar-item", data: { turbolinks: false} %> </div> </div> </div> </div> </nav> <% end %> <script> $(document).ready(function() { // navbar burgerアイコンでクリックイベントを確認する $(".navbar-burger").click(function() { // 「navbar-burger」と「navbar-menu」の両方で「is-active」クラスを切り替える $(".navbar-burger").toggleClass("is-active"); $(".navbar-menu").toggleClass("is-active"); }); }); </script>
ブラウザ確認
http://localhost:3000/calendar
ステータスがお仕事完了になるとカレンダーに買い手の名前が表示されなくなります。
↓↓クリックして頂けると励みになります。
[51]メッセージと会話| コメントへのファイル添付 << [ホームに戻る] >> [53]デプロイ | herokuアカウント