diff --git a/assets/js/app.js b/assets/js/app.js
index 5f83b83e..b9f19848 100644
--- a/assets/js/app.js
+++ b/assets/js/app.js
@@ -56,6 +56,7 @@ import "../node_modules/bootstrap-icons/icons/save.svg";
import "../node_modules/bootstrap-icons/icons/asterisk.svg";
import "../node_modules/bootstrap-icons/icons/card-list.svg";
import "../node_modules/bootstrap-icons/icons/file-earmark-spreadsheet.svg";
+import "../node_modules/bootstrap-icons/icons/box-arrow-in-left.svg";
// webpack automatically bundles all modules in your
// entry points. Those entry points can be configured
diff --git a/lib/shift73k_web/live/shift_import_live/index.ex b/lib/shift73k_web/live/shift_import_live/index.ex
new file mode 100644
index 00000000..9da8abb9
--- /dev/null
+++ b/lib/shift73k_web/live/shift_import_live/index.ex
@@ -0,0 +1,63 @@
+defmodule Shift73kWeb.ShiftImportLive.Index do
+ use Shift73kWeb, :live_view
+
+ @impl true
+ def mount(_params, session, socket) do
+ HTTPoison.start()
+
+ socket
+ |> assign_defaults(session)
+ |> live_okreply()
+ end
+
+ @impl true
+ def handle_event("save", %{"ics_import" => %{"ics_url" => ics_url}}, socket) do
+ ics_url
+ |> IO.inspect(label: "given ical url :")
+ |> HTTPoison.get!()
+ |> handle_http_ics_response(socket)
+ end
+
+ defp handle_http_ics_response(%HTTPoison.Response{status_code: 200} = resp, socket) do
+ case content_type_calendar?(resp.headers) do
+ false ->
+ handle_http_ics_response(false, socket)
+
+ true ->
+ resp.body
+ |> ICalendar.from_ics()
+ |> handle_parsed_ics_data(socket)
+ end
+ end
+
+ defp handle_http_ics_response(_, socket) do
+ socket
+ |> put_flash(:error, "Bad data, bad URL, or some other error")
+ |> live_noreply()
+ end
+
+ defp handle_parsed_ics_data([], socket), do: handle_http_ics_response(false, socket)
+
+ defp handle_parsed_ics_data(events, socket) do
+ IO.inspect(events, label: "We got some ical events! :")
+
+ socket
+ |> put_flash(:success, "We got some ical events")
+ |> live_noreply()
+ end
+
+ def ical_request(ics_url) do
+ # ics_url = "https://calendar.google.com/calendar/ical/l44mcggj2rsoqq7prlakvitqfo%40group.calendar.google.com/private-66f4cf8b340bdd6e9de8c60b2ae36528/basic.ics"
+ end
+
+ defp content_type_calendar?(headers) do
+ headers
+ |> List.keyfind("Content-Type", 0)
+ |> elem(1)
+ |> String.contains?("text/calendar")
+ end
+
+ def shift_from_event(%ICalendar.Event{} = event) do
+ %{}
+ end
+end
diff --git a/lib/shift73k_web/live/shift_import_live/index.html.leex b/lib/shift73k_web/live/shift_import_live/index.html.leex
new file mode 100644
index 00000000..3edf3548
--- /dev/null
+++ b/lib/shift73k_web/live/shift_import_live/index.html.leex
@@ -0,0 +1,35 @@
+
+
+
+
+ <%= icon_div @socket, "bi-box-arrow-in-left", [class: "icon baseline"] %>
+ Import Shifts
+
+
+
If you have an iCal/ics formatted calendar hosted elsewhere, provide its URL here to import its events.
+
+
+
+
+ <%= form_for :ics_import, "#", [phx_submit: "save"], fn iimf -> %>
+
+
+
+ <%= label iimf, :ics_url, "iCal/ics URL", class: "form-label" %>
+ <%= url_input iimf, :ics_url, class: "form-control" %>
+
+
+
+
+
+ <%= submit "Submit", class: "btn btn-primary" %>
+
+
+
+ <% end %>
+
+
+
+
+
+
diff --git a/lib/shift73k_web/router.ex b/lib/shift73k_web/router.ex
index a22c1a95..1cdf67b0 100644
--- a/lib/shift73k_web/router.ex
+++ b/lib/shift73k_web/router.ex
@@ -106,6 +106,8 @@ defmodule Shift73kWeb.Router do
get "/csv", UserShiftsCsvController, :new
post "/csv", UserShiftsCsvController, :export
+
+ live "/import", ShiftImportLive.Index, :index
end
# scope "/", Shift73kWeb do
diff --git a/lib/shift73k_web/templates/layout/navbar/_shifts_menu.html.eex b/lib/shift73k_web/templates/layout/navbar/_shifts_menu.html.eex
index 137f8140..ae472ab1 100644
--- a/lib/shift73k_web/templates/layout/navbar/_shifts_menu.html.eex
+++ b/lib/shift73k_web/templates/layout/navbar/_shifts_menu.html.eex
@@ -34,6 +34,12 @@
CSV Export
<% end %>
+
+ <%= link nav_link_opts(@conn, to: Routes.shift_import_index_path(@conn, :index), class: "dropdown-item") do %>
+ <%= icon_div @conn, "bi-box-arrow-in-left", [class: "icon baseline me-1"] %>
+ iCal Import
+ <% end %>
+
diff --git a/mix.exs b/mix.exs
index 9d064ea5..520ec53b 100644
--- a/mix.exs
+++ b/mix.exs
@@ -53,7 +53,8 @@ defmodule Shift73k.MixProject do
{:scrivener_ecto, "~> 2.0"},
{:tzdata, "~> 1.1"},
{:nimble_csv, "~> 1.0"},
- {:icalendar, "~> 1.1"}
+ {:icalendar, "~> 1.1"},
+ {:httpoison, "~> 1.7"}
]
end
diff --git a/mix.lock b/mix.lock
index 578aa5fe..7149b0ff 100644
--- a/mix.lock
+++ b/mix.lock
@@ -21,6 +21,7 @@
"gettext": {:hex, :gettext, "0.18.2", "7df3ea191bb56c0309c00a783334b288d08a879f53a7014341284635850a6e55", [:mix], [], "hexpm", "f9f537b13d4fdd30f3039d33cb80144c3aa1f8d9698e47d7bcbcc8df93b1f5c5"},
"hackney": {:hex, :hackney, "1.17.4", "99da4674592504d3fb0cfef0db84c3ba02b4508bae2dff8c0108baa0d6e0977c", [:rebar3], [{:certifi, "~>2.6.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~>6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~>1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~>1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "de16ff4996556c8548d512f4dbe22dd58a587bf3332e7fd362430a7ef3986b16"},
"html_entities": {:hex, :html_entities, "0.5.2", "9e47e70598da7de2a9ff6af8758399251db6dbb7eebe2b013f2bbd2515895c3c", [:mix], [], "hexpm", "c53ba390403485615623b9531e97696f076ed415e8d8058b1dbaa28181f4fdcc"},
+ "httpoison": {:hex, :httpoison, "1.8.0", "6b85dea15820b7804ef607ff78406ab449dd78bed923a49c7160e1886e987a3d", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "28089eaa98cf90c66265b6b5ad87c59a3729bea2e74e9d08f9b51eb9729b3c3a"},
"hut": {:hex, :hut, "1.3.0", "71f2f054e657c03f959cf1acc43f436ea87580696528ca2a55c8afb1b06c85e7", [:"erlang.mk", :rebar, :rebar3], [], "hexpm", "7e15d28555d8a1f2b5a3a931ec120af0753e4853a4c66053db354f35bf9ab563"},
"icalendar": {:hex, :icalendar, "1.1.0", "898a8640abb32d161d990e419999004718a7a4b48be31f48db248f90ca33fa6e", [:mix], [{:timex, "~> 3.4", [hex: :timex, repo: "hexpm", optional: false]}], "hexpm", "a131f45fbabd2ee5a22e6bc49ea91e81131158394e7169274cee866263640dca"},
"idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"},