Last active
October 5, 2020 12:10
-
-
Save mazz/9a64e77ea3152ba5449e2977735b0669 to your computer and use it in GitHub Desktop.
liveview
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule ElijahWeb.SearchLive do | |
use ElijahWeb, :live_view | |
alias Elijah.Bank | |
require Logger | |
def mount(_params, _session, socket) do | |
socket = | |
assign(socket, | |
query: "", | |
code: "", | |
code_search: true, | |
loading: false, | |
challenges: [], | |
suggestions: [], | |
revealed_answer: 0, | |
total_entries: 0 | |
) | |
Logger.info("socket: ") | |
IO.inspect(socket) | |
{:ok, socket} | |
end | |
def render(assigns) do | |
~L""" | |
<div class="w-full md:w-11/12 xl:w-8/12 mx-auto text-left md:text-center"> | |
<p class="text-lg md:text-xl text-gray-600 mb-6"> | |
<%= if @code_search do %> | |
Search for an exam code<br/> | |
<% else %> | |
Search the questions for keywords<br/> | |
<% end %> | |
<%= if !@code_search do %> | |
<%= @total_entries %> results | |
<% end %> | |
</p> | |
<%= if @code_search do %> | |
<form phx-submit="code-search"> | |
<% else %> | |
<form phx-change="suggest-term" phx-submit="query-search"> | |
<% end %> | |
<label class="tag-label"> | |
<div class="tag-append"> | |
<%= if @code_search do %> | |
<input class="tag-input" type="text" name="code" value="<%= @code %>" placeholder="'B-001-001-001'" list="results" autofocus autocomplete="off" <%= if @loading, do: "readonly" %>/> | |
<% else %> | |
<input class="tag-input" type="text" name="query" value="<%= @query %>" phx-debounce="300" placeholder="'repeater station'" list="suggestions" autofocus autocomplete="off" <%= if @loading, do: "readonly" %>/> | |
<% end %> | |
<button type="submit" class="btn btn-dark" phx-disable-with="Searching...">Search</button> | |
</div> | |
</label> | |
</form> | |
<datalist id="suggestions"> | |
<%= for suggestion <- @suggestions do %> | |
<option value="<%= suggestion.query_text %>"><%= suggestion.query_text %></option> | |
<% end %> | |
</datalist> | |
<div> </div> | |
<div class="btn-group" role="group" aria-label="Query Type"> | |
<button class="btn btn-<%= if !@code_search, do: "outline-" %>dark" phx-click="code-search-on">Exam Code</button> | |
<button class="btn btn-<%= if @code_search, do: "outline-" %>dark" phx-click="query-search-on">Questions</button> | |
</div> | |
</div> | |
<div class="w-full md:w-11/12 xl:w-8/12 mx-auto text-left md:text-center"> </div> | |
<%= if @loading do %> | |
<div class="mx-auto md:text-center"> | |
<div class="spinner w-12 h-12" role="status"> | |
<span class="sr-only">Loading...</span> | |
</div> | |
</div> | |
<% end %> | |
<%= for challenge <- @challenges do %> | |
<div class="w-full md:w-11/12 xl:w-8/12 mx-auto text-left"> | |
<div class="card shadow"> | |
<div class="card-body shadow overflow-hidden rounded-md"> | |
<div class="container mx-auto flex justify-between items-center"> | |
<p class="text-sm md:text-md text-gray-400 mb-2"><%= challenge.category_name %></p> | |
<%= if @revealed_answer == challenge.id do %> | |
<button class="btn btn-light rounded-full btn-sm"><%= challenge.answer %></button> | |
<% else %> | |
<button class="btn btn-light rounded-full btn-sm" phx-click="reveal-answer" phx-value-id="<%= challenge.id %>">Reveal Answer</button> | |
<% end %> | |
</div> | |
<h3 class="text-2xl md:text-3xl text-gray-900 leading-tight mb-3 font-bold md:font-extrabold"><%= challenge.code %></h3> | |
<p class="text-lg md:text-xl text-gray-900 mb-2"><%= challenge.question %> </p> | |
<p class="text-lg md:text-xl text-gray-600 mb-2" style="white-space: pre-line"><%= Enum.map(String.split(challenge.choices , "\n"), fn str -> str <> "\n" end)%> </p> | |
</div> | |
</div> | |
</div> | |
<div> </div> | |
<% end %> | |
""" | |
end | |
def handle_event("reveal-answer", %{"id" => id}, socket) do | |
IO.inspect(id) | |
case Integer.parse(id) do | |
:error -> {:noreply, socket} | |
{number, _} -> {:noreply, assign(socket, revealed_answer: number)} | |
end | |
end | |
def handle_event("code-search-on", _, socket) do | |
socket = assign(socket, code_search: true) | |
{:noreply, socket} | |
end | |
def handle_event("query-search-on", _, socket) do | |
socket = assign(socket, code_search: false) | |
{:noreply, socket} | |
end | |
def handle_event("code-search", %{"code" => code}, socket) do | |
send(self(), {:run_code_search, code}) | |
socket = | |
assign(socket, | |
code: code, | |
challenges: [], | |
loading: true | |
) | |
{:noreply, socket} | |
end | |
def handle_event("query-search", %{"query" => query}, socket) do | |
send(self(), {:run_query_search, query}) | |
socket = | |
assign(socket, | |
query: query, | |
challenges: [], | |
loading: true | |
) | |
{:noreply, socket} | |
end | |
def handle_event("suggest-term", %{"query" => prefix}, socket) do | |
socket = | |
assign(socket, | |
suggestions: Bank.suggested_terms(prefix), | |
challenges: [], | |
# to avoid clobbering the input field when user selects prefix | |
query: prefix, | |
loading: false | |
) | |
{:noreply, socket} | |
end | |
def handle_info({:run_code_search, code}, socket) do | |
case Bank.search_by_code(String.upcase(code)) do | |
nil -> | |
socket = | |
socket | |
|> put_flash(:info, "No exam code matching \"#{code}\"") | |
|> assign(challenges: [], code: code, loading: false) | |
{:noreply, socket} | |
challenge -> | |
socket = assign(socket, challenges: [challenge], code: code, loading: false) | |
{:noreply, socket} | |
end | |
end | |
def handle_info({:run_query_search, query}, socket) do | |
challenge = Bank.search_by_question_query(query) | |
if challenge.total_entries == 0 do | |
socket = | |
socket | |
|> put_flash(:info, "No questions containing \"#{query}\"") | |
|> assign(challenges: [], query: query, loading: false, total_entries: 0) | |
{:noreply, socket} | |
else | |
socket = assign(socket, challenges: challenge, query: query, loading: false, total_entries: challenge.total_entries, revealed_answer: 0) | |
{:noreply, socket} | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment