Skip to content

Commit

Permalink
Merge pull request #9 from Gaurav1924/SigninErrorFixed
Browse files Browse the repository at this point in the history
Signin error fixed
  • Loading branch information
girishramnani authored Jul 29, 2024
2 parents b05e726 + 8fd216d commit 1b4533e
Show file tree
Hide file tree
Showing 15 changed files with 11,278 additions and 34 deletions.
10,975 changes: 10,975 additions & 0 deletions .elixir-tools/next-ls.log

Large diffs are not rendered by default.

36 changes: 36 additions & 0 deletions assets/css/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
.button-link {
display: inline-flex;
text-decoration: none;
}

.edit-button {
background-color: #4a90e2;
color: white;
padding: 0.5rem 1rem;
border-radius: 0.375rem;
font-weight: bold;
transition: background-color 0.3s ease;
}

.edit-button:hover {
background-color: #357abd;
}

.text-blue-600 {
color: #1d4ed8;
}

.text-blue-600:hover {
color: #1e40af;
}

.sr-only {
position: absolute;
width: 1px;
height: 1px;
margin: -1px;
padding: 0;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
}
30 changes: 29 additions & 1 deletion lib/polly/polls.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ defmodule Polly.Polls do
"""
alias Polly.Schema.Poll

@spec list_polls() :: [Poll.t()]
def list_polls() do
Polly.PollsManager.list_polls_with_ids()
end
Expand All @@ -18,10 +19,15 @@ defmodule Polly.Polls do
end
end

@spec get_poll!(binary()) :: Poll.t()
def get_poll!(id) do
Polly.PollsManager.get_poll_simple!(id)
end

@spec create_poll(map()) :: {:ok, Poll.t()} | {:error, Ecto.Changeset.t()}
def create_poll(params) do
Poll.changeset(%Poll{}, params)
|> Ecto.Changeset.apply_action(:update)
|> Ecto.Changeset.apply_action(:insert)
|> do_create_poll()
end

Expand All @@ -33,4 +39,26 @@ defmodule Polly.Polls do
defp do_create_poll({:error, changeset}) do
{:error, changeset}
end

@spec update_poll(Poll.t(), map()) :: {:ok, Poll.t()} | {:error, Ecto.Changeset.t()}
def update_poll(%Poll{} = poll, attrs) do
poll
|> Poll.changeset(attrs)
|> Ecto.Changeset.apply_action(:update)
|> do_update_poll(poll)
end

defp do_update_poll({:ok, %Poll{} = updated_poll}, _poll) do
:ok = Polly.PollsManager.update_poll(updated_poll)
{:ok, updated_poll}
end

defp do_update_poll({:error, changeset}, _poll) do
{:error, changeset}
end

@spec change_poll(Poll.t(), map()) :: Ecto.Changeset.t()
def change_poll(%Poll{} = poll, attrs \\ %{}) do
Poll.changeset(poll, attrs)
end
end
25 changes: 22 additions & 3 deletions lib/polly/polls_manager.ex
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
defmodule Polly.PollsManager do
alias Polly.Schema.Poll
alias Polly.StorageBehaviour
# alias Polly.StorageBehaviour

@storage_module Application.get_env(:polly, :storage_module, Polly.ETSStorage)
@storage_module Application.compile_env(:polly, :storage_module, Polly.ETSStorage)
def init() do
@storage_module.init()
end
Expand Down Expand Up @@ -36,6 +36,11 @@ defmodule Polly.PollsManager do
|> replace_option_votes(with_option_votes)
end

@spec get_poll_simple!(binary()) :: Poll.t()
def get_poll_simple!(id) do
@storage_module.get_poll!(id, false)
end

defp get_poll_votes!(poll_id) do
@storage_module.get_poll_votes!(poll_id)
end
Expand All @@ -53,7 +58,7 @@ defmodule Polly.PollsManager do
poll
end

defp has_option?(poll_id, option_id) do
def has_option?(poll_id, option_id) do
poll_id
|> @storage_module.get_poll!(false)
|> Map.fetch!(:options)
Expand All @@ -65,4 +70,18 @@ defmodule Polly.PollsManager do
defp safe_lookup_element(option_id) do
@storage_module.safe_lookup_element(option_id)
end

@spec update_poll(binary(), Poll.t()) :: :ok | {:error, atom()}
def update_poll(poll_id, %Poll{} = updated_poll) do
if @storage_module.get_poll!(poll_id) do
@storage_module.update_poll(poll_id, updated_poll)
else
{:error, :poll_not_found}
end
end

@spec change_poll(Poll.t(), map()) :: Ecto.Changeset.t()
def change_poll(%Poll{} = poll, attrs \\ %{}) do
Poll.changeset(poll, attrs)
end
end
6 changes: 6 additions & 0 deletions lib/polly/schema/poll.ex
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ defmodule Polly.Schema.Poll do
embeds_many(:options, Option, on_replace: :delete)
end

@spec changeset(Polly.Schema.Poll.t()) :: Ecto.Changeset.t()
def changeset(%Poll{} = poll, attrs \\ %{}) do
poll
|> cast(attrs, [:title, :total_votes, :creator_username, :description])
Expand All @@ -45,5 +46,10 @@ defmodule Polly.Schema.Poll do
changeset
end

# def changeset(poll, attrs) do
# poll
# |> cast(attrs, [:title, :description])
# |> validate_required([:title, :description])
# end
# defstruct title: nil, options: [], total_votes: 0, created_at: nil
end
3 changes: 3 additions & 0 deletions lib/polly/storage/behaviour.ex
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,7 @@ defmodule Polly.StorageBehaviour do
@callback get_poll_votes!(binary()) :: integer()
@callback has_option?(binary(), binary()) :: boolean()
@callback safe_lookup_element(binary()) :: integer()
@callback update_poll(binary(), Poll.t()) :: :ok | {:error, atom()}
# @callback replace_option_votes(Poll.t(), boolean()) :: Poll.t()

end
13 changes: 11 additions & 2 deletions lib/polly/storage/ets_storage.ex
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ defmodule Polly.ETSStorage do
:ets.lookup_element(@polls_votes, poll_id, 2)
end

@impl Polly.StorageBehaviour
def replace_option_votes(poll, true) do
updated_options =
Enum.map(poll.options, fn option ->
Expand All @@ -65,7 +64,6 @@ defmodule Polly.ETSStorage do
Map.replace(poll, :options, updated_options)
end

@impl Polly.StorageBehaviour
def replace_option_votes(poll, false), do: poll

@impl Polly.StorageBehaviour
Expand All @@ -84,4 +82,15 @@ defmodule Polly.ETSStorage do
ArgumentError -> 0
end
end

@impl Polly.StorageBehaviour
@spec update_poll(binary(), Poll.t()) :: :ok | {:error, atom()}
def update_poll(poll_id, %Poll{} = updated_poll) do
if :ets.lookup(@polls, poll_id) != [] do
:ets.insert(@polls, {poll_id, updated_poll})
:ok
else
{:error, :poll_not_found}
end
end
end
77 changes: 53 additions & 24 deletions lib/polly_web/components/layouts/app.html.heex
Original file line number Diff line number Diff line change
@@ -1,26 +1,55 @@
<header class="px-4 sm:px-6 lg:px-8">
<div class="flex items-center justify-between border-b border-zinc-100 py-3 text-sm">
<div class="flex items-center gap-4">
<a href="/">
Polly
</a>
<!DOCTYPE html>
<html>
<head>
<title>Polly</title>
<link rel="stylesheet" href="/assets/css/styles.css">
</head>
<body>
<header class="px-4 sm:px-6 lg:px-8">
<div class="flex items-center justify-between border-b border-zinc-100 py-3 text-sm">
<div class="flex items-center gap-4">
<a href="/" class="font-bold text-lg">
Polly
</a>
</div>
<div class="flex items-center gap-4 font-semibold leading-6 text-zinc-900">
<%= if assigns[:current_user] do %>
<.link href={~p"/username/log_out"} method="delete" class="text-blue-600 hover:underline">
<%= assigns[:current_user] %>
</.link>
<% else %>
<.link navigate={~p"/username/log_in"} class="text-blue-600 hover:underline">
Sign In
</.link>
<% end %>
</div>
</div>
<div class="flex items-center gap-4 font-semibold leading-6 text-zinc-900">
<%= if assigns[:current_user] do %>
<.link href={~p"/username/log_out"} method="delete">
<%= assigns[:current_user] %>
</.link>
<% else %>
<.link navigate={~p"/username/log_in"}>
Sign In
</.link>
<% end %>
</header>

<main class="px-4 py-20 sm:px-6 lg:px-8">
<div class="mx-auto max-w-2xl">
<.flash_group flash={@flash} />

<!-- Action Buttons -->
<div class="action-buttons flex gap-4 mt-6">
<%= if assigns[:polls] do %>
<%= for {_id, poll} <- @polls do %>
<div class="flex items-center gap-4">
<.link navigate={~p"/polls/#{poll.id}/edit"} class="button-link">
<.button class="edit-button">Edit</.button>
</.link>
<div class="sr-only">
<.link navigate={~p"/polls/#{poll.id}"} class="text-blue-600 hover:underline">
Show
</.link>
</div>
</div>
<% end %>
<% end %>

<%= @inner_content %>
</div>
</div>
</div>
</header>
<main class="px-4 py-20 sm:px-6 lg:px-8">
<div class="mx-auto max-w-2xl">
<.flash_group flash={@flash} />
<%= @inner_content %>
</div>
</main>
</main>
</body>
</html>
2 changes: 1 addition & 1 deletion lib/polly_web/live/login_live/index.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ defmodule PollyWeb.LoginLive.Index do

def mount(_params, _session, socket) do
form = to_form(%{"username" => nil})
{:ok, assign(socket, form: form)}
{:ok, assign(socket, form: form, polls: [])}
end
end
68 changes: 68 additions & 0 deletions lib/polly_web/live/poll_live/edit.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
defmodule PollyWeb.PollLive.Edit do
use PollyWeb, :live_view

alias Polly.Polls
alias Polly.Schema.Poll

@impl true
def mount(_params, _session, socket) do
{:ok, assign(socket, :page_title, "Edit Poll")}
end

@impl true
def handle_params(%{"id" => id}, _, socket) do
poll = Polls.get_poll!(id)
changeset = Polls.change_poll(poll)
{:noreply, assign(socket, poll: poll, changeset: changeset)}
end

@impl true
def handle_event("save", %{"poll" => poll_params}, socket) do
case Polls.update_poll(socket.assigns.poll, poll_params) do
{:ok, poll} ->
{:noreply,
socket
|> put_flash(:info, "Poll updated successfully")
|> push_redirect(to: Routes.poll_index_path(socket, :index))}

{:error, %Ecto.Changeset{} = changeset} ->
{:noreply, assign(socket, :changeset, changeset)}
end
end

def render(assigns) do
~H"""
<.header>
Edit Poll
</.header>
<.simple_form
for={@changeset}
id="poll-form"
phx-target={@myself}
phx-submit="save"
>
<.input field={@changeset[:title]} type="text" label="Title" />
<.input field={@changeset[:description]} type="textarea" label="Description" />
<fieldset>
<legend>Options</legend>
<%= hidden_input(@changeset, :options, value: "[]") %>
<%= for f_option <- inputs_for(@changeset, :options) do %>
<div class="m-4">
<%= hidden_inputs_for(f_option) %>
<.input field={f_option[:text]} type="text" />
</div>
<% end %>
<.button id="add-option" type="button" phx-click="add-option" phx-target={@myself}>
Add
</.button>
</fieldset>
<:actions>
<.button phx-disable-with="Saving...">Save Poll</.button>
</:actions>
</.simple_form>
"""
end
end
19 changes: 18 additions & 1 deletion lib/polly_web/live/poll_live/form_component.ex
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ defmodule PollyWeb.PollLive.FormComponent do
save_poll(socket, socket.assigns.action, poll_params)
end


defp save_poll(socket, :new, poll_params) do
# add the creator_username to the poll params so it can be added to the Poll
poll_params
|> Map.merge(%{"creator_username" => socket.assigns[:current_user]})
|> Polls.create_poll()
Expand All @@ -118,6 +118,23 @@ defmodule PollyWeb.PollLive.FormComponent do
end
end

defp save_poll(socket, :edit, poll_params) do
Polly.Polls.update_poll(socket.assigns.poll.id, poll_params)
|> case do
{:ok, poll} ->
notify_parent({:saved, poll})

{:noreply,
socket
|> put_flash(:info, "Poll updated successfully")
|> push_patch(to: socket.assigns.patch)}

{:error, changeset} ->
{:noreply, assign_form(socket, changeset)}
end
end


defp assign_form(socket, changeset) do
socket
|> assign(:form, to_form(changeset))
Expand Down
Loading

0 comments on commit 1b4533e

Please sign in to comment.