diff --git a/.idea/farmitry_hvac.iml b/.idea/farmitry_hvac.iml
index 529c03a..ef0ceff 100644
--- a/.idea/farmitry_hvac.iml
+++ b/.idea/farmitry_hvac.iml
@@ -53,6 +53,7 @@
+
@@ -66,6 +67,7 @@
+
diff --git a/Gemfile.lock b/Gemfile.lock
index 22dd906..8c08f76 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -129,6 +129,7 @@ GEM
et-orbi (1.2.11)
tzinfo
ffi (1.17.2-aarch64-linux-gnu)
+ ffi (1.17.2-arm64-darwin)
foreman (0.88.1)
fugit (1.11.1)
et-orbi (~> 1, >= 1.2.11)
@@ -192,18 +193,8 @@ GEM
nio4r (2.7.4)
nokogiri (1.18.7-aarch64-linux-gnu)
racc (~> 1.4)
- nokogiri (1.18.7-aarch64-linux-musl)
- racc (~> 1.4)
- nokogiri (1.18.7-arm-linux-gnu)
- racc (~> 1.4)
- nokogiri (1.18.7-arm-linux-musl)
- racc (~> 1.4)
nokogiri (1.18.7-arm64-darwin)
racc (~> 1.4)
- nokogiri (1.18.7-x86_64-linux-gnu)
- racc (~> 1.4)
- nokogiri (1.18.7-x86_64-linux-musl)
- racc (~> 1.4)
ostruct (0.6.1)
parallel (1.27.0)
parser (3.3.8.0)
@@ -328,12 +319,7 @@ GEM
railties (>= 7.1)
thor (~> 1.3.1)
sqlite3 (2.6.0-aarch64-linux-gnu)
- sqlite3 (2.6.0-aarch64-linux-musl)
- sqlite3 (2.6.0-arm-linux-gnu)
- sqlite3 (2.6.0-arm-linux-musl)
sqlite3 (2.6.0-arm64-darwin)
- sqlite3 (2.6.0-x86_64-linux-gnu)
- sqlite3 (2.6.0-x86_64-linux-musl)
sshkit (1.24.0)
base64
logger
@@ -348,7 +334,6 @@ GEM
thruster (0.1.12)
thruster (0.1.12-aarch64-linux)
thruster (0.1.12-arm64-darwin)
- thruster (0.1.12-x86_64-linux)
timeout (0.4.3)
turbo-rails (2.0.13)
actionpack (>= 7.1.0)
@@ -377,13 +362,7 @@ GEM
PLATFORMS
aarch64-linux
aarch64-linux-gnu
- aarch64-linux-musl
- arm-linux-gnu
- arm-linux-musl
arm64-darwin-24
- x86_64-linux
- x86_64-linux-gnu
- x86_64-linux-musl
DEPENDENCIES
amazing_print
diff --git a/app/controllers/modals_controller.rb b/app/controllers/modals_controller.rb
new file mode 100644
index 0000000..37b937e
--- /dev/null
+++ b/app/controllers/modals_controller.rb
@@ -0,0 +1,5 @@
+class ModalsController < ApplicationController
+ def open
+ render partial: "partials/modals_open", locals: { type: params[:type], close_button: params[:close_button] }
+ end
+end
diff --git a/app/helpers/modals_helper.rb b/app/helpers/modals_helper.rb
new file mode 100644
index 0000000..5a44557
--- /dev/null
+++ b/app/helpers/modals_helper.rb
@@ -0,0 +1,2 @@
+module ModalsHelper
+end
diff --git a/app/javascript/controllers/index.js b/app/javascript/controllers/index.js
index e7ee40d..d37ac52 100644
--- a/app/javascript/controllers/index.js
+++ b/app/javascript/controllers/index.js
@@ -7,5 +7,8 @@ import { application } from "./application"
import HelloController from "./hello_controller"
application.register("hello", HelloController)
+import ModalsController from "./modals_controller"
+application.register("modals", ModalsController)
+
import TimerController from "./timer_controller"
application.register("timer", TimerController)
diff --git a/app/javascript/controllers/modals_controller.js b/app/javascript/controllers/modals_controller.js
new file mode 100644
index 0000000..014e1b0
--- /dev/null
+++ b/app/javascript/controllers/modals_controller.js
@@ -0,0 +1,55 @@
+import { Controller } from "@hotwired/stimulus"
+import { useClickOutside } from 'stimulus-use'
+
+// Connects to data-controller="modals"
+export default class extends Controller {
+ connect() {
+ // useClickOutside(this)
+ this.boundHandleKeydown = this.handleKeydown.bind(this)
+ document.addEventListener("keydown", this.boundHandleKeydown)
+ window.addEventListener('modals:close', this.close.bind(this))
+
+ const panelElement = document.getElementById("modals-panel")
+ const backdropElement = document.getElementById("modals-backdrop")
+
+ if (panelElement && backdropElement) {
+ setTimeout(() => {
+ panelElement.classList.remove('opacity-0', 'translate-y-4', 'sm:scale-95')
+ panelElement.classList.add('opacity-100', 'translate-y-0', 'sm:scale-100')
+ backdropElement.classList.remove('opacity-0')
+ backdropElement.classList.add('opacity-75')
+ }, 10) // 애니메이션이 바로 시작되도록 약간의 지연 추가
+ }
+ }
+
+ disconnect() {
+ document.removeEventListener('keydown', this.boundHandleKeydown)
+ }
+
+ handleKeydown(event) {
+ if (event.key === "Escape") {
+ this.close()
+ }
+ }
+
+ close(event) {
+ const panelElement = document.getElementById("modals-panel")
+ const backdropElement = document.getElementById("modals-backdrop")
+
+ if (panelElement && backdropElement) {
+ panelElement.classList.remove("opacity-100", "translate-y-0", "sm:scale-100")
+ panelElement.classList.add("opacity-0", "translate-y-4", "sm:scale-95")
+
+ backdropElement.classList.remove("opacity-75")
+ backdropElement.classList.add("opacity-0")
+
+ setTimeout(() => {
+ const modalsFrame = document.querySelector("turbo-frame#modals")
+ if (modalsFrame) {
+ modalsFrame.innerHTML = ""
+ window.location.reload()
+ }
+ }, 300) // 닫힘 애니메이션 시간과 동일하게 300ms 지연 후 모달 제거
+ }
+ }
+}
diff --git a/app/javascript/controllers/timer_controller.js b/app/javascript/controllers/timer_controller.js
index bde4917..b35678a 100644
--- a/app/javascript/controllers/timer_controller.js
+++ b/app/javascript/controllers/timer_controller.js
@@ -1,4 +1,4 @@
-import { Controller } from "@hotwired/stimulus"
+import {Controller} from "@hotwired/stimulus"
// Connects to data-controller="timer"
export default class extends Controller {
@@ -15,8 +15,7 @@ export default class extends Controller {
updateTime() {
const now = new Date()
- const formatted = `${now.getFullYear()}년 ${String(now.getMonth() + 1).padStart(2, '0')}월 ${String(now.getDate()).padStart(2, '0')}일 ` +
+ this.outputTarget.textContent = `${now.getFullYear()}년 ${String(now.getMonth() + 1).padStart(2, '0')}월 ${String(now.getDate()).padStart(2, '0')}일 ` +
`${String(now.getHours()).padStart(2, '0')}시 ${String(now.getMinutes()).padStart(2, '0')}분 ${String(now.getSeconds()).padStart(2, '0')}초`
- this.outputTarget.textContent = formatted
}
}
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index e94cc54..0e9d66b 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -24,10 +24,10 @@
+<%= turbo_frame_tag :modals %>
<%= render "partials/header" %>
- <%#= render "partials/sidebar" %>
<%= yield %>
diff --git a/app/views/modbus/schedule_edit.html.erb b/app/views/modbus/schedule_edit.html.erb
index 728589d..2bed1d4 100644
--- a/app/views/modbus/schedule_edit.html.erb
+++ b/app/views/modbus/schedule_edit.html.erb
@@ -11,7 +11,9 @@
<% @schedule.each do |s| %>
| <%= s.hour %>시 |
- <%= number_field_tag "schedule[#{s.id}][temperature]", s.temperature, step: "0.1", inputmode: "decimal", class: "border px-2 py-1 rounded" %> °C |
+ <%= number_field_tag "schedule[#{s.id}][temperature]", s.temperature, step: "0.1", inputmode: "decimal", class: "border px-2 py-1 rounded" %>
+ °C
+ |
<% end %>
@@ -22,3 +24,11 @@
<%= submit_tag "업데이트", class: "btn bg-primary" %>
<% end %>
+
+ <%= button_to "추가하기", open_modals_path(type: "add_schedule"),
+ class: "btn btn-default",
+ data: {
+ turbo_method: :post,
+ turbo_frame: "modals"
+ } %>
+
diff --git a/app/views/partials/_header.html.erb b/app/views/partials/_header.html.erb
index c724f8b..ce3e52f 100644
--- a/app/views/partials/_header.html.erb
+++ b/app/views/partials/_header.html.erb
@@ -4,8 +4,4 @@
FARMITRY
-
-
- <%#= link_to "로그아웃", '', class: "btn" %>
-
diff --git a/app/views/partials/_modals_open.html.erb b/app/views/partials/_modals_open.html.erb
new file mode 100644
index 0000000..4631890
--- /dev/null
+++ b/app/views/partials/_modals_open.html.erb
@@ -0,0 +1,44 @@
+<%= turbo_frame_tag :modals do %>
+
+
+
+
+
+
+
+
+
+ <%= render "partials/modals/#{type}" %>
+
+ <% if close_button != "false" %>
+ <%= button_tag type: 'button',
+ data: {
+ action: 'modals#close'
+ },
+ class: 'inline-flex btn w-full' do %>
+
닫기
+ <% end %>
+ <% end %>
+
+
+
+
+<% end %>
diff --git a/app/views/partials/_sidebar.html.erb b/app/views/partials/_sidebar.html.erb
deleted file mode 100644
index 2fe673a..0000000
--- a/app/views/partials/_sidebar.html.erb
+++ /dev/null
@@ -1,42 +0,0 @@
-
diff --git a/app/views/partials/modals/_add_schedule.html.erb b/app/views/partials/modals/_add_schedule.html.erb
new file mode 100644
index 0000000..4f0d83f
--- /dev/null
+++ b/app/views/partials/modals/_add_schedule.html.erb
@@ -0,0 +1 @@
+스케쥴 추가
diff --git a/config/routes.rb b/config/routes.rb
index 788f395..d60f13e 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -20,4 +20,10 @@ Rails.application.routes.draw do
post "schedule_edit_update"
end
end
+
+ resources :modals do
+ collection do
+ post :open
+ end
+ end
end
diff --git a/package.json b/package.json
index 449f108..4f8b589 100644
--- a/package.json
+++ b/package.json
@@ -12,6 +12,7 @@
"@hotwired/stimulus": "^3.2.2",
"@hotwired/turbo-rails": "^8.0.13",
"@tailwindcss/cli": "^4.1.4",
- "tailwindcss": "^4.1.4"
+ "tailwindcss": "^4.1.4",
+ "stimulus-use": "^0.52.2"
}
}
diff --git a/test/controllers/modals_controller_test.rb b/test/controllers/modals_controller_test.rb
new file mode 100644
index 0000000..af6d564
--- /dev/null
+++ b/test/controllers/modals_controller_test.rb
@@ -0,0 +1,7 @@
+require "test_helper"
+
+class ModalsControllerTest < ActionDispatch::IntegrationTest
+ # test "the truth" do
+ # assert true
+ # end
+end
diff --git a/yarn.lock b/yarn.lock
index b853bb2..6a0c7a8 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -571,6 +571,11 @@ picomatch@^2.3.1:
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
+stimulus-use@^0.52.2:
+ version "0.52.3"
+ resolved "https://registry.yarnpkg.com/stimulus-use/-/stimulus-use-0.52.3.tgz#d6f35fa93277274957a2ed98a7b04b4d702cb1d6"
+ integrity sha512-stZ5dID6FUrGCR/ChWUa0FT5Z8iqkzT6lputOAb50eF+Ayg7RzJj4U/HoRlp2NV333QfvoRidru9HLbom4hZVw==
+
tailwindcss@4.1.4, tailwindcss@^4.1.4:
version "4.1.4"
resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-4.1.4.tgz#27b3c910c6f1a47f4540451f3faf7cdd6d977a69"