Skip to content

Commit

Permalink
Merge pull request #8 from upmaru/feature/ops-577-dashboard-ui
Browse files Browse the repository at this point in the history
Feature/ops 577 dashboard UI
  • Loading branch information
zacksiri committed Feb 27, 2024
2 parents cc14cd0 + 62921c6 commit ba05d53
Show file tree
Hide file tree
Showing 29 changed files with 1,140 additions and 17 deletions.
16 changes: 16 additions & 0 deletions lib/polar/accounts.ex
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,26 @@ defmodule Polar.Accounts do
to: Space.Manager,
as: :create

defdelegate change_space(space),
to: Space.Manager,
as: :change

defdelegate change_space(space, attrs),
to: Space.Manager,
as: :change

defdelegate get_space_credential(query),
to: Space.Manager,
as: :get_credential

defdelegate change_space_credential(credential),
to: Space.Manager,
as: :change_credential

defdelegate change_space_credential(credential, attrs),
to: Space.Manager,
as: :change_credential

defdelegate create_space_credential(space, user, params),
to: Space.Manager,
as: :create_credential
Expand Down
4 changes: 2 additions & 2 deletions lib/polar/accounts/space.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ defmodule Polar.Accounts.Space do

schema "spaces" do
field :name, :string
field :cdn_host, :string

belongs_to :owner, User

Expand All @@ -16,7 +15,8 @@ defmodule Polar.Accounts.Space do
@doc false
def changeset(space, attrs) do
space
|> cast(attrs, [:name, :cdn_host])
|> cast(attrs, [:name])
|> validate_required([:name])
|> unique_constraint(:name, name: :spaces_owner_id_name_index)
end
end
5 changes: 4 additions & 1 deletion lib/polar/accounts/space/credential.ex
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ defmodule Polar.Accounts.Space.Credential do

def expires_in_range, do: @expires_in_range

def types, do: ["lxd", "incus"]

@doc false
def changeset(credential, attrs) do
expires_in_range_values = Enum.map(@expires_in_range, fn r -> r.value end)
Expand All @@ -47,9 +49,10 @@ defmodule Polar.Accounts.Space.Credential do
|> cast(attrs, [:name, :expires_in, :type])
|> generate_token()
|> validate_inclusion(:expires_in, expires_in_range_values)
|> validate_inclusion(:type, ["lxd", "incus"])
|> validate_inclusion(:type, types())
|> maybe_set_expires_at()
|> validate_required([:token, :type, :name])
|> unique_constraint(:name, name: :space_credentials_space_id_name_index)
end

def scope(:active, queryable) do
Expand Down
8 changes: 8 additions & 0 deletions lib/polar/accounts/space/manager.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,19 @@ defmodule Polar.Accounts.Space.Manager do
|> Repo.insert()
end

def change(%Space{} = space, attrs \\ %{}) do
Space.changeset(space, attrs)
end

def get_credential(token: token) do
Space.Credential.scope(:active, Space.Credential)
|> Repo.get_by(token: token)
end

def change_credential(credential_or_changeset, attrs \\ %{}) do
Space.Credential.changeset(credential_or_changeset, attrs)
end

def create_credential(%Accounts.Space{} = space, user, params) do
%Space.Credential{space_id: space.id}
|> Space.Credential.changeset(params)
Expand Down
4 changes: 3 additions & 1 deletion lib/polar/streams/item/manager.ex
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@ defmodule Polar.Streams.Item.Manager do
|> Repo.insert!()

%Item.Access{id: item_access_id} = item_access ->
timestamp = DateTime.utc_now()

from(ia in Item.Access,
update: [inc: [count: 1]],
update: [inc: [count: 1], set: [updated_at: ^timestamp]],
where: ia.id == ^item_access_id
)
|> Repo.update_all([])
Expand Down
11 changes: 11 additions & 0 deletions lib/polar_web/components/core_components.ex
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,17 @@ defmodule PolarWeb.CoreComponents do
"""
end

def input(%{type: "radio"} = assigns) do
assigns =
assign_new(assigns, :checked, fn ->
Phoenix.HTML.Form.normalize_value("checkbox", assigns[:value])
end)

~H"""
<input id={@id} type={@type} name={@name} checked={@checked} value={@value} {@rest} />
"""
end

# All other inputs text, datetime-local, url, password, etc. are handled here...
def input(assigns) do
~H"""
Expand Down
18 changes: 15 additions & 3 deletions lib/polar_web/components/layouts/app.html.heex
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,26 @@
>
<%= gettext("Home") %>
</.link>
<.link
navigate={~p"/dashboard"}
class={
if assigns[:current_path] == ~p"/dashboard",
do: "bg-slate-900 text-white rounded-md px-3 py-2 text-sm font-medium",
else:
"rounded-md px-3 py-2 text-sm font-medium text-slate-300 hover:bg-slate-900 hover:text-white"
}
aria-current="page"
>
<%= gettext("Dashboard") %>
</.link>
</div>
</div>
</div>
<div class="hidden md:block">
<div class="ml-4 flex items-center md:ml-6">
<%= if @current_user do %>
<.link
href={~p"/users/settings"}
navigate={~p"/users/settings"}
class={
if assigns[:current_path] == ~p"/users/settings",
do: "bg-slate-900 text-white rounded-md px-3 py-2 text-sm font-medium",
Expand All @@ -47,13 +59,13 @@
</.link>
<% else %>
<.link
href={~p"/users/log_in"}
navigate={~p"/users/log_in"}
class="text-slate-300 rounded-md px-3 py-2 text-sm font-medium hover:bg-slate-900 hover:text-white"
>
<%= gettext("Sign In") %>
</.link>
<.link
href={~p"/users/register"}
navigate={~p"/users/register"}
class="text-slate-300 rounded-md px-3 py-2 text-sm font-medium hover:bg-slate-900 hover:text-white"
>
<%= gettext("Register") %>
Expand Down
8 changes: 4 additions & 4 deletions lib/polar_web/controllers/error_html.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ defmodule PolarWeb.ErrorHTML do
# * lib/polar_web/controllers/error_html/404.html.heex
# * lib/polar_web/controllers/error_html/500.html.heex
#
# embed_templates "error_html/*"
embed_templates "error_html/*"

# The default is to render a plain text page based on
# the template name. For example, "404.html" becomes
# "Not Found".
def render(template, _assigns) do
Phoenix.Controller.status_message_from_template(template)
end
# def render(template, _assigns) do
# Phoenix.Controller.status_message_from_template(template)
# end
end
81 changes: 81 additions & 0 deletions lib/polar_web/controllers/error_html/404.html.heex
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<!DOCTYPE html>
<html lang="en" class="[scrollbar-gutter:stable]" class="h-full">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon.png" />
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16.png" />
<link rel="manifest" href="/images/site.webmanifest" />
<link rel="mask-icon" href="/images/safari-pinned-tab.svg" color="#5bbad5" />
<link rel="stylesheet" href="https://rsms.me/inter/inter.css" />
<meta name="msapplication-TileColor" content="#da532c" />
<meta name="theme-color" content="#0f172a" />
<meta name="csrf-token" content={get_csrf_token()} />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<.live_title suffix=" · Polar">
<%= "Page Not Found" %>
</.live_title>
<link phx-track-static rel="stylesheet" href={~p"/assets/app.css"} />
<script defer phx-track-static type="text/javascript" src={~p"/assets/app.js"}>
</script>
<%= if domain = System.get_env("PHX_HOST") do %>
<script defer data-domain={domain} src="https://plausible.io/js/script.js">
</script>
<% end %>
</head>
<body class="h-full bg-slate-950">
<div class="mx-auto mt-20 max-w-2xl text-center sm:mt-24">
<p class="text-base font-semibold leading-8 text-indigo-400"><%= gettext("404") %></p>
<h1 class="mt-4 text-3xl font-bold tracking-tight text-white sm:text-5xl">
<%= gettext("This page does not exist") %>
</h1>
<p class="mt-4 text-base leading-7 text-gray-600 sm:mt-6 sm:text-lg sm:leading-8">
<% gettext("Sorry, we couldn’t find the page you’re looking for.") %>
</p>
</div>
<div class="mx-auto mt-16 flow-root max-w-lg sm:mt-20">
<h2 class="sr-only"><%= gettext("Check out other pages") %></h2>
<ul role="list" class="-mt-6 divide-y divide-gray-900/5 border-b border-gray-900/5">
<li class="relative flex gap-x-6 py-6">
<div class="flex h-10 w-10 flex-none items-center justify-center rounded-lg shadow-sm ring-1 ring-slate-900/10">
<.icon name="hero-home-solid" class="h-6 w-6 text-indigo-400" />
</div>
<div class="flex-auto">
<h3 class="text-sm font-semibold leading-6 text-slate-100">
<a href="/">
<span class="absolute inset-0" aria-hidden="true"></span> <%= gettext(
"Take me home"
) %>
</a>
</h3>
<p class="mt-2 text-sm leading-6 text-slate-200">
<%= gettext("to the place I belong. West Virginia.") %>
</p>
</div>
<div class="flex-none self-center">
<.icon name="hero-chevron-right-solid" class="h-5 w-5 text-slate-400" />
</div>
</li>
<li class="relative flex gap-x-6 py-6">
<div class="flex h-10 w-10 flex-none items-center justify-center rounded-lg shadow-sm ring-1 ring-gray-900/10">
<.icon name="hero-squares-plus-solid" class="h-6 w-6 text-indigo-400" />
</div>
<div class="flex-auto">
<h3 class="text-sm font-semibold leading-6 text-slate-100">
<a href={~p"/dashboard"}>
<span class="absolute inset-0" aria-hidden="true"></span> <%= gettext("Dashboard") %>
</a>
</h3>
<p class="mt-2 text-sm leading-6 text-slate-200">
<%= gettext("Go back to the dashboard.") %>
</p>
</div>
<div class="flex-none self-center">
<.icon name="hero-chevron-right-solid" class="h-5 w-5 text-slate-400" />
</div>
</li>
</ul>
</div>
</body>
</html>
81 changes: 81 additions & 0 deletions lib/polar_web/controllers/error_html/500.html.heex
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<!DOCTYPE html>
<html lang="en" class="[scrollbar-gutter:stable]" class="h-full">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon.png" />
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16.png" />
<link rel="manifest" href="/images/site.webmanifest" />
<link rel="mask-icon" href="/images/safari-pinned-tab.svg" color="#5bbad5" />
<link rel="stylesheet" href="https://rsms.me/inter/inter.css" />
<meta name="msapplication-TileColor" content="#da532c" />
<meta name="theme-color" content="#0f172a" />
<meta name="csrf-token" content={get_csrf_token()} />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<.live_title suffix=" · Polar">
<%= "Page Not Found" %>
</.live_title>
<link phx-track-static rel="stylesheet" href={~p"/assets/app.css"} />
<script defer phx-track-static type="text/javascript" src={~p"/assets/app.js"}>
</script>
<%= if domain = System.get_env("PHX_HOST") do %>
<script defer data-domain={domain} src="https://plausible.io/js/script.js">
</script>
<% end %>
</head>
<body class="h-full bg-slate-950">
<div class="mx-auto mt-20 max-w-2xl text-center sm:mt-24">
<p class="text-base font-semibold leading-8 text-indigo-400"><%= gettext("404") %></p>
<h1 class="mt-4 text-3xl font-bold tracking-tight text-white sm:text-5xl">
<%= gettext("Whoops! Something went wrong.") %>
</h1>
<p class="mt-4 text-base leading-7 text-gray-600 sm:mt-6 sm:text-lg sm:leading-8">
<% gettext("Sorry, an error happened, we've logged the error.") %>
</p>
</div>
<div class="mx-auto mt-16 flow-root max-w-lg sm:mt-20">
<h2 class="sr-only"><%= gettext("Check out other pages") %></h2>
<ul role="list" class="-mt-6 divide-y divide-gray-900/5 border-b border-gray-900/5">
<li class="relative flex gap-x-6 py-6">
<div class="flex h-10 w-10 flex-none items-center justify-center rounded-lg shadow-sm ring-1 ring-slate-900/10">
<.icon name="hero-home-solid" class="h-6 w-6 text-indigo-400" />
</div>
<div class="flex-auto">
<h3 class="text-sm font-semibold leading-6 text-slate-100">
<a href="/">
<span class="absolute inset-0" aria-hidden="true"></span> <%= gettext(
"Take me home"
) %>
</a>
</h3>
<p class="mt-2 text-sm leading-6 text-slate-200">
<%= gettext("to the place I belong. West Virginia.") %>
</p>
</div>
<div class="flex-none self-center">
<.icon name="hero-chevron-right-solid" class="h-5 w-5 text-slate-400" />
</div>
</li>
<li class="relative flex gap-x-6 py-6">
<div class="flex h-10 w-10 flex-none items-center justify-center rounded-lg shadow-sm ring-1 ring-gray-900/10">
<.icon name="hero-squares-plus-solid" class="h-6 w-6 text-indigo-400" />
</div>
<div class="flex-auto">
<h3 class="text-sm font-semibold leading-6 text-slate-100">
<a href={~p"/dashboard"}>
<span class="absolute inset-0" aria-hidden="true"></span> <%= gettext("Dashboard") %>
</a>
</h3>
<p class="mt-2 text-sm leading-6 text-slate-200">
<%= gettext("Go back to the dashboard.") %>
</p>
</div>
<div class="flex-none self-center">
<.icon name="hero-chevron-right-solid" class="h-5 w-5 text-slate-400" />
</div>
</li>
</ul>
</div>
</body>
</html>
9 changes: 9 additions & 0 deletions lib/polar_web/controllers/space_controller.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
defmodule PolarWeb.SpaceController do
use PolarWeb, :controller

action_fallback PolarWeb.FallbackController

def show(conn, %{"space_token" => _space_token}) do
redirect(conn, to: ~p"/")
end
end
4 changes: 1 addition & 3 deletions lib/polar_web/controllers/streams/item_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ defmodule PolarWeb.Streams.ItemController do

Streams.record_item_access(item, credential)

endpoint = credential.space.cdn_host || default_cdn_host

url = Path.join(["https://", endpoint, item.path])
url = Path.join(["https://", default_cdn_host, item.path])

redirect(conn, external: url)
end
Expand Down
Loading

0 comments on commit ba05d53

Please sign in to comment.