diff --git a/.iex.exs b/.iex.exs index 052498c3..99529970 100644 --- a/.iex.exs +++ b/.iex.exs @@ -3,5 +3,5 @@ import Ecto.Query alias Shift73k.Repo alias Shift73k.Accounts alias Shift73k.Accounts.User -alias Shift73k.ShiftTemplates, as: STemplates -alias Shift73k.ShiftTemplates.ShiftTemplate, as: STemplate +alias Shift73k.ShiftTemplates +alias Shift73k.ShiftTemplates.ShiftTemplate diff --git a/assets/js/app.js b/assets/js/app.js index 63a63a96..66c975dd 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -5,7 +5,7 @@ import "../css/app.scss"; // Import icons for sprite-loader // navbar brand icon -import "../node_modules/@mdi/svg/svg/skull-crossbones.svg"; // brand +import "../node_modules/bootstrap-icons/icons/calendar3-week.svg"; // brand // menus etc import "../node_modules/bootstrap-icons/icons/person-circle.svg"; // accounts menu import "../node_modules/bootstrap-icons/icons/person-plus.svg"; // new user / register @@ -35,6 +35,9 @@ import "../node_modules/bootstrap-icons/icons/arrow-repeat.svg"; // resend confi import "../node_modules/bootstrap-icons/icons/door-open.svg"; // log in header import "../node_modules/@mdi/svg/svg/head-question-outline.svg"; // forgot password import "../node_modules/bootstrap-icons/icons/people.svg"; // users management +// calendar/event icons +import "../node_modules/bootstrap-icons/icons/calendar3-event.svg"; // brand +import "../node_modules/bootstrap-icons/icons/clock-history.svg"; // brand // webpack automatically bundles all modules in your // entry points. Those entry points can be configured diff --git a/lib/shift73k/shift_templates.ex b/lib/shift73k/shift_templates.ex index cf53408f..c3079102 100644 --- a/lib/shift73k/shift_templates.ex +++ b/lib/shift73k/shift_templates.ex @@ -21,6 +21,11 @@ defmodule Shift73k.ShiftTemplates do Repo.all(ShiftTemplate) end + def list_shift_templates_by_user_id(user_id) do + (from s in ShiftTemplate, where: s.user_id == ^user_id) + |> Repo.all() + end + @doc """ Gets a single shift_template. diff --git a/lib/shift73k/shift_templates/shift_template.ex b/lib/shift73k/shift_templates/shift_template.ex index 48254c9c..a81f5eef 100644 --- a/lib/shift73k/shift_templates/shift_template.ex +++ b/lib/shift73k/shift_templates/shift_template.ex @@ -2,17 +2,20 @@ defmodule Shift73k.ShiftTemplates.ShiftTemplate do use Ecto.Schema import Ecto.Changeset + @app_vars Application.get_env(:shift73k, :app_global_vars, time_zone: "America/New_York") + @time_zone @app_vars[:time_zone] + @primary_key {:id, :binary_id, autogenerate: true} @foreign_key_type :binary_id schema "shift_templates" do field :label, :string - field :subject, :string + field :subject, :string, default: "My Work Shift" field :description, :string field :location, :string - field :timezone, :string - field :start_time, :time - field :length_hours, :integer - field :length_minutes, :integer + field :timezone, :string, default: @time_zone + field :start_time, :time, default: ~T[09:00:00] + field :length_hours, :integer, default: 8 + field :length_minutes, :integer, default: 0 belongs_to(:user, Shift73k.Accounts.User) diff --git a/lib/shift73k_web/live/shift_template_live/index.ex b/lib/shift73k_web/live/shift_template_live/index.ex index 98a311ab..65efc1cc 100644 --- a/lib/shift73k_web/live/shift_template_live/index.ex +++ b/lib/shift73k_web/live/shift_template_live/index.ex @@ -3,15 +3,36 @@ defmodule Shift73kWeb.ShiftTemplateLive.Index do alias Shift73k.ShiftTemplates alias Shift73k.ShiftTemplates.ShiftTemplate + alias Shift73kWeb.Roles @impl true - def mount(_params, _session, socket) do - {:ok, assign(socket, :shift_templates, list_shift_templates())} + def mount(_params, session, socket) do + # {:ok, assign(socket, :shift_templates, list_shift_templates())} + socket + |> assign_defaults(session) + |> live_okreply() end @impl true def handle_params(params, _url, socket) do - {:noreply, apply_action(socket, socket.assigns.live_action, params)} + current_user = socket.assigns.current_user + live_action = socket.assigns.live_action + shift_template = shift_template_from_params(params) + + + if Roles.can?(current_user, shift_template, live_action) do + socket + |> assign_shift_templates() + |> assign(:modal_return_to, Routes.shift_template_index_path(socket, :index)) + |> assign(:delete_shift_template, nil) + |> apply_action(socket.assigns.live_action, params) + |> live_noreply() + else + socket + |> put_flash(:error, "Unauthorised") + |> redirect(to: "/") + |> live_noreply() + end end defp apply_action(socket, :edit, %{"id" => id}) do @@ -32,15 +53,36 @@ defmodule Shift73kWeb.ShiftTemplateLive.Index do |> assign(:shift_template, nil) end + defp assign_shift_templates(socket) do + %User{id: uid} = socket.assigns.current_user + user_shifts = ShiftTemplates.list_shift_templates_by_user_id(uid) + assign(socket, :shift_templates, user_shifts) + end + + defp shift_template_from_params(params) + + defp shift_template_from_params(%{"id" => id}), + do: ShiftTemplates.get_shift_template!(id) + + defp shift_template_from_params(_params), do: %ShiftTemplate{} + + @impl true def handle_event("delete", %{"id" => id}, socket) do shift_template = ShiftTemplates.get_shift_template!(id) {:ok, _} = ShiftTemplates.delete_shift_template(shift_template) - {:noreply, assign(socket, :shift_templates, list_shift_templates())} + {:noreply, assign_shift_templates(socket)} end - defp list_shift_templates do - ShiftTemplates.list_shift_templates() + @impl true + def handle_info({:close_modal, _}, %{assigns: %{modal_return_to: to}} = socket) do + socket |> copy_flash() |> push_patch(to: to) |> live_noreply() end + + @impl true + def handle_info({:put_flash_message, {flash_type, msg}}, socket) do + socket |> put_flash(flash_type, msg) |> live_noreply() + 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 6f92d575..3729b3e4 100644 --- a/lib/shift73k_web/live/shift_template_live/index.html.leex +++ b/lib/shift73k_web/live/shift_template_live/index.html.leex @@ -1,15 +1,24 @@ -

Listing Shift templates

- <%= if @live_action in [:new, :edit] do %> <%= live_modal @socket, Shift73kWeb.ShiftTemplateLive.FormComponent, id: @shift_template.id || :new, title: @page_title, action: @live_action, shift_template: @shift_template, - return_to: Routes.shift_template_index_path(@socket, :index) %> + current_user: @current_user %> <% end %> - + +
+

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

+ <%= live_patch "New Shift Template", to: Routes.shift_template_index_path(@socket, :new), class: "btn btn-primary" %> +
+ + +
+
@@ -18,8 +27,7 @@ - - + @@ -32,9 +40,8 @@ - - - + +
LabelLocation Timezone Start timeLength hoursLength minutesLength
<%= shift_template.description %> <%= shift_template.location %> <%= shift_template.timezone %><%= shift_template.start_time %><%= shift_template.length_hours %><%= shift_template.length_minutes %><%= shift_template.start_time |> Calendar.strftime("%I:%M %p") %><%= shift_template.length_hours %>h <%= shift_template.length_minutes || 0 %>m <%= live_redirect "Show", to: Routes.shift_template_show_path(@socket, :show, shift_template) %> @@ -45,5 +52,4 @@ <% end %>
- -<%= live_patch "New Shift template", to: Routes.shift_template_index_path(@socket, :new) %> + diff --git a/lib/shift73k_web/roles.ex b/lib/shift73k_web/roles.ex index 284730c0..ed8985b3 100644 --- a/lib/shift73k_web/roles.ex +++ b/lib/shift73k_web/roles.ex @@ -4,7 +4,7 @@ defmodule Shift73kWeb.Roles do """ alias Shift73k.Accounts.User - # alias Shift73k.Properties.Property + alias Shift73k.ShiftTemplates.ShiftTemplate @type entity :: struct() @type action :: :new | :index | :edit | :show | :delete | :edit_role @@ -12,13 +12,13 @@ defmodule Shift73kWeb.Roles do def can?(user, entity, action) - # # Properties / Property - # def can?(%User{role: :admin}, %Property{}, _any), do: true - # def can?(%User{}, %Property{}, :index), do: true - # def can?(%User{}, %Property{}, :new), do: true - # def can?(%User{}, %Property{}, :show), do: true - # def can?(%User{id: id}, %Property{user_id: id}, :edit), do: true - # def can?(%User{id: id}, %Property{user_id: id}, :delete), do: true + # ShiftTemplates / ShiftTemplate + def can?(%User{role: :admin}, %ShiftTemplate{}, _any), do: true + def can?(%User{}, %ShiftTemplate{}, :index), do: true + def can?(%User{}, %ShiftTemplate{}, :new), do: true + def can?(%User{}, %ShiftTemplate{}, :show), do: true + def can?(%User{id: id}, %ShiftTemplate{user_id: id}, :edit), do: true + def can?(%User{id: id}, %ShiftTemplate{user_id: id}, :delete), do: true # Accounts / User def can?(%User{role: :admin}, %User{}, _any), do: true diff --git a/lib/shift73k_web/router.ex b/lib/shift73k_web/router.ex index fb7798db..1f929c89 100644 --- a/lib/shift73k_web/router.ex +++ b/lib/shift73k_web/router.ex @@ -91,12 +91,12 @@ defmodule Shift73kWeb.Router do scope "/", Shift73kWeb do pipe_through([:browser, :require_authenticated_user, :user]) - live "/shift_templates", ShiftTemplateLive.Index, :index - live "/shift_templates/new", ShiftTemplateLive.Index, :new - live "/shift_templates/:id/edit", ShiftTemplateLive.Index, :edit + live "/my_shifts", ShiftTemplateLive.Index, :index + live "/my_shifts/new", ShiftTemplateLive.Index, :new + live "/my_shifts/:id/edit", ShiftTemplateLive.Index, :edit - live "/shift_templates/:id", ShiftTemplateLive.Show, :show - live "/shift_templates/:id/show/edit", ShiftTemplateLive.Show, :edit + live "/my_shifts/:id", ShiftTemplateLive.Show, :show + live "/my_shifts/:id/show/edit", ShiftTemplateLive.Show, :edit end # scope "/", Shift73kWeb do diff --git a/lib/shift73k_web/templates/layout/_navbar.html.eex b/lib/shift73k_web/templates/layout/_navbar.html.eex index 431d6b8e..384487f0 100644 --- a/lib/shift73k_web/templates/layout/_navbar.html.eex +++ b/lib/shift73k_web/templates/layout/_navbar.html.eex @@ -3,7 +3,7 @@

<%= link to: Routes.page_path(@conn, :index), class: "navbar-brand fs-4" do %> - <%= icon_div @conn, "mdi-skull-crossbones", [class: "icon baseline fs-3"] %> + <%= icon_div @conn, "bi-calendar3-week", [class: "icon baseline me-1"] %> Shift73k <% end %>