From 09814ac40d16f17b71f03a8fcff39447d0ff083e Mon Sep 17 00:00:00 2001 From: MICHAELMUNAVU83 Date: Tue, 17 Oct 2023 03:46:50 +0300 Subject: [PATCH 01/15] Started add to cart with sockets --- .../live/home_live/cart_component.ex | 24 +++++++++++++++++++ .../live/home_live/index.ex | 15 ++++++++++++ .../live/home_live/index.html.heex | 16 ++++++++++++- lib/elixir_conf_africa_web/router.ex | 1 + 4 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 lib/elixir_conf_africa_web/live/home_live/cart_component.ex diff --git a/lib/elixir_conf_africa_web/live/home_live/cart_component.ex b/lib/elixir_conf_africa_web/live/home_live/cart_component.ex new file mode 100644 index 0000000..73b6218 --- /dev/null +++ b/lib/elixir_conf_africa_web/live/home_live/cart_component.ex @@ -0,0 +1,24 @@ +defmodule ElixirConfAfricaWeb.HomeLive.CartComponent do + use ElixirConfAfricaWeb, :live_component + + @impl true + def render(assigns) do + ~H""" +
+ tvgbhnjmk + test +
+ """ + end + + @impl true + def update(params, socket) do + IO.inspect(socket) + + {:ok, socket} + end + + @impl true + + defp notify_parent(msg), do: send(self(), {__MODULE__, msg}) +end diff --git a/lib/elixir_conf_africa_web/live/home_live/index.ex b/lib/elixir_conf_africa_web/live/home_live/index.ex index 9dfc8d0..9ec563d 100644 --- a/lib/elixir_conf_africa_web/live/home_live/index.ex +++ b/lib/elixir_conf_africa_web/live/home_live/index.ex @@ -9,6 +9,21 @@ defmodule ElixirConfAfricaWeb.HomeLive.Index do {:ok, socket |> assign(:available_tickets, availabe_tickets) + |> assign(:cart, []) |> assign(:event, elixir_conf_africa_event)} end + + def handle_event("add_to_cart", %{"id" => id}, socket) do + if Enum.member?(socket.assigns.cart, String.to_integer(id)) do + {:noreply, + socket + |> put_flash(:error, "Ticket already in cart")} + else + new_cart_items = socket.assigns.cart ++ [String.to_integer(id)] + + {:noreply, + socket + |> assign(:cart, new_cart_items)} + end + end end diff --git a/lib/elixir_conf_africa_web/live/home_live/index.html.heex b/lib/elixir_conf_africa_web/live/home_live/index.html.heex index cec095a..3157508 100644 --- a/lib/elixir_conf_africa_web/live/home_live/index.html.heex +++ b/lib/elixir_conf_africa_web/live/home_live/index.html.heex @@ -124,7 +124,11 @@

KSH <%= ticket_type.price %>

- @@ -141,3 +145,13 @@
+ +<%= if @live_action in [:cart] do %> + <.live_component + module={ElixirConfAfricaWeb.HomeLive.CartComponent} + id="cart" + title="Cart" + action={@live_action} + patch={~p"/ticket_types"} + /> +<% end %> diff --git a/lib/elixir_conf_africa_web/router.ex b/lib/elixir_conf_africa_web/router.ex index b538e48..9d99a7d 100644 --- a/lib/elixir_conf_africa_web/router.ex +++ b/lib/elixir_conf_africa_web/router.ex @@ -20,6 +20,7 @@ defmodule ElixirConfAfricaWeb.Router do get "/", PageController, :home live "/home", HomeLive.Index, :index + live "/home/cart", HomeLive.Index, :cart live "/events", EventLive.Index, :index live "/events/new", EventLive.Index, :new From f5db2d41dcd3980f6263a4de9156aec90a56dc29 Mon Sep 17 00:00:00 2001 From: MICHAELMUNAVU83 Date: Wed, 18 Oct 2023 04:32:50 +0300 Subject: [PATCH 02/15] Added cart in socket --- .../live/home_live/cart_component.ex | 24 -- .../live/home_live/index.ex | 32 ++- .../live/home_live/index.html.heex | 244 +++++++++++++----- lib/elixir_conf_africa_web/router.ex | 1 - 4 files changed, 206 insertions(+), 95 deletions(-) delete mode 100644 lib/elixir_conf_africa_web/live/home_live/cart_component.ex diff --git a/lib/elixir_conf_africa_web/live/home_live/cart_component.ex b/lib/elixir_conf_africa_web/live/home_live/cart_component.ex deleted file mode 100644 index 73b6218..0000000 --- a/lib/elixir_conf_africa_web/live/home_live/cart_component.ex +++ /dev/null @@ -1,24 +0,0 @@ -defmodule ElixirConfAfricaWeb.HomeLive.CartComponent do - use ElixirConfAfricaWeb, :live_component - - @impl true - def render(assigns) do - ~H""" -
- tvgbhnjmk - test -
- """ - end - - @impl true - def update(params, socket) do - IO.inspect(socket) - - {:ok, socket} - end - - @impl true - - defp notify_parent(msg), do: send(self(), {__MODULE__, msg}) -end diff --git a/lib/elixir_conf_africa_web/live/home_live/index.ex b/lib/elixir_conf_africa_web/live/home_live/index.ex index 9ec563d..e9c6877 100644 --- a/lib/elixir_conf_africa_web/live/home_live/index.ex +++ b/lib/elixir_conf_africa_web/live/home_live/index.ex @@ -1,29 +1,53 @@ defmodule ElixirConfAfricaWeb.HomeLive.Index do use ElixirConfAfricaWeb, :live_view alias ElixirConfAfrica.Events + alias ElixirConfAfrica.TicketTypes def mount(_params, _session, socket) do elixir_conf_africa_event = Events.get_elixir_conf_event_and_ticket_types() availabe_tickets = Events.get_all_available_tickets() + cart = [] + total_price = get_total_price(cart) {:ok, socket |> assign(:available_tickets, availabe_tickets) - |> assign(:cart, []) + |> assign(:cart, cart) + |> assign(:total_price, total_price) + |> assign(:page_state, "details") |> assign(:event, elixir_conf_africa_event)} end def handle_event("add_to_cart", %{"id" => id}, socket) do - if Enum.member?(socket.assigns.cart, String.to_integer(id)) do + ticket_type = + TicketTypes.get_ticket_type!(String.to_integer(id)) + |> Map.put(:quantity, 1) + + if Enum.member?(socket.assigns.cart, ticket_type) do {:noreply, socket |> put_flash(:error, "Ticket already in cart")} else - new_cart_items = socket.assigns.cart ++ [String.to_integer(id)] + new_cart_items = [ticket_type | socket.assigns.cart] + total_price = get_total_price(new_cart_items) {:noreply, socket - |> assign(:cart, new_cart_items)} + |> put_flash(:info, "Ticket added to cart") + |> assign(:cart, new_cart_items) + |> assign(:total_price, total_price)} end end + + def handle_event("change_page_state", %{"page_state" => page_state}, socket) do + {:noreply, + socket + |> assign(:page_state, page_state)} + end + + defp get_total_price(cart) do + Enum.reduce(cart, 0, fn ticket_type, acc -> + acc + Decimal.to_integer(ticket_type.price) * ticket_type.quantity + end) + end end diff --git a/lib/elixir_conf_africa_web/live/home_live/index.html.heex b/lib/elixir_conf_africa_web/live/home_live/index.html.heex index 3157508..1330c66 100644 --- a/lib/elixir_conf_africa_web/live/home_live/index.html.heex +++ b/lib/elixir_conf_africa_web/live/home_live/index.html.heex @@ -57,10 +57,18 @@
-

+

Details

-

+

Cart

@@ -72,70 +80,184 @@

-<%!-- navbar --%> -
-
-
-
-

- Event Information -

-
-
-

Start Date

-

<%= @event.start_date %>

-
-
-

End Date

-

<%= @event.start_date %>

+ <%= if @page_state == "details" do %> +
+
+
+

+ Event Information +

+
+
+

Start Date

+

<%= @event.start_date %>

+
+
+

End Date

+

<%= @event.start_date %>

+
+
+

Event Type

+

<%= @event.event_type %>

+
+
+

Available Tickets

+

<%= @available_tickets %>

+
-
-

Event Type

-

<%= @event.event_type %>

+
+

Location

+

<%= @event.location %>

-

Available Tickets

-

<%= @available_tickets %>

+

Hosted by

+

Elixir Conf Africa

-
-

Location

-

<%= @event.location %>

-
-
-

Hosted by

-

Elixir Conf Africa

+
+

Available Tickets

+ +
+ <%= for ticket_type <- @event.ticket_types do %> +
+
+

<%= ticket_type.name %>

+

<%= ticket_type.number %>Tickets

+
+

+ <%= ticket_type.description %> +

+
+

KSH <%= ticket_type.price %>

+
+ + +
+
+
+ <% end %> +
-
-

Available Tickets

+
+ <% else %> +
+
+
+

+ Ticket Cart +

-
- <%= for ticket_type <- @event.ticket_types do %> -
-
-

<%= ticket_type.name %>

-

<%= ticket_type.number %>Tickets

-
-

- <%= ticket_type.description %> + <%= for cart_item <- @cart do %> +

+

+ <%= cart_item.name %>

-
-

KSH <%= ticket_type.price %>

-
- - +
+

+ <%= cart_item.price %> +

+
+
+

+ Who is this ticket for ? +

+ +
+ <% end %> + +
+

Total Amount

+

<%= @total_price %>

+
+
+

+ Checkout +

+
+
+
+

+ Ticket Overview +

+ + <%= for cart_item <- @cart do %> +

Early Bird Ticket

+
+

+ +

+
+
+ +

+ Elixir Safari +

+
+
+ +
+
+
+

Name:

+

Otieno

+
+
+

Country:

+

kenya

+
+
+
+

20th June 2024

+

+

20th June 2024

+
+
+
+

+ Ticket Value +

+

+ <%= cart_item.price %> +

+
+
+
+ +
@@ -143,15 +265,5 @@
-
+ <% end %>
- -<%= if @live_action in [:cart] do %> - <.live_component - module={ElixirConfAfricaWeb.HomeLive.CartComponent} - id="cart" - title="Cart" - action={@live_action} - patch={~p"/ticket_types"} - /> -<% end %> diff --git a/lib/elixir_conf_africa_web/router.ex b/lib/elixir_conf_africa_web/router.ex index 9d99a7d..b538e48 100644 --- a/lib/elixir_conf_africa_web/router.ex +++ b/lib/elixir_conf_africa_web/router.ex @@ -20,7 +20,6 @@ defmodule ElixirConfAfricaWeb.Router do get "/", PageController, :home live "/home", HomeLive.Index, :index - live "/home/cart", HomeLive.Index, :cart live "/events", EventLive.Index, :index live "/events/new", EventLive.Index, :new From 0145e70e2f6821dfbc3ce88062f4f36866b4a551 Mon Sep 17 00:00:00 2001 From: MICHAELMUNAVU83 Date: Wed, 18 Oct 2023 04:39:26 +0300 Subject: [PATCH 03/15] Refractored pipe function --- lib/elixir_conf_africa/ticket_types.ex | 5 +++++ lib/elixir_conf_africa_web/live/home_live/index.ex | 6 ++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/elixir_conf_africa/ticket_types.ex b/lib/elixir_conf_africa/ticket_types.ex index bba0b1f..e20f843 100644 --- a/lib/elixir_conf_africa/ticket_types.ex +++ b/lib/elixir_conf_africa/ticket_types.ex @@ -21,6 +21,11 @@ defmodule ElixirConfAfrica.TicketTypes do Repo.all(TicketType) end + def add_quantity(ticket_type, quantity) do + ticket_type + |> Map.put(:quantity, quantity) + end + @doc """ Gets a single ticket_type. diff --git a/lib/elixir_conf_africa_web/live/home_live/index.ex b/lib/elixir_conf_africa_web/live/home_live/index.ex index e9c6877..ff7c585 100644 --- a/lib/elixir_conf_africa_web/live/home_live/index.ex +++ b/lib/elixir_conf_africa_web/live/home_live/index.ex @@ -20,8 +20,10 @@ defmodule ElixirConfAfricaWeb.HomeLive.Index do def handle_event("add_to_cart", %{"id" => id}, socket) do ticket_type = - TicketTypes.get_ticket_type!(String.to_integer(id)) - |> Map.put(:quantity, 1) + id + |> String.to_integer() + |> TicketTypes.get_ticket_type!() + |> TicketTypes.add_quantity(1) if Enum.member?(socket.assigns.cart, ticket_type) do {:noreply, From 4c9027d6025a2bd64ab09217e5afc611ce5599a3 Mon Sep 17 00:00:00 2001 From: MICHAELMUNAVU83 Date: Tue, 17 Oct 2023 03:46:50 +0300 Subject: [PATCH 04/15] Started add to cart with sockets --- .../live/home_live/cart_component.ex | 24 +++++++++++++++++++ .../live/home_live/index.ex | 15 ++++++++++++ .../live/home_live/index.html.heex | 16 ++++++++++++- lib/elixir_conf_africa_web/router.ex | 1 + 4 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 lib/elixir_conf_africa_web/live/home_live/cart_component.ex diff --git a/lib/elixir_conf_africa_web/live/home_live/cart_component.ex b/lib/elixir_conf_africa_web/live/home_live/cart_component.ex new file mode 100644 index 0000000..73b6218 --- /dev/null +++ b/lib/elixir_conf_africa_web/live/home_live/cart_component.ex @@ -0,0 +1,24 @@ +defmodule ElixirConfAfricaWeb.HomeLive.CartComponent do + use ElixirConfAfricaWeb, :live_component + + @impl true + def render(assigns) do + ~H""" +
+ tvgbhnjmk + test +
+ """ + end + + @impl true + def update(params, socket) do + IO.inspect(socket) + + {:ok, socket} + end + + @impl true + + defp notify_parent(msg), do: send(self(), {__MODULE__, msg}) +end diff --git a/lib/elixir_conf_africa_web/live/home_live/index.ex b/lib/elixir_conf_africa_web/live/home_live/index.ex index 9dfc8d0..9ec563d 100644 --- a/lib/elixir_conf_africa_web/live/home_live/index.ex +++ b/lib/elixir_conf_africa_web/live/home_live/index.ex @@ -9,6 +9,21 @@ defmodule ElixirConfAfricaWeb.HomeLive.Index do {:ok, socket |> assign(:available_tickets, availabe_tickets) + |> assign(:cart, []) |> assign(:event, elixir_conf_africa_event)} end + + def handle_event("add_to_cart", %{"id" => id}, socket) do + if Enum.member?(socket.assigns.cart, String.to_integer(id)) do + {:noreply, + socket + |> put_flash(:error, "Ticket already in cart")} + else + new_cart_items = socket.assigns.cart ++ [String.to_integer(id)] + + {:noreply, + socket + |> assign(:cart, new_cart_items)} + end + end end diff --git a/lib/elixir_conf_africa_web/live/home_live/index.html.heex b/lib/elixir_conf_africa_web/live/home_live/index.html.heex index cec095a..3157508 100644 --- a/lib/elixir_conf_africa_web/live/home_live/index.html.heex +++ b/lib/elixir_conf_africa_web/live/home_live/index.html.heex @@ -124,7 +124,11 @@

KSH <%= ticket_type.price %>

- @@ -141,3 +145,13 @@
+ +<%= if @live_action in [:cart] do %> + <.live_component + module={ElixirConfAfricaWeb.HomeLive.CartComponent} + id="cart" + title="Cart" + action={@live_action} + patch={~p"/ticket_types"} + /> +<% end %> diff --git a/lib/elixir_conf_africa_web/router.ex b/lib/elixir_conf_africa_web/router.ex index b538e48..9d99a7d 100644 --- a/lib/elixir_conf_africa_web/router.ex +++ b/lib/elixir_conf_africa_web/router.ex @@ -20,6 +20,7 @@ defmodule ElixirConfAfricaWeb.Router do get "/", PageController, :home live "/home", HomeLive.Index, :index + live "/home/cart", HomeLive.Index, :cart live "/events", EventLive.Index, :index live "/events/new", EventLive.Index, :new From 9ad48f1b5646ff1872b0f17f77ca47be77a650d5 Mon Sep 17 00:00:00 2001 From: MICHAELMUNAVU83 Date: Wed, 18 Oct 2023 04:32:50 +0300 Subject: [PATCH 05/15] Added cart in socket --- .../live/home_live/cart_component.ex | 24 -- .../live/home_live/index.ex | 32 ++- .../live/home_live/index.html.heex | 244 +++++++++++++----- lib/elixir_conf_africa_web/router.ex | 1 - 4 files changed, 206 insertions(+), 95 deletions(-) delete mode 100644 lib/elixir_conf_africa_web/live/home_live/cart_component.ex diff --git a/lib/elixir_conf_africa_web/live/home_live/cart_component.ex b/lib/elixir_conf_africa_web/live/home_live/cart_component.ex deleted file mode 100644 index 73b6218..0000000 --- a/lib/elixir_conf_africa_web/live/home_live/cart_component.ex +++ /dev/null @@ -1,24 +0,0 @@ -defmodule ElixirConfAfricaWeb.HomeLive.CartComponent do - use ElixirConfAfricaWeb, :live_component - - @impl true - def render(assigns) do - ~H""" -
- tvgbhnjmk - test -
- """ - end - - @impl true - def update(params, socket) do - IO.inspect(socket) - - {:ok, socket} - end - - @impl true - - defp notify_parent(msg), do: send(self(), {__MODULE__, msg}) -end diff --git a/lib/elixir_conf_africa_web/live/home_live/index.ex b/lib/elixir_conf_africa_web/live/home_live/index.ex index 9ec563d..e9c6877 100644 --- a/lib/elixir_conf_africa_web/live/home_live/index.ex +++ b/lib/elixir_conf_africa_web/live/home_live/index.ex @@ -1,29 +1,53 @@ defmodule ElixirConfAfricaWeb.HomeLive.Index do use ElixirConfAfricaWeb, :live_view alias ElixirConfAfrica.Events + alias ElixirConfAfrica.TicketTypes def mount(_params, _session, socket) do elixir_conf_africa_event = Events.get_elixir_conf_event_and_ticket_types() availabe_tickets = Events.get_all_available_tickets() + cart = [] + total_price = get_total_price(cart) {:ok, socket |> assign(:available_tickets, availabe_tickets) - |> assign(:cart, []) + |> assign(:cart, cart) + |> assign(:total_price, total_price) + |> assign(:page_state, "details") |> assign(:event, elixir_conf_africa_event)} end def handle_event("add_to_cart", %{"id" => id}, socket) do - if Enum.member?(socket.assigns.cart, String.to_integer(id)) do + ticket_type = + TicketTypes.get_ticket_type!(String.to_integer(id)) + |> Map.put(:quantity, 1) + + if Enum.member?(socket.assigns.cart, ticket_type) do {:noreply, socket |> put_flash(:error, "Ticket already in cart")} else - new_cart_items = socket.assigns.cart ++ [String.to_integer(id)] + new_cart_items = [ticket_type | socket.assigns.cart] + total_price = get_total_price(new_cart_items) {:noreply, socket - |> assign(:cart, new_cart_items)} + |> put_flash(:info, "Ticket added to cart") + |> assign(:cart, new_cart_items) + |> assign(:total_price, total_price)} end end + + def handle_event("change_page_state", %{"page_state" => page_state}, socket) do + {:noreply, + socket + |> assign(:page_state, page_state)} + end + + defp get_total_price(cart) do + Enum.reduce(cart, 0, fn ticket_type, acc -> + acc + Decimal.to_integer(ticket_type.price) * ticket_type.quantity + end) + end end diff --git a/lib/elixir_conf_africa_web/live/home_live/index.html.heex b/lib/elixir_conf_africa_web/live/home_live/index.html.heex index 3157508..1330c66 100644 --- a/lib/elixir_conf_africa_web/live/home_live/index.html.heex +++ b/lib/elixir_conf_africa_web/live/home_live/index.html.heex @@ -57,10 +57,18 @@
-

+

Details

-

+

Cart

@@ -72,70 +80,184 @@

-<%!-- navbar --%> -
-
-
-
-

- Event Information -

-
-
-

Start Date

-

<%= @event.start_date %>

-
-
-

End Date

-

<%= @event.start_date %>

+ <%= if @page_state == "details" do %> +
+
+
+

+ Event Information +

+
+
+

Start Date

+

<%= @event.start_date %>

+
+
+

End Date

+

<%= @event.start_date %>

+
+
+

Event Type

+

<%= @event.event_type %>

+
+
+

Available Tickets

+

<%= @available_tickets %>

+
-
-

Event Type

-

<%= @event.event_type %>

+
+

Location

+

<%= @event.location %>

-

Available Tickets

-

<%= @available_tickets %>

+

Hosted by

+

Elixir Conf Africa

-
-

Location

-

<%= @event.location %>

-
-
-

Hosted by

-

Elixir Conf Africa

+
+

Available Tickets

+ +
+ <%= for ticket_type <- @event.ticket_types do %> +
+
+

<%= ticket_type.name %>

+

<%= ticket_type.number %>Tickets

+
+

+ <%= ticket_type.description %> +

+
+

KSH <%= ticket_type.price %>

+
+ + +
+
+
+ <% end %> +
-
-

Available Tickets

+
+ <% else %> +
+
+
+

+ Ticket Cart +

-
- <%= for ticket_type <- @event.ticket_types do %> -
-
-

<%= ticket_type.name %>

-

<%= ticket_type.number %>Tickets

-
-

- <%= ticket_type.description %> + <%= for cart_item <- @cart do %> +

+

+ <%= cart_item.name %>

-
-

KSH <%= ticket_type.price %>

-
- - +
+

+ <%= cart_item.price %> +

+
+
+

+ Who is this ticket for ? +

+ +
+ <% end %> + +
+

Total Amount

+

<%= @total_price %>

+
+
+

+ Checkout +

+
+
+
+

+ Ticket Overview +

+ + <%= for cart_item <- @cart do %> +

Early Bird Ticket

+
+

+ +

+
+
+ +

+ Elixir Safari +

+
+
+ +
+
+
+

Name:

+

Otieno

+
+
+

Country:

+

kenya

+
+
+
+

20th June 2024

+

+

20th June 2024

+
+
+
+

+ Ticket Value +

+

+ <%= cart_item.price %> +

+
+
+
+ +
@@ -143,15 +265,5 @@
-
+ <% end %>
- -<%= if @live_action in [:cart] do %> - <.live_component - module={ElixirConfAfricaWeb.HomeLive.CartComponent} - id="cart" - title="Cart" - action={@live_action} - patch={~p"/ticket_types"} - /> -<% end %> diff --git a/lib/elixir_conf_africa_web/router.ex b/lib/elixir_conf_africa_web/router.ex index 9d99a7d..b538e48 100644 --- a/lib/elixir_conf_africa_web/router.ex +++ b/lib/elixir_conf_africa_web/router.ex @@ -20,7 +20,6 @@ defmodule ElixirConfAfricaWeb.Router do get "/", PageController, :home live "/home", HomeLive.Index, :index - live "/home/cart", HomeLive.Index, :cart live "/events", EventLive.Index, :index live "/events/new", EventLive.Index, :new From 04d166b31d1d1ae6c13e6862ac2913f3a28f184b Mon Sep 17 00:00:00 2001 From: MICHAELMUNAVU83 Date: Wed, 18 Oct 2023 04:39:26 +0300 Subject: [PATCH 06/15] Refractored pipe function --- lib/elixir_conf_africa/ticket_types.ex | 5 +++++ lib/elixir_conf_africa_web/live/home_live/index.ex | 6 ++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/elixir_conf_africa/ticket_types.ex b/lib/elixir_conf_africa/ticket_types.ex index bba0b1f..e20f843 100644 --- a/lib/elixir_conf_africa/ticket_types.ex +++ b/lib/elixir_conf_africa/ticket_types.ex @@ -21,6 +21,11 @@ defmodule ElixirConfAfrica.TicketTypes do Repo.all(TicketType) end + def add_quantity(ticket_type, quantity) do + ticket_type + |> Map.put(:quantity, quantity) + end + @doc """ Gets a single ticket_type. diff --git a/lib/elixir_conf_africa_web/live/home_live/index.ex b/lib/elixir_conf_africa_web/live/home_live/index.ex index e9c6877..ff7c585 100644 --- a/lib/elixir_conf_africa_web/live/home_live/index.ex +++ b/lib/elixir_conf_africa_web/live/home_live/index.ex @@ -20,8 +20,10 @@ defmodule ElixirConfAfricaWeb.HomeLive.Index do def handle_event("add_to_cart", %{"id" => id}, socket) do ticket_type = - TicketTypes.get_ticket_type!(String.to_integer(id)) - |> Map.put(:quantity, 1) + id + |> String.to_integer() + |> TicketTypes.get_ticket_type!() + |> TicketTypes.add_quantity(1) if Enum.member?(socket.assigns.cart, ticket_type) do {:noreply, From e0af9fe1e69093563017e3276fbc4752a2e01433 Mon Sep 17 00:00:00 2001 From: MICHAELMUNAVU83 Date: Thu, 16 Nov 2023 06:26:53 +0300 Subject: [PATCH 07/15] added cart context files --- lib/elixir_conf_africa/cart.ex | 60 +++++ .../live/home_live/index.ex | 49 ++-- .../live/home_live/index.html.heex | 232 ++++-------------- 3 files changed, 133 insertions(+), 208 deletions(-) create mode 100644 lib/elixir_conf_africa/cart.ex diff --git a/lib/elixir_conf_africa/cart.ex b/lib/elixir_conf_africa/cart.ex new file mode 100644 index 0000000..3120dfc --- /dev/null +++ b/lib/elixir_conf_africa/cart.ex @@ -0,0 +1,60 @@ +defmodule ElixirConfAfrica.Cart do + @moduledoc """ + The cart module + """ + + alias ElixirConfAfrica.TicketTypes + + def cart_list_ids(cart) do + cart |> Enum.map(fn cart_item -> cart_item.id end) + end + + def add_quantity_to_cart_item(cart_item, quantity) do + cart_item + |> Map.put(:quantity, quantity) + end + + def add_to_cart(cart, cart_item_id) do + cart_list_ids = cart_list_ids(cart) + + case Enum.member?(cart_list_ids, cart_item_id) do + true -> + ticket_type = Enum.find(cart, fn item -> item.id == cart_item_id end) + updated_cart = get_updated_cart("in-cart", ticket_type, cart) + + false -> + ticket_type = TicketTypes.get_ticket_type!(cart_item_id) + updated_cart = get_updated_cart("out-of-cart", ticket_type, cart) + end + end + + def get_updated_cart("in-cart", cart_item, cart) do + cart_item_with_added_quantity = + add_quantity_to_cart_item(cart, cart_item, cart_item.quantity + 1) + + cart + |> Enum.filter(fn item -> item.id != cart_item.id end) + |> Enum.concat([cart_item_with_added_quantity]) + end + + def get_updated_cart("out-of-cart", cart_item, cart) do + cart_item_with_default_quantity_of_one = + add_quantity_to_cart_item(cart, cart_item, 1) + + [cart_item_with_default_quantity_of_one | cart] + end + + def add_quantity_to_cart_item(cart, cart_item, quantity) do + case cart |> Enum.filter(fn item -> item.id == cart_item.id end) do + [] -> + cart_item + |> Map.put(:quantity, quantity) + + _ -> + cart + |> Enum.filter(fn item -> item.id == cart_item.id end) + |> Enum.map(fn item -> add_quantity_to_cart_item(item, item.quantity + 1) end) + |> List.first() + end + end +end diff --git a/lib/elixir_conf_africa_web/live/home_live/index.ex b/lib/elixir_conf_africa_web/live/home_live/index.ex index 144a3ca..66509c9 100644 --- a/lib/elixir_conf_africa_web/live/home_live/index.ex +++ b/lib/elixir_conf_africa_web/live/home_live/index.ex @@ -2,22 +2,21 @@ defmodule ElixirConfAfricaWeb.HomeLive.Index do use ElixirConfAfricaWeb, :live_view alias ElixirConfAfrica.Events alias ElixirConfAfrica.TicketTypes + alias ElixirConfAfrica.Cart def mount(_params, _session, socket) do - event_name = "ElixirConf Africa #{get_current_year()}" + event_name = "ElixirConf Africa #{get_upcoming_year()}" event = Events.get_event_with_ticket_types_by_event_name(event_name) - available_ticket = Events.get_total_number_of_available_tickets(event_name) - - cart = [] - total_price = get_total_price(cart) + available_tickets = Events.get_total_number_of_available_tickets(event_name) {:ok, socket - |> assign(:event, event)} - |> assign(available_ticket: available_ticket) + |> assign(:event, event) + |> assign(:cart, []) + |> assign(available_tickets: available_tickets)} end defp get_current_year do @@ -25,38 +24,28 @@ defmodule ElixirConfAfricaWeb.HomeLive.Index do year end + defp get_upcoming_year do + %{year: year} = DateTime.utc_now() + year + 1 + end + def handle_event("add_to_cart", %{"id" => id}, socket) do - ticket_type = - id - |> String.to_integer() - |> TicketTypes.get_ticket_type!() - |> TicketTypes.add_quantity(1) + cart_item_ids = Cart.cart_list_ids(socket.assigns.cart) + + if Enum.member?(cart_item_ids, String.to_integer(id)) do + updated_cart = Cart.add_to_cart(socket.assigns.cart, String.to_integer(id)) - if Enum.member?(socket.assigns.cart, ticket_type) do {:noreply, socket - |> put_flash(:error, "Ticket already in cart")} + |> assign(:cart, updated_cart) + |> put_flash(:info, "Ticket already in cart , quantity increased by 1")} else - new_cart_items = [ticket_type | socket.assigns.cart] - total_price = get_total_price(new_cart_items) + updated_cart = Cart.add_to_cart(socket.assigns.cart, String.to_integer(id)) {:noreply, socket |> put_flash(:info, "Ticket added to cart") - |> assign(:cart, new_cart_items) - |> assign(:total_price, total_price)} + |> assign(:cart, updated_cart)} end end - - def handle_event("change_page_state", %{"page_state" => page_state}, socket) do - {:noreply, - socket - |> assign(:page_state, page_state)} - end - - defp get_total_price(cart) do - Enum.reduce(cart, 0, fn ticket_type, acc -> - acc + Decimal.to_integer(ticket_type.price) * ticket_type.quantity - end) - end end diff --git a/lib/elixir_conf_africa_web/live/home_live/index.html.heex b/lib/elixir_conf_africa_web/live/home_live/index.html.heex index 1330c66..019aa32 100644 --- a/lib/elixir_conf_africa_web/live/home_live/index.html.heex +++ b/lib/elixir_conf_africa_web/live/home_live/index.html.heex @@ -57,18 +57,10 @@
-

+

Details

-

+

Cart

@@ -81,183 +73,67 @@

- <%= if @page_state == "details" do %> -
-
-
-

- Event Information -

-
-
-

Start Date

-

<%= @event.start_date %>

-
-
-

End Date

-

<%= @event.start_date %>

-
-
-

Event Type

-

<%= @event.event_type %>

-
-
-

Available Tickets

-

<%= @available_tickets %>

-
+
+
+
+

+ Event Information +

+
+
+

Start Date

+

<%= @event.start_date %>

-
-

Location

-

<%= @event.location %>

+
+

End Date

+

<%= @event.start_date %>

-

Hosted by

-

Elixir Conf Africa

+

Event Type

+

<%= @event.event_type %>

-
-
-

Available Tickets

- -
- <%= for ticket_type <- @event.ticket_types do %> -
-
-

<%= ticket_type.name %>

-

<%= ticket_type.number %>Tickets

-
-

- <%= ticket_type.description %> -

-
-

KSH <%= ticket_type.price %>

-
- - -
-
-
- <% end %> +
+

Available Tickets

+

<%= @available_tickets %>

+
+

Location

+

<%= @event.location %>

+
+
+

Hosted by

+

Elixir Conf Africa

+
-
- <% else %> -
-
-
-

- Ticket Cart -

+
+

Available Tickets

- <%= for cart_item <- @cart do %> -
-

- <%= cart_item.name %> -

-
-
-

- This ticket gives you access to the 3-day in-person event at - the Jua Kali Avenue, Nairobi -

- -
-
-
-

-

-

<%= cart_item.quantity %>

-

+

-
-

- <%= cart_item.price %> -

-
+
+ <%= for ticket_type <- @event.ticket_types do %> +
+
+

<%= ticket_type.name %>

+

<%= ticket_type.number %>Tickets

-

- Who is this ticket for ? -

- -
- <% end %> - -
-

Total Amount

-

<%= @total_price %>

-
-
-

- Checkout -

-
-
-
-

- Ticket Overview -

- - <%= for cart_item <- @cart do %> -

Early Bird Ticket

-
-

- +

+ <%= ticket_type.description %>

-
-
- -

- Elixir Safari -

-
-
- -
-
-
-

Name:

-

Otieno

-
-
-

Country:

-

kenya

-
-
-
-

20th June 2024

-

-

20th June 2024

-
-
-
-

- Ticket Value -

-

- <%= cart_item.price %> -

-
-
-
- - +
+

KSH <%= ticket_type.price %>

+
+ +
@@ -265,5 +141,5 @@
- <% end %> +
From 63bdb46adf74b1e80bc3b2673925890a1a948311 Mon Sep 17 00:00:00 2001 From: MICHAELMUNAVU83 Date: Thu, 16 Nov 2023 07:02:50 +0300 Subject: [PATCH 08/15] added context tests for the cart module --- lib/elixir_conf_africa/cart.ex | 7 ++-- test/elixir_conf_africa/cart_test.exs | 51 +++++++++++++++++++++++++ test/elixir_conf_africa/events_test.exs | 2 +- 3 files changed, 55 insertions(+), 5 deletions(-) create mode 100644 test/elixir_conf_africa/cart_test.exs diff --git a/lib/elixir_conf_africa/cart.ex b/lib/elixir_conf_africa/cart.ex index 3120dfc..30d7e71 100644 --- a/lib/elixir_conf_africa/cart.ex +++ b/lib/elixir_conf_africa/cart.ex @@ -9,7 +9,7 @@ defmodule ElixirConfAfrica.Cart do cart |> Enum.map(fn cart_item -> cart_item.id end) end - def add_quantity_to_cart_item(cart_item, quantity) do + def increase_cart_item_quantity(cart_item, quantity) do cart_item |> Map.put(:quantity, quantity) end @@ -47,13 +47,12 @@ defmodule ElixirConfAfrica.Cart do def add_quantity_to_cart_item(cart, cart_item, quantity) do case cart |> Enum.filter(fn item -> item.id == cart_item.id end) do [] -> - cart_item - |> Map.put(:quantity, quantity) + increase_cart_item_quantity(cart_item, quantity) _ -> cart |> Enum.filter(fn item -> item.id == cart_item.id end) - |> Enum.map(fn item -> add_quantity_to_cart_item(item, item.quantity + 1) end) + |> Enum.map(fn item -> increase_cart_item_quantity(item, item.quantity + 1) end) |> List.first() end end diff --git a/test/elixir_conf_africa/cart_test.exs b/test/elixir_conf_africa/cart_test.exs new file mode 100644 index 0000000..d445e77 --- /dev/null +++ b/test/elixir_conf_africa/cart_test.exs @@ -0,0 +1,51 @@ +defmodule ElixirConfAfrica.CartTest do + use ElixirConfAfrica.DataCase + alias ElixirConfAfrica.Cart + + describe "Cart Functionaity" do + import ElixirConfAfrica.Factory + + setup do + event = insert!(:elixir_conf_event) + ticket_type = insert!(:elixir_conf_ticket_type, event_id: event.id) + + [ticket_type: ticket_type] + end + + test "cart_list_ids/1 returns all ids from the carts in a list" do + assert Cart.cart_list_ids([%{id: 1}, %{id: 2}]) == [1, 2] + end + + test "increase_cart_item_quantity/2 increases the quantity of a cart item" do + assert Cart.increase_cart_item_quantity(%{quantity: 1}, 2) == %{quantity: 2} + end + + test "add quantity to cart_item/3 returns the cart item with an increased quantity " do + assert Cart.add_quantity_to_cart_item([%{id: 1, quantity: 1}], %{id: 1, quantity: 1}, 2) == + %{id: 1, quantity: 2} + + assert Cart.add_quantity_to_cart_item([%{id: 1, quantity: 1}], %{id: 2}, 1) == + %{id: 2, quantity: 1} + end + + test "get_updated_cart/3 returns the updated cart" do + assert Cart.get_updated_cart("in-cart", %{id: 1, quantity: 1}, [%{id: 1, quantity: 1}]) == + [%{id: 1, quantity: 2}] + + assert Cart.get_updated_cart("out-of-cart", %{id: 2}, [%{id: 1, quantity: 1}]) == + [%{id: 2, quantity: 1}, %{id: 1, quantity: 1}] + end + + test "add_to_cart/2 adds an item to the cart", %{ticket_type: ticket_type} do + assert Cart.add_to_cart([%{id: 1, quantity: 1}, %{id: 2, quantity: 1}], 1) == + [%{id: 2, quantity: 1}, %{id: 1, quantity: 2}] + + assert Cart.add_to_cart([%{id: 1, quantity: 1}, %{id: 2, quantity: 1}], ticket_type.id) == + [ + ticket_type |> Map.put(:quantity, 1), + %{id: 1, quantity: 1}, + %{id: 2, quantity: 1} + ] + end + end +end diff --git a/test/elixir_conf_africa/events_test.exs b/test/elixir_conf_africa/events_test.exs index db27efe..ab3f5e5 100644 --- a/test/elixir_conf_africa/events_test.exs +++ b/test/elixir_conf_africa/events_test.exs @@ -8,7 +8,7 @@ defmodule ElixirConfAfrica.EventsTest do alias ElixirConfAfrica.Events.Event @invalid_attrs %{ - name: nil, + name: nil, description: nil, location: nil, event_type: nil, From b91ae5a908a3770e44555ee43182105ca09900a1 Mon Sep 17 00:00:00 2001 From: MICHAELMUNAVU83 Date: Thu, 16 Nov 2023 07:50:06 +0300 Subject: [PATCH 09/15] Added live tests --- lib/elixir_conf_africa/cart.ex | 27 +++++++++ .../live/home_live/index.ex | 7 +-- .../live/home_live/index.html.heex | 1 + test/elixir_conf_africa/cart_test.exs | 2 + test/elixir_conf_africa/events_test.exs | 2 +- .../live/home_live_test.exs | 59 +++++++++++++++++++ 6 files changed, 91 insertions(+), 7 deletions(-) create mode 100644 test/elixir_conf_africa_web/live/home_live_test.exs diff --git a/lib/elixir_conf_africa/cart.ex b/lib/elixir_conf_africa/cart.ex index 30d7e71..0e98574 100644 --- a/lib/elixir_conf_africa/cart.ex +++ b/lib/elixir_conf_africa/cart.ex @@ -5,15 +5,30 @@ defmodule ElixirConfAfrica.Cart do alias ElixirConfAfrica.TicketTypes + @doc """ + Returns the ids of all the cart items in a list + + + + """ def cart_list_ids(cart) do cart |> Enum.map(fn cart_item -> cart_item.id end) end + @doc """ + Increases the quantity of a cart item given the cart item and the quantity to increase by + + """ + def increase_cart_item_quantity(cart_item, quantity) do cart_item |> Map.put(:quantity, quantity) end + @doc """ + Adds a cart item to the cart given the cart and the cart item id to add + + """ def add_to_cart(cart, cart_item_id) do cart_list_ids = cart_list_ids(cart) @@ -21,13 +36,20 @@ defmodule ElixirConfAfrica.Cart do true -> ticket_type = Enum.find(cart, fn item -> item.id == cart_item_id end) updated_cart = get_updated_cart("in-cart", ticket_type, cart) + updated_cart false -> ticket_type = TicketTypes.get_ticket_type!(cart_item_id) updated_cart = get_updated_cart("out-of-cart", ticket_type, cart) + updated_cart end end + @doc """ + Returns the updated cart for when a cart item already in the cart or out of the cart given the cart item and the cart + + """ + def get_updated_cart("in-cart", cart_item, cart) do cart_item_with_added_quantity = add_quantity_to_cart_item(cart, cart_item, cart_item.quantity + 1) @@ -44,6 +66,11 @@ defmodule ElixirConfAfrica.Cart do [cart_item_with_default_quantity_of_one | cart] end + @doc """ + Returns the cart item with an increased quantity given the cart, the cart item and the quantity to increase by. + It also checks if the cart item is already in the cart and increases the quantity if it is. + + """ def add_quantity_to_cart_item(cart, cart_item, quantity) do case cart |> Enum.filter(fn item -> item.id == cart_item.id end) do [] -> diff --git a/lib/elixir_conf_africa_web/live/home_live/index.ex b/lib/elixir_conf_africa_web/live/home_live/index.ex index 66509c9..54b05e7 100644 --- a/lib/elixir_conf_africa_web/live/home_live/index.ex +++ b/lib/elixir_conf_africa_web/live/home_live/index.ex @@ -1,7 +1,7 @@ defmodule ElixirConfAfricaWeb.HomeLive.Index do use ElixirConfAfricaWeb, :live_view alias ElixirConfAfrica.Events - alias ElixirConfAfrica.TicketTypes + alias ElixirConfAfrica.Cart def mount(_params, _session, socket) do @@ -19,11 +19,6 @@ defmodule ElixirConfAfricaWeb.HomeLive.Index do |> assign(available_tickets: available_tickets)} end - defp get_current_year do - %{year: year} = DateTime.utc_now() - year - end - defp get_upcoming_year do %{year: year} = DateTime.utc_now() year + 1 diff --git a/lib/elixir_conf_africa_web/live/home_live/index.html.heex b/lib/elixir_conf_africa_web/live/home_live/index.html.heex index 019aa32..9f0d943 100644 --- a/lib/elixir_conf_africa_web/live/home_live/index.html.heex +++ b/lib/elixir_conf_africa_web/live/home_live/index.html.heex @@ -124,6 +124,7 @@