├── _build
├── assets
├── config
├── deps
├── lib
│ └── cannelloni <- domain / business logic
│ └── cannelloni_web.ex <- webserver logic
├── priv
└── test
├── _build
├── assets
├── config
├── deps
├── lib
│ └── cannelloni <- domain / business logic
│ └── cannelloni_web.ex <- webserver logic
├── priv
└── test
lib/cannelloni_web
├── channels
│ └── user_socket.ex
├── controllers
│ └── page_controller.ex
├── templates
│ ├── layout
│ │ └── app.html.eex
│ └── page
│ └── index.html.eex
├── views
│ ├── error_helpers.ex
│ ├── error_view.ex
│ ├── layout_view.ex
│ └── page_view.ex
├── endpoint.ex
├── gettext.ex
├── router.ex
└── telemetry.ex
lib/cannelloni_web
├── channels
│
├── controllers
│
├── live
│ └── recipe_live
│
│
├── templates
│
│
├── views
│
│
│
│
├── endpoint.ex
├── gettext.ex
├── router.ex
└── telemetry.ex
defmodule CannelloniWeb.Router do
use CannelloniWeb, :router
...
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_live_flash
plug :fetch_current_user
plug :fetch_username
plug :put_root_layout, {CannelloniWeb.LayoutView, :root}
plug :protect_from_forgery
plug :put_secure_browser_headers
end
scope "/", CannelloniWeb do
pipe_through [:browser, :redirect_if_user_is_authenticated]
get "/users/register", UserRegistrationController, :new
post "/users/register", UserRegistrationController, :create
get "/users/log_in", UserSessionController, :new
post "/users/log_in", UserSessionController, :create
end
scope "/", CannelloniWeb do
pipe_through [:browser, :require_authenticated_user]
live "/recipes", RecipeLive.Index
live "/recipes/new", RecipeLive.New
end
end
defmodule CannelloniWeb.UserRegistrationController do
use CannelloniWeb, :controller
alias Cannelloni.Accounts
alias Cannelloni.Accounts.User
alias CannelloniWeb.UserAuth
def new(conn, _params) do
changeset = Accounts.change_user_registration(%User{})
render(conn, "new.html", changeset: changeset)
end
def create(conn, %{"user" => user_params}) do
case Accounts.register_user(user_params) do
{:ok, user} ->
{:ok, _} =
Accounts.deliver_user_confirmation_instructions(
user,
&Routes.user_confirmation_url(conn, :confirm, &1)
)
conn
|> put_flash(:info, "User created successfully.")
|> UserAuth.log_in_user(user)
{:error, %Ecto.Changeset{} = changeset} ->
render(conn, "new.html", changeset: changeset)
end
end
end
Vad?
Hur?
Varför?
...
<ul id="ingredient-list">
<%= for ingredient <- Enum.reverse(@recipe.ingredients) do %>
<li class="ingredient-list-item">
<%= ingredient %>
</li>
<% end %>
<%= if @current_user do %>
<li id="add-ingredient-input">
<input id="add-ingredient" type="text" phx-key="Enter" phx-window-keydown="add_ingredient" phx-hook="Input"
placeholder="T.ex. krossade tomater"/>
</li>
<% end %>
</ul>
show.html.leex
...
def mount(_params, session, socket) do
{:ok, assign(socket, :current_user, session["current_user"])}
end
def handle_params(%{"id" => id}, _, socket) do
{:noreply, assign(socket, :recipe, RecipeList.get_recipe!(id))}
end
def handle_event("add_ingredient", %{"value" => ingredient}, socket) do
{:ok, recipe} = RecipeList.add_ingredient(socket.assigns.recipe, ingredient)
socket =
socket
|> assign(:recipe, recipe)
|> push_event("clear_input", %{})
{:noreply, socket}
end
end
show.ex
Vad?
Hur?
Varför?
Live Telemetrics