diff --git a/assets/js/app.js b/assets/js/app.js index 326e55d7..e228a03b 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -35,6 +35,7 @@ import "../node_modules/@mdi/svg/svg/head-question-outline.svg"; // forgot passw import "../node_modules/bootstrap-icons/icons/people.svg"; // users management // calendar/event icons import "../node_modules/bootstrap-icons/icons/calendar3-event.svg"; +import "../node_modules/bootstrap-icons/icons/calendar3-range.svg"; import "../node_modules/bootstrap-icons/icons/clock-history.svg"; // shift template import "../node_modules/bootstrap-icons/icons/tag.svg"; import "../node_modules/bootstrap-icons/icons/hourglass.svg"; diff --git a/lib/shift73k/accounts.ex b/lib/shift73k/accounts.ex index 965e3c31..28511d10 100644 --- a/lib/shift73k/accounts.ex +++ b/lib/shift73k/accounts.ex @@ -462,4 +462,15 @@ defmodule Shift73k.Accounts do |> where(id: ^user_id) |> Repo.update_all(set: [fave_shift_template_id: nil]) end + + ## Week Start at + + @doc """ + Sets the "week start at" day for user + """ + def set_user_week_start_at(user_id, day) do + User + |> where(id: ^user_id) + |> Repo.update_all(set: [week_start_at: day]) + end end diff --git a/lib/shift73k/util/dt.ex b/lib/shift73k/util/dt.ex index 31c8c0e8..6f5dfe46 100644 --- a/lib/shift73k/util/dt.ex +++ b/lib/shift73k/util/dt.ex @@ -1,10 +1,6 @@ defmodule Shift73k.Util.Dt do @app_vars Application.get_env(:shift73k, :app_global_vars, time_zone: "America/New_York") - @time_zone @app_vars[:time_zone] + @app_time_zone @app_vars[:time_zone] - def ndt_to_local(%NaiveDateTime{} = ndt), do: DateTime.from_naive(ndt, @time_zone) - - def format_dt_local({:ok, dt_local}, fstr), do: Calendar.strftime(dt_local, fstr) - - def format_ndt(%NaiveDateTime{} = ndt, fstr), do: ndt |> ndt_to_local() |> format_dt_local(fstr) + def app_time_zone, do: @app_time_zone end diff --git a/lib/shift73k_web/live/shift_assign_live/index.ex b/lib/shift73k_web/live/shift_assign_live/index.ex new file mode 100644 index 00000000..527ad622 --- /dev/null +++ b/lib/shift73k_web/live/shift_assign_live/index.ex @@ -0,0 +1,10 @@ +defmodule Shift73kWeb.ShiftAssignLive.Index do + use Shift73kWeb, :live_view + + @impl true + def mount(_params, session, socket) do + socket + |> assign_defaults(session) + |> live_okreply() + end +end diff --git a/lib/shift73k_web/live/shift_assign_live/index.html.leex b/lib/shift73k_web/live/shift_assign_live/index.html.leex new file mode 100644 index 00000000..6ea4a950 --- /dev/null +++ b/lib/shift73k_web/live/shift_assign_live/index.html.leex @@ -0,0 +1,4 @@ +

+ <%= icon_div @socket, "bi-clock-history", [class: "icon baseline"] %> + Assign Shift To Dates +

diff --git a/lib/shift73k_web/live/shift_template_live/delete_component.ex b/lib/shift73k_web/live/shift_template_live/delete_component.ex index 6540d6cb..71205ab3 100644 --- a/lib/shift73k_web/live/shift_template_live/delete_component.ex +++ b/lib/shift73k_web/live/shift_template_live/delete_component.ex @@ -1,5 +1,6 @@ defmodule Shift73kWeb.ShiftTemplateLive.DeleteComponent do use Shift73kWeb, :live_component + use Timex alias Shift73k.Shifts.Templates diff --git a/lib/shift73k_web/live/shift_template_live/delete_component.html.leex b/lib/shift73k_web/live/shift_template_live/delete_component.html.leex index ad6435bd..d43ce9d1 100644 --- a/lib/shift73k_web/live/shift_template_live/delete_component.html.leex +++ b/lib/shift73k_web/live/shift_template_live/delete_component.html.leex @@ -1,9 +1,9 @@ -
Shift length: <%= @shift_length |> elem(0) %>h <%= @shift_length |> elem(1) %>m
+
Shift length: <%= @shift_length %>
<%= error_tag f, :time_start %> diff --git a/lib/shift73k_web/live/shift_template_live/index.ex b/lib/shift73k_web/live/shift_template_live/index.ex index 07f06de1..22ece55f 100644 --- a/lib/shift73k_web/live/shift_template_live/index.ex +++ b/lib/shift73k_web/live/shift_template_live/index.ex @@ -1,5 +1,6 @@ defmodule Shift73kWeb.ShiftTemplateLive.Index do use Shift73kWeb, :live_view + use Timex alias Shift73k.Accounts alias Shift73k.Shifts.Templates @@ -105,4 +106,15 @@ defmodule Shift73kWeb.ShiftTemplateLive.Index do def handle_info({:put_flash_message, {flash_type, msg}}, socket) do socket |> put_flash(flash_type, msg) |> live_noreply() end + + def format_shift_length(shift_template) do + shift_template + |> ShiftTemplate.shift_length() + |> Timex.Duration.from_minutes() + |> Timex.format_duration() + |> String.replace("PT", "") + |> String.replace("H", "h ") + |> String.replace("M", "m") + |> String.trim() + end end diff --git a/lib/shift73k_web/live/shift_template_live/index.html.leex b/lib/shift73k_web/live/shift_template_live/index.html.leex index 501d5f31..56b03aaf 100644 --- a/lib/shift73k_web/live/shift_template_live/index.html.leex +++ b/lib/shift73k_web/live/shift_template_live/index.html.leex @@ -57,13 +57,12 @@ Hours: - <%= template.time_start |> Calendar.strftime("%I:%M%P") %> + <%= template.time_start |> Timex.format!("{h12}:{m}{am}") %> — - <%= template.time_end |> Calendar.strftime("%I:%M%P") %> + <%= template.time_end |> Timex.format!("{h12}:{m}{am}") %> Shift length: - <% shift_len = ShiftTemplate.shift_length_h_m(template) %> - (<%= shift_len |> elem(0) %>h <%= shift_len |> elem(1) %>m) + (<%= format_shift_length(template) %>) TZ: <%= template.time_zone %> diff --git a/lib/shift73k_web/live/user/settings.ex b/lib/shift73k_web/live/user/settings.ex index aa25bbf5..1e48ff26 100644 --- a/lib/shift73k_web/live/user/settings.ex +++ b/lib/shift73k_web/live/user/settings.ex @@ -1,6 +1,7 @@ defmodule Shift73kWeb.UserLive.Settings do use Shift73kWeb, :live_view + alias Shift73k.Accounts alias Shift73k.Accounts.User @impl true @@ -36,4 +37,11 @@ defmodule Shift73kWeb.UserLive.Settings do def handle_info({:clear_flash_message, flash_type}, socket) do socket |> clear_flash(flash_type) |> live_noreply() end + + @impl true + def handle_info({:reload_current_user, _}, socket) do + socket + |> assign(:current_user, Accounts.get_user!(socket.assigns.current_user.id)) + |> live_noreply() + end end diff --git a/lib/shift73k_web/live/user/settings.html.leex b/lib/shift73k_web/live/user/settings.html.leex index a6f31b7d..02da8a24 100644 --- a/lib/shift73k_web/live/user/settings.html.leex +++ b/lib/shift73k_web/live/user/settings.html.leex @@ -9,6 +9,7 @@
<%= live_component @socket, Shift73kWeb.UserLive.Settings.Email, id: "email-#{@current_user.id}", current_user: @current_user %> <%= live_component @socket, Shift73kWeb.UserLive.Settings.Password, id: "password-#{@current_user.id}", current_user: @current_user %> + <%= live_component @socket, Shift73kWeb.UserLive.Settings.WeekStart, id: "week_start-#{@current_user.id}", current_user: @current_user %>
diff --git a/lib/shift73k_web/live/user/settings/week_start.ex b/lib/shift73k_web/live/user/settings/week_start.ex new file mode 100644 index 00000000..d248caac --- /dev/null +++ b/lib/shift73k_web/live/user/settings/week_start.ex @@ -0,0 +1,35 @@ +defmodule Shift73kWeb.UserLive.Settings.WeekStart do + use Shift73kWeb, :live_component + + alias Shift73k.EctoEnums.WeekdayEnum + alias Shift73k.Accounts + # alias Shift73k.Accounts.User + + @impl true + def update(%{current_user: user} = assigns, socket) do + socket + |> assign(id: assigns.id) + |> assign(current_user: user) + |> assign(form_week_start_at: user.week_start_at) + |> live_okreply() + end + + def week_start_options do + WeekdayEnum.__enum_map__() |> Enum.map(fn {d, n} -> {Timex.day_name(n), d} end) + end + + @iml true + def handle_event("changed", %{"calendar_view" => %{"week_start_at" => day}}, socket) do + {:noreply, assign(socket, form_week_start_at: String.to_existing_atom(day))} + end + + @impl true + def handle_event("save", %{"calendar_view" => %{"week_start_at" => day}}, socket) do + Accounts.set_user_week_start_at(socket.assigns.current_user.id, day) + flash_msg = {:info, "Calendar view settings updated."} + send(self(), {:clear_flash_message, :error}) + send(self(), {:put_flash_message, flash_msg}) + send(self(), {:reload_current_user, true}) + {:noreply, socket} + end +end diff --git a/lib/shift73k_web/live/user/settings/week_start.html.leex b/lib/shift73k_web/live/user/settings/week_start.html.leex new file mode 100644 index 00000000..fe95ba87 --- /dev/null +++ b/lib/shift73k_web/live/user/settings/week_start.html.leex @@ -0,0 +1,27 @@ +
+ +

Calendar view

+ + <%= form_for :calendar_view, "#", [phx_change: :changed, phx_submit: :save, phx_target: @myself], fn cvf -> %> + + <%= label cvf, :week_start_at, class: "form-label" %> +
+ <%= icon_div @socket, "bi-calendar3-range", [class: "icon is-left text-muted fs-5"] %> + <%= select cvf, :week_start_at, week_start_options(), + value: @current_user.week_start_at, + class: "form-select" + %> +
+ +
+ <%= submit "Save", + class: "btn btn-primary", + disabled: @form_week_start_at == @current_user.week_start_at, + aria_disabled: (@form_week_start_at == @current_user.week_start_at) && "true" || false, + phx_disable_with: "Saving..." + %> +
+ + <% end %> + +
diff --git a/lib/shift73k_web/live/user_management/index.ex b/lib/shift73k_web/live/user_management/index.ex index 782c7cc4..804fc3f2 100644 --- a/lib/shift73k_web/live/user_management/index.ex +++ b/lib/shift73k_web/live/user_management/index.ex @@ -1,9 +1,10 @@ defmodule Shift73kWeb.UserManagementLive.Index do use Shift73kWeb, :live_view + use Timex import Ecto.Query - import Shift73kWeb.Pagination import Shift73k.Util.Dt + import Shift73kWeb.Pagination alias Shift73k.Repo alias Shift73k.Accounts @@ -187,5 +188,9 @@ defmodule Shift73kWeb.UserManagementLive.Index do ] end - def dt_out(ndt), do: format_ndt(ndt, "%Y %b %d, %I:%M %p") + def dt_out(ndt) do + ndt + |> Timex.to_datetime(app_time_zone()) + |> Timex.format!("{YYYY} {Mshort} {D}, {h12}:{m} {AM}") + end end diff --git a/lib/shift73k_web/router.ex b/lib/shift73k_web/router.ex index eac6e1f1..716513a3 100644 --- a/lib/shift73k_web/router.ex +++ b/lib/shift73k_web/router.ex @@ -96,6 +96,8 @@ defmodule Shift73kWeb.Router do live "/templates/:id/edit", ShiftTemplateLive.Index, :edit live "/templates/:id/clone", ShiftTemplateLive.Index, :clone + live "/assign", ShiftAssignLive.Index, :index + live "/shifts", ShiftLive.Index, :index live "/shifts/new", ShiftLive.Index, :new live "/shifts/:id/edit", ShiftLive.Index, :edit