2022-09-21 18:06:22 +08:00
|
|
|
defmodule LivebookWeb.LearnLive do
|
2021-06-03 03:51:43 +08:00
|
|
|
use LivebookWeb, :live_view
|
|
|
|
|
|
|
|
import LivebookWeb.SessionHelpers
|
|
|
|
|
2022-09-21 18:06:22 +08:00
|
|
|
alias LivebookWeb.{LayoutHelpers, LearnHelpers, PageHelpers}
|
|
|
|
alias Livebook.Notebook.Learn
|
2021-06-03 03:51:43 +08:00
|
|
|
|
2022-08-18 21:34:27 +08:00
|
|
|
on_mount LivebookWeb.SidebarHook
|
|
|
|
|
2021-06-03 03:51:43 +08:00
|
|
|
@impl true
|
2021-11-02 02:33:43 +08:00
|
|
|
def mount(_params, _session, socket) do
|
2022-09-21 18:06:22 +08:00
|
|
|
[lead_notebook_info | notebook_infos] = Learn.visible_notebook_infos()
|
2021-06-03 03:51:43 +08:00
|
|
|
|
|
|
|
{:ok,
|
2022-08-18 21:34:27 +08:00
|
|
|
assign(socket,
|
2021-06-03 03:51:43 +08:00
|
|
|
lead_notebook_info: lead_notebook_info,
|
2022-01-07 01:37:55 +08:00
|
|
|
notebook_infos: notebook_infos,
|
2022-09-21 18:06:22 +08:00
|
|
|
page_title: "Livebook - Learn"
|
2021-06-03 03:51:43 +08:00
|
|
|
)}
|
|
|
|
end
|
|
|
|
|
|
|
|
@impl true
|
|
|
|
def render(assigns) do
|
2021-07-07 20:32:49 +08:00
|
|
|
~H"""
|
2022-08-23 18:38:39 +08:00
|
|
|
<LayoutHelpers.layout
|
|
|
|
socket={@socket}
|
2022-09-21 18:06:22 +08:00
|
|
|
current_page={Routes.learn_path(@socket, :page)}
|
2022-08-23 18:38:39 +08:00
|
|
|
current_user={@current_user}
|
|
|
|
saved_hubs={@saved_hubs}
|
|
|
|
>
|
2022-10-12 01:06:18 +08:00
|
|
|
<div class="p-4 md:px-12 md:py-7 max-w-screen-lg mx-auto space-y-4">
|
2022-08-23 18:38:39 +08:00
|
|
|
<div>
|
2022-09-21 18:06:22 +08:00
|
|
|
<PageHelpers.title text="Learn" />
|
2022-08-29 01:08:43 +08:00
|
|
|
<p class="mt-4 mb-8 text-gray-700">
|
|
|
|
Check out a number of examples showcasing various parts of the Elixir ecosystem.<br />
|
2022-08-23 18:38:39 +08:00
|
|
|
Click on any notebook you like and start playing around with it!
|
|
|
|
</p>
|
|
|
|
</div>
|
2022-08-29 01:25:34 +08:00
|
|
|
<div
|
|
|
|
id="welcome-to-livebook"
|
2022-10-25 21:33:15 +08:00
|
|
|
class="p-8 bg-gray-900 rounded-2xl flex flex-col sm:flex-row space-y-8 sm:space-y-0 space-x-0 sm:space-x-8 items-center"
|
2022-08-29 01:25:34 +08:00
|
|
|
>
|
2022-11-30 06:35:35 +08:00
|
|
|
<img
|
|
|
|
src={Routes.static_path(@socket, @lead_notebook_info.details.cover_url)}
|
|
|
|
width="100"
|
|
|
|
alt="livebook"
|
|
|
|
/>
|
2022-08-29 01:08:43 +08:00
|
|
|
<div>
|
2022-08-23 18:38:39 +08:00
|
|
|
<h3 class="text-xl text-gray-50 font-semibold">
|
|
|
|
<%= @lead_notebook_info.title %>
|
|
|
|
</h3>
|
|
|
|
<p class="mt-2 text-sm text-gray-300">
|
|
|
|
<%= @lead_notebook_info.details.description %>
|
2021-06-03 03:51:43 +08:00
|
|
|
</p>
|
2022-08-23 18:38:39 +08:00
|
|
|
<div class="mt-4">
|
2022-08-29 01:08:43 +08:00
|
|
|
<%= live_patch("Open notebook",
|
2022-09-21 18:06:22 +08:00
|
|
|
to: Routes.learn_path(@socket, :notebook, @lead_notebook_info.slug),
|
2022-08-23 18:38:39 +08:00
|
|
|
class: "button-base button-blue"
|
|
|
|
) %>
|
2021-06-03 03:51:43 +08:00
|
|
|
</div>
|
|
|
|
</div>
|
2022-08-23 18:38:39 +08:00
|
|
|
</div>
|
2022-10-12 01:06:18 +08:00
|
|
|
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-1 lg:grid-cols-2 xl:grid-cols-3 gap-4">
|
2022-08-23 18:38:39 +08:00
|
|
|
<% # Note: it's fine to use stateless components in this comprehension,
|
|
|
|
# because @notebook_infos never change %>
|
|
|
|
<%= for info <- @notebook_infos do %>
|
2022-09-21 18:06:22 +08:00
|
|
|
<LearnHelpers.notebook_card notebook_info={info} socket={@socket} />
|
2021-12-28 04:01:31 +08:00
|
|
|
<% end %>
|
2021-06-03 03:51:43 +08:00
|
|
|
</div>
|
2022-09-21 18:06:22 +08:00
|
|
|
<%= for group_info <- Learn.group_infos() do %>
|
2022-08-23 18:38:39 +08:00
|
|
|
<.notebook_group group_info={group_info} socket={@socket} />
|
|
|
|
<% end %>
|
2021-06-03 03:51:43 +08:00
|
|
|
</div>
|
2022-08-23 18:38:39 +08:00
|
|
|
</LayoutHelpers.layout>
|
2021-06-03 03:51:43 +08:00
|
|
|
"""
|
|
|
|
end
|
|
|
|
|
2021-12-28 04:01:31 +08:00
|
|
|
defp notebook_group(assigns) do
|
|
|
|
~H"""
|
|
|
|
<div>
|
2022-08-29 01:08:43 +08:00
|
|
|
<div class="p-8 mt-16 rounded-2xl border border-gray-300 flex flex-col sm:flex-row space-y-8 sm:space-y-0 space-x-0 sm:space-x-8 items-center">
|
2022-11-30 06:34:38 +08:00
|
|
|
<img src={Routes.static_path(@socket, @group_info.cover_url)} width="100" />
|
2021-12-28 04:01:31 +08:00
|
|
|
<div>
|
|
|
|
<div class="inline-flex px-2 py-0.5 bg-gray-200 rounded-3xl text-gray-700 text-xs font-medium">
|
|
|
|
<%= length(@group_info.notebook_infos) %> notebooks
|
|
|
|
</div>
|
2022-01-18 00:11:06 +08:00
|
|
|
<h3 class="mt-1 text-xl text-gray-800 font-semibold">
|
2021-12-28 04:01:31 +08:00
|
|
|
<%= @group_info.title %>
|
|
|
|
</h3>
|
|
|
|
<p class="mt-2 text-gray-700">
|
|
|
|
<%= @group_info.description %>
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="mt-4">
|
|
|
|
<ul>
|
|
|
|
<%= for {notebook_info, number} <- Enum.with_index(@group_info.notebook_infos, 1) do %>
|
2022-10-12 01:06:18 +08:00
|
|
|
<li class="py-4 flex flex-row items-center space-x-5 border-b border-gray-200 last:border-b-0">
|
2021-12-28 04:01:31 +08:00
|
|
|
<div class="text-lg text-gray-400 font-semibold">
|
|
|
|
<%= number |> Integer.to_string() |> String.pad_leading(2, "0") %>
|
|
|
|
</div>
|
2022-01-18 00:11:06 +08:00
|
|
|
<div class="grow text-gray-800 font-semibold">
|
2021-12-28 04:01:31 +08:00
|
|
|
<%= notebook_info.title %>
|
|
|
|
</div>
|
2022-09-21 18:06:22 +08:00
|
|
|
<%= live_redirect to: Routes.learn_path(@socket, :notebook, notebook_info.slug),
|
2022-10-12 01:06:18 +08:00
|
|
|
class: "button-base button-outlined-gray" do %>
|
|
|
|
<.remix_icon icon="play-circle-line" class="align-middle mr-1" /> Open
|
2021-12-28 04:01:31 +08:00
|
|
|
<% end %>
|
|
|
|
</li>
|
|
|
|
<% end %>
|
|
|
|
</ul>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
"""
|
|
|
|
end
|
|
|
|
|
2021-06-03 03:51:43 +08:00
|
|
|
@impl true
|
2021-06-15 03:25:18 +08:00
|
|
|
def handle_params(%{"slug" => "new"}, _url, socket) do
|
|
|
|
{:noreply, create_session(socket)}
|
|
|
|
end
|
|
|
|
|
2021-06-03 03:51:43 +08:00
|
|
|
def handle_params(%{"slug" => slug}, _url, socket) do
|
2022-09-21 18:06:22 +08:00
|
|
|
{notebook, images} = Learn.notebook_by_slug!(slug)
|
2021-06-08 19:28:53 +08:00
|
|
|
{:noreply, create_session(socket, notebook: notebook, images: images)}
|
2021-06-03 03:51:43 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
def handle_params(_params, _url, socket), do: {:noreply, socket}
|
|
|
|
end
|