diff --git a/app/assets/images/svg/svg_logo.svg b/app/assets/images/svg/svg_logo.svg new file mode 100644 index 0000000..89ecf7e --- /dev/null +++ b/app/assets/images/svg/svg_logo.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/app/assets/stylesheets/application.tailwind.css b/app/assets/stylesheets/application.tailwind.css index ade35dc..c8fcea5 100644 --- a/app/assets/stylesheets/application.tailwind.css +++ b/app/assets/stylesheets/application.tailwind.css @@ -2,14 +2,14 @@ @theme { --color-default: rgb(226, 232, 240); - --color-defaultSlate: rgb(100, 116, 139); - --color-defaultSlateDark: rgb(71, 85, 105); + --color-default-slate: rgb(100, 116, 139); + --color-default-slate-dark: rgb(71, 85, 105); --color-primary: rgb(66, 165, 245); --color-notice: rgb(19, 198, 154); --color-warning: rgb(255, 202, 40); --color-accept: rgb(121, 134, 203); --color-danger: rgb(239, 83, 80); - --color-tableBorder: rgb(203, 213, 225); + --color-table-border: rgb(203, 213, 225); --base-font-size: 0.85rem; --text-xs: calc(var(--base-font-size) * 0.75); @@ -42,11 +42,11 @@ @layer base { body { - @apply text-sm text-defaultSlateDark + @apply text-sm text-default-slate-dark } hr { - @apply border-tableBorder + @apply border-table-border } a.disabled { @@ -58,33 +58,41 @@ } .btn { - @apply justify-center rounded-xs bg-defaultSlate px-2 py-0.5 text-sm font-semibold leading-6 text-white + @apply justify-center rounded-md bg-default-slate px-4 py-2 text-sm font-semibold leading-6 text-white shadow-xs hover:opacity-80 cursor-pointer } .card { - @apply bg-white border border-tableBorder rounded-xs shadow-xs + @apply bg-white border border-table-border rounded-xs shadow-xs } /*Form*/ .label-style { - @apply block my-1 font-bold text-defaultSlateDark + @apply block my-1 font-bold text-default-slate-dark } .select-style { - @apply block w-full h-8 px-3 py-1.5 border border-defaultSlate/50 rounded-xs + @apply block w-full h-8 px-3 py-1.5 border border-default-slate/50 rounded-xs } .input-style { - @apply block w-full h-8 px-3 py-1.5 border border-defaultSlate/50 rounded-xs + @apply block w-full h-8 px-3 py-1.5 border border-default-slate/50 rounded-xs } .textarea-style { - @apply block w-full pl-4 flex-1 py-1.5 ring-1 ring-inset ring-defaultSlate/50 rounded-xs + @apply block w-full pl-4 flex-1 py-1.5 ring-1 ring-inset ring-default-slate/50 rounded-xs } } @layer utilities { + .header { + @apply p-4 text-lg font-bold h-16 flex justify-between items-center; + } + + .side-bar { + @apply w-64 px-4 text-lg font-bold divide-y divide-default-slate-dark; + } + .page-title { @apply text-xl font-bold; } @@ -94,7 +102,7 @@ } .form-title { - @apply text-center text-3xl font-bold tracking-tight text-defaultSlateDark + @apply text-center text-3xl font-bold tracking-tight text-default-slate-dark } .field { @@ -107,15 +115,15 @@ /*Menu*/ .menu-group { - @apply py-2 px-4 + @apply flex flex-row py-6 px-4 gap-x-4 justify-between items-center w-full } - .menu-group-title { - @apply py-1 text-sm text-defaultSlateDark font-medium + .menu-group-icon { + @apply py-1 text-sm text-default-slate-dark font-medium justify-center } - .menu-group-items { - @apply p-1 + .menu-group-name { + @apply p-1 flex-1 } .menu-group-items-title { @@ -123,16 +131,16 @@ } .copyright { - @apply text-defaultSlateDark text-center + @apply text-default-slate-dark text-center } /*Pagy*/ .pagy { - @apply flex items-center justify-center space-x-1 font-semibold text-sm text-defaultSlate; + @apply flex items-center justify-center space-x-1 font-semibold text-sm text-default-slate; } .pagy a:not(.gap) { - @apply block rounded-xs px-2 py-1 border border-defaultSlate/50; + @apply block rounded-xs px-2 py-1 border border-default-slate/50; } .pagy a:not(.gap):hover { @@ -140,11 +148,11 @@ } .pagy a:not(.gap):not([href]) { - @apply text-defaultSlate/50 border border-defaultSlate/25 cursor-default + @apply text-default-slate/50 border border-default-slate/25 cursor-default } .pagy a:not(.gap).current { - @apply text-white bg-defaultSlate + @apply text-white bg-default-slate } .pagy a.gap { @@ -161,15 +169,15 @@ /*Base Table*/ .base-table { - @apply min-w-full divide-y divide-tableBorder whitespace-nowrap + @apply min-w-full divide-y divide-table-border whitespace-nowrap border border-table-border } .base-table th { - @apply bg-default px-2 py-2 text-left font-semibold text-defaultSlateDark lg:table-cell + @apply bg-default px-2 py-2 text-left font-semibold text-default-slate-dark lg:table-cell } .base-table td { - @apply border-t border-tableBorder px-2 py-1 text-defaultSlate lg:table-cell whitespace-nowrap + @apply border-t border-table-border px-2 py-1 text-default-slate lg:table-cell whitespace-nowrap } } diff --git a/app/javascript/controllers/index.js b/app/javascript/controllers/index.js index d0685d3..e7ee40d 100644 --- a/app/javascript/controllers/index.js +++ b/app/javascript/controllers/index.js @@ -6,3 +6,6 @@ import { application } from "./application" import HelloController from "./hello_controller" application.register("hello", HelloController) + +import TimerController from "./timer_controller" +application.register("timer", TimerController) diff --git a/app/javascript/controllers/timer_controller.js b/app/javascript/controllers/timer_controller.js new file mode 100644 index 0000000..bde4917 --- /dev/null +++ b/app/javascript/controllers/timer_controller.js @@ -0,0 +1,22 @@ +import { Controller } from "@hotwired/stimulus" + +// Connects to data-controller="timer" +export default class extends Controller { + static targets = ["output"] + + connect() { + this.updateTime() + this.interval = setInterval(() => this.updateTime(), 1000) + } + + disconnect() { + clearInterval(this.interval) + } + + updateTime() { + const now = new Date() + const formatted = `${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 acabb33..2dc8c35 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -20,11 +20,19 @@ <%# Includes all stylesheet files in app/assets/stylesheets %> <%= stylesheet_link_tag :app, "data-turbo-track": "reload" %> <%= javascript_include_tag "application", "data-turbo-track": "reload", type: "module" %> + - -
- <%= yield %> + +
+ <%= render "partials/header" %> +
+ <%= render "partials/sidebar" %> +
+ <%= yield %> +
+
+ diff --git a/app/views/modbus/index.html.erb b/app/views/modbus/index.html.erb index 1e8ec6e..16de25f 100644 --- a/app/views/modbus/index.html.erb +++ b/app/views/modbus/index.html.erb @@ -1,5 +1,3 @@ - - <% if flash[:notice] %>
<%= flash[:notice] %> @@ -9,28 +7,41 @@ <%= flash[:alert] %>
<% end %> +
+
+ + + + + + + + + <% @schedule.each do |s| %> + + + + + <% end %> + +
시간온도
<%= s.hour %>시<%= s.temperature %> °C
+
+
+ <%= button_to "스케쥴러 시작", start_modbus_index_path, method: :post, class: "btn bg-accept" %> + <%= button_to "스케쥴러 정지", stop_modbus_index_path, method: :post, class: "btn bg-danger" %> +
-<% @schedule.each do |s| %> -
-
<%= s.hour %>시
-
<%= s.temperature %> °C
+
+ 스케쥴러 상태: + <% if @modbus_running %> + 실행 중 + <% else %> + 정지됨 + <% end %> +
+
-<% end %> - -
- <%= button_to "수정", schedule_edit_modbus_index_path, method: :get, class: "btn bg-primary" %> -
- -
- <%= button_to "스케쥴러 시작", start_modbus_index_path, method: :post, class: "btn bg-accept" %> - <%= button_to "스케쥴러 정지", stop_modbus_index_path, method: :post, class: "btn bg-danger" %> -
- -
- 스케쥴러 상태: - <% if @modbus_running %> - 실행 중 - <% else %> - 정지됨 - <% end %> -
+
+ <%= link_to "수정", "/modbus/schedule_edit", class: "btn bg-default-slate" %> +
+
\ No newline at end of file diff --git a/app/views/modbus/schedule_edit.html.erb b/app/views/modbus/schedule_edit.html.erb index b2cd467..dfdc53e 100644 --- a/app/views/modbus/schedule_edit.html.erb +++ b/app/views/modbus/schedule_edit.html.erb @@ -1,14 +1,24 @@ -<%= form_with url: schedule_edit_update_modbus_index_path, method: :post do %> - <% @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 -
-
- <% end %> - -
- <%= submit_tag "업데이트", class: "bg-blue-500 text-white px-4 py-2 rounded" %> +<%= form_with url: schedule_edit_update_modbus_index_path, method: :post, class: 'flex flex-col h-full divide-y divide-border-table-border' do %> +
+ + + + + + + + + <% @schedule.each do |s| %> + + + + + <% end %> + +
시간온도
<%= s.hour %>시<%= number_field_tag "schedule[#{s.id}][temperature]", s.temperature, step: "0.1", inputmode: "decimal", class: "border px-2 py-1 rounded" %> °C
-<% end %> + +
+ <%= submit_tag "업데이트", class: "btn bg-primary" %> +
+<% end %> \ No newline at end of file diff --git a/app/views/partials/_header.html.erb b/app/views/partials/_header.html.erb new file mode 100644 index 0000000..0306ecc --- /dev/null +++ b/app/views/partials/_header.html.erb @@ -0,0 +1,11 @@ +
+
+ <%= image_tag "svg/svg_logo.svg", class: "w-16 h-auto" %> +
FARMITRY
+
+
+
+ + <%= link_to "로그아웃", '', class: "btn" %> +
+
\ No newline at end of file diff --git a/app/views/partials/_sidebar.html.erb b/app/views/partials/_sidebar.html.erb new file mode 100644 index 0000000..e8536c3 --- /dev/null +++ b/app/views/partials/_sidebar.html.erb @@ -0,0 +1,42 @@ + \ No newline at end of file