Skip to content

Instantly share code, notes, and snippets.

@luizpvas
Created June 17, 2019 02:07
Show Gist options
  • Save luizpvas/85edc618360f40c4d623b20502fd99db to your computer and use it in GitHub Desktop.
Save luizpvas/85edc618360f40c4d623b20502fd99db to your computer and use it in GitHub Desktop.
defmodule AppWeb.Live.Subscription do
use Phoenix.LiveView
alias AppWeb.Router.Helpers, as: Routes
def render(assigns) do
~L"""
<form class="flex" phx-submit="submit">
<div class="w-1/2 mr-8">
<%= if @billing_period == :monthly do %>
<button class="border-2 text-sm py-1 px-2 rounded text-green-500 border-green-500">Monthly</button>
<% else %>
<button class="border-2 text-sm py-1 px-2 rounded text-gray-600" phx-click="set_billing_period" phx-value="monthly">
Monthly
</button>
<% end %>
<%= if @billing_period == :yearly do %>
<button class="border-2 text-sm py-1 px-2 rounded text-green-500 border-green-500">Yearly</button>
<% else %>
<button class="border-2 text-sm py-1 px-2 rounded text-gray-500 border-gray-400" phx-click="set_billing_period" phx-value="yearly">
Yearly
</button>
<% end %>
<%= for plan <- plans() do %>
<%= render_plan(plan, @selected_plan_id == plan[:id], assigns) %>
<% end %>
</div>
<div class="w-1/2">
<div>
<label>How many seats are you interested?</label>
<input class="block w-full border p-1 text-sm" type="number" phx-keyup="set_seats" value="<%= @seats %>">
</div>
<div class="font-mono text-sm my-2">
Total: <%= total_price_in_cents(assigns) |> format_money() %>
</div>
<div>
<%= if @subscribed do %>
<div class="text-green-600 italic">You're subscribed!</div>
<% end %>
<button class="bg-blue-600 text-white rounded py-1 px-3 font-bold" type="submit">Submit</button>
</div>
</div>
</form>
"""
end
def render_plan(plan, is_selected, assigns) do
class = if is_selected do
"flex items-center mt-2 border-2 border-green-500 rounded p-2"
else
"mt-2 flex items-center border-2 rounded p-2"
end
~L"""
<div class="<%= class %>" phx-click="select_plan" phx-value="<%= plan[:id] %>">
<div class="mr-auto"><%= plan[:name] %></div>
<div class="text-sm">
<%= plan_price(plan, assigns) |> format_money() %>
</div>
</div>
"""
end
def plans do
[
%{id: 1, name: "Starter", monthly_value: 1990, yearly_value: 19000},
%{id: 2, name: "Basic", monthly_value: 2990, yearly_value: 29000},
%{id: 3, name: "Enterprise", monthly_value: 3990, yearly_value: 39000}
]
end
def total_price_in_cents(assigns) do
plans()
|> Enum.find(fn plan -> plan[:id] == assigns[:selected_plan_id] end)
|> case do
nil -> "Invalid selected plan"
plan ->
case assigns[:billing_period] do
:monthly -> plan[:monthly_value] * assigns[:seats]
:yearly -> plan[:yearly_value] * assigns[:seats]
_ -> "Invalid billing period"
end
end
end
def plan_price(plan, assigns) do
case assigns[:billing_period] do
:monthly -> plan[:monthly_value]
:yearly -> plan[:yearly_value]
_ -> "Invalid billing period"
end
end
def format_money(cents) do
"$#{:erlang.float_to_binary(cents / 100, decimals: 2)}"
end
def mount(_session, socket) do
{:ok,
socket
|> assign(:selected_plan_id, 1)
|> assign(:billing_period, :monthly)
|> assign(:seats, 1)
|> assign(:subscribed, false)
}
end
def handle_event("select_plan", id, socket) do
{id, _} = Integer.parse(id)
{:noreply, assign(socket, :selected_plan_id, id)}
end
def handle_event("set_billing_period", "monthly", socket) do
{:noreply, assign(socket, :billing_period, :monthly)}
end
def handle_event("set_billing_period", "yearly", socket) do
{:noreply, assign(socket, :billing_period, :yearly)}
end
def handle_event("set_seats", value, socket) do
case Integer.parse(value) do
{seats, _} -> {:noreply, assign(socket, :seats, seats)}
_ -> {:noreply, socket}
end
end
def handle_event("submit", value, socket) do
{:noreply, assign(socket, :subscribed, true)}
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment