diff options
author | href <href@random.sh> | 2021-09-01 10:30:18 +0200 |
---|---|---|
committer | href <href@random.sh> | 2021-09-01 10:30:18 +0200 |
commit | 75687711f35355bc30e4829439384aab28fcac6d (patch) | |
tree | 8f3256f472893c39720a684d390e890a152f7303 /lib/lsg_web | |
parent | link: post_* callbacks; html & pdftitle. (diff) |
Commit all the changes that hasn't been committed + updates.
Diffstat (limited to 'lib/lsg_web')
-rw-r--r-- | lib/lsg_web/controllers/alcoolog_controller.ex | 263 | ||||
-rw-r--r-- | lib/lsg_web/controllers/irc_controller.ex | 9 | ||||
-rw-r--r-- | lib/lsg_web/router.ex | 11 | ||||
-rw-r--r-- | lib/lsg_web/templates/alcoolog/index.html.eex | 222 | ||||
-rw-r--r-- | lib/lsg_web/templates/alcoolog/user.html.eex | 170 | ||||
-rw-r--r-- | lib/lsg_web/templates/irc/index.html.eex | 25 | ||||
-rw-r--r-- | lib/lsg_web/templates/irc/txt.html.eex | 22 | ||||
-rw-r--r-- | lib/lsg_web/templates/irc/txts.html.eex | 35 | ||||
-rw-r--r-- | lib/lsg_web/templates/layout/app.html.eex | 135 | ||||
-rw-r--r-- | lib/lsg_web/templates/page/user.html.eex | 2 | ||||
-rw-r--r-- | lib/lsg_web/views/alcoolog_view.ex | 2 | ||||
-rw-r--r-- | lib/lsg_web/views/layout_view.ex | 7 |
12 files changed, 800 insertions, 103 deletions
diff --git a/lib/lsg_web/controllers/alcoolog_controller.ex b/lib/lsg_web/controllers/alcoolog_controller.ex index b88faa3..6542f15 100644 --- a/lib/lsg_web/controllers/alcoolog_controller.ex +++ b/lib/lsg_web/controllers/alcoolog_controller.ex @@ -16,6 +16,166 @@ defmodule LSGWeb.AlcoologController do end end + def nick(conn = %{assigns: %{account: account}}, params = %{"network" => network, "nick" => nick}) do + profile_account = IRC.Account.find_always_by_nick(network, nick, nick) + days = String.to_integer(Map.get(params, "days", "180")) + friend? = Enum.member?(IRC.Membership.friends(account), profile_account.id) + if friend? do + stats = LSG.IRC.AlcoologPlugin.get_full_statistics(profile_account.id) + history = for {{nick, ts}, points, active, cl, deg, type, descr, meta} <- LSG.IRC.AlcoologPlugin.nick_history(profile_account) do + %{ + at: ts |> DateTime.from_unix!(:millisecond), + points: points, + active: active, + cl: cl, + deg: deg, + type: type, + description: descr, + meta: meta + } + end + history = Enum.sort(history, &(DateTime.compare(&1.at, &2.at) != :lt)) + |> IO.inspect() + conn + |> assign(:title, "alcoolog #{nick}") + |> render("user.html", network: network, profile: profile_account, days: days, nick: nick, history: history, stats: stats) + else + conn + |> put_status(404) + |> text("Page not found") + end + end + + def nick_stats_json(conn = %{assigns: %{account: account}}, params = %{"network" => network, "nick" => nick}) do + profile_account = IRC.Account.find_always_by_nick(network, nick, nick) + friend? = Enum.member?(IRC.Membership.friends(account), profile_account.id) + if friend? do + stats = LSG.IRC.AlcoologPlugin.get_full_statistics(profile_account.id) + + conn + |> put_resp_content_type("application/json") + |> text(Jason.encode!(stats)) + else + conn + |> put_status(404) + |> json([]) + end + end + + def nick_gls_json(conn = %{assigns: %{account: account}}, params = %{"network" => network, "nick" => nick}) do + profile_account = IRC.Account.find_always_by_nick(network, nick, nick) + friend? = Enum.member?(IRC.Membership.friends(account), profile_account.id) + count = String.to_integer(Map.get(params, "days", "180")) + if friend? do + data = LSG.IRC.AlcoologPlugin.user_over_time_gl(profile_account, count) + delay = count*((24 * 60)*60) + now = DateTime.utc_now() + start_date = DateTime.utc_now() + |> DateTime.shift_zone!("Europe/Paris", Tzdata.TimeZoneDatabase) + |> DateTime.add(-delay, :second, Tzdata.TimeZoneDatabase) + |> DateTime.to_date() + |> Date.to_erl() + filled = (:calendar.date_to_gregorian_days(start_date) .. :calendar.date_to_gregorian_days(DateTime.utc_now |> DateTime.to_date() |> Date.to_erl)) + |> Enum.to_list + |> Enum.map(&(:calendar.gregorian_days_to_date(&1))) + |> Enum.map(&Date.from_erl!(&1)) + |> Enum.map(fn(date) -> + %{date: date, gls: Map.get(data, date, 0)} + end) + |> Enum.sort(&(Date.compare(&1.date, &2.date) != :gt)) + + conn + |> put_resp_content_type("application/json") + |> text(Jason.encode!(filled)) + else + conn + |> put_status(404) + |> json([]) + end + end + + + + def nick_volumes_json(conn = %{assigns: %{account: account}}, params = %{"network" => network, "nick" => nick}) do + profile_account = IRC.Account.find_always_by_nick(network, nick, nick) + friend? = Enum.member?(IRC.Membership.friends(account), profile_account.id) + count = String.to_integer(Map.get(params, "days", "180")) + if friend? do + data = LSG.IRC.AlcoologPlugin.user_over_time(profile_account, count) + delay = count*((24 * 60)*60) + now = DateTime.utc_now() + start_date = DateTime.utc_now() + |> DateTime.shift_zone!("Europe/Paris", Tzdata.TimeZoneDatabase) + |> DateTime.add(-delay, :second, Tzdata.TimeZoneDatabase) + |> DateTime.to_date() + |> Date.to_erl() + filled = (:calendar.date_to_gregorian_days(start_date) .. :calendar.date_to_gregorian_days(DateTime.utc_now |> DateTime.to_date() |> Date.to_erl)) + |> Enum.to_list + |> Enum.map(&(:calendar.gregorian_days_to_date(&1))) + |> Enum.map(&Date.from_erl!(&1)) + |> Enum.map(fn(date) -> + %{date: date, volumes: Map.get(data, date, 0)} + end) + |> Enum.sort(&(Date.compare(&1.date, &2.date) != :gt)) + + conn + |> put_resp_content_type("application/json") + |> text(Jason.encode!(filled)) + else + conn + |> put_status(404) + |> json([]) + end + end + + def nick_log_json(conn = %{assigns: %{account: account}}, %{"network" => network, "nick" => nick}) do + profile_account = IRC.Account.find_always_by_nick(network, nick, nick) + friend? = Enum.member?(IRC.Membership.friends(account), profile_account.id) + if friend? do + history = for {{nick, ts}, points, active, cl, deg, type, descr, meta} <- LSG.IRC.AlcoologPlugin.nick_history(profile_account) do + %{ + at: ts |> DateTime.from_unix!(:millisecond) |> DateTime.to_iso8601(), + points: points, + active: active, + cl: cl, + deg: deg, + type: type, + description: descr, + meta: meta + } + end + last = List.last(history) + {_, active} = LSG.IRC.AlcoologPlugin.user_stats(profile_account) + last = %{last | active: active, at: DateTime.utc_now() |> DateTime.to_iso8601()} + history = history ++ [last] + + conn + |> put_resp_content_type("application/json") + |> text(Jason.encode!(history)) + else + conn + |> put_status(404) + |> json([]) + end + end + + def nick_history_json(conn = %{assigns: %{account: account}}, %{"network" => network, "nick" => nick}) do + profile_account = IRC.Account.find_always_by_nick(network, nick, nick) + friend? = Enum.member?(IRC.Membership.friends(account), profile_account.id) + if friend? do + history = for {_, date, value} <- LSG.IRC.AlcoologAnnouncerPlugin.log(profile_account) do + %{date: DateTime.to_iso8601(date), value: value} + end + conn + |> put_resp_content_type("application/json") + |> text(Jason.encode!(history)) + else + conn + |> put_status(404) + |> json([]) + end + end + def index(conn = %{assigns: %{account: account}}, %{"network" => network, "chan" => channel}) do index(conn, account, network, LSGWeb.reformat_chan(channel)) end @@ -40,16 +200,22 @@ defmodule LSGWeb.AlcoologController do #end def index(conn, account, network, channel) do - aday = 18*((24 * 60)*60) + aday = ((24 * 60)*60) now = DateTime.utc_now() - before = now - |> DateTime.add(-aday, :second) - |> DateTime.to_unix(:millisecond) + before7 = now + |> DateTime.add(-(7*aday), :second) + |> DateTime.to_unix(:millisecond) + before15 = now + |> DateTime.add(-(15*aday), :second) + |> DateTime.to_unix(:millisecond) + before31 = now + |> DateTime.add(-(31*aday), :second) + |> DateTime.to_unix(:millisecond) #match = :ets.fun2ms(fn(obj = {{^nick, date}, _, _, _, _}) when date > before -> obj end) match = [ - {{{:_, :"$1"}, :_, :_, :_, :_}, + {{{:_, :"$1"}, :_, :_, :_, :_, :_, :_, :_}, [ - {:>, :"$1", {:const, before}}, + {:>, :"$1", {:const, before15}}, ], [:"$_"]} ] @@ -58,13 +224,13 @@ defmodule LSGWeb.AlcoologController do members_ids = Enum.map(members, fn({account, _, nick}) -> account.id end) member_names = Enum.reduce(members, %{}, fn({account, _, nick}, acc) -> Map.put(acc, account.id, nick) end) drinks = :ets.select(LSG.IRC.AlcoologPlugin.ETS, match) - |> Enum.filter(fn({{account, _}, _, _, _, _}) -> Enum.member?(members_ids, account) end) - |> Enum.map(fn({{account, _}, _, _, _, _} = object) -> {object, Map.get(member_names, account)} end) - |> Enum.sort_by(fn({{{_, ts}, _, _, _, _}, _}) -> ts end, &>/2) + |> Enum.filter(fn({{account, _}, _vol, _cur, _cl, _deg, _name, _cmt, _meta}) -> Enum.member?(members_ids, account) end) + |> Enum.map(fn({{account, _}, _, _, _, _, _, _, _} = object) -> {object, Map.get(member_names, account)} end) + |> Enum.sort_by(fn({{{_, ts}, _, _, _, _, _, _, _}, _}) -> ts end, &>/2) stats = LSG.IRC.AlcoologPlugin.get_channel_statistics(account, network, channel) - top = Enum.reduce(drinks, %{}, fn({{{account_id, _}, vol, _, _, _}, _}, acc) -> + top = Enum.reduce(drinks, %{}, fn({{{account_id, _}, vol, _, _, _, _, _, _}, _}, acc) -> nick = Map.get(member_names, account_id) all = Map.get(acc, nick, 0) Map.put(acc, nick, all + vol) @@ -77,4 +243,81 @@ defmodule LSGWeb.AlcoologController do |> render("index.html", network: network, channel: channel, drinks: drinks, top: top, stats: stats) end + def index_gls_json(conn = %{assigns: %{account: account}}, %{"network" => network, "chan" => channel}) do + count = 30 + channel = LSGWeb.reformat_chan(channel) + members = IRC.Membership.expanded_members_or_friends(account, network, channel) + members_ids = Enum.map(members, fn({account, _, nick}) -> account.id end) + member_names = Enum.reduce(members, %{}, fn({account, _, nick}, acc) -> Map.put(acc, account.id, nick) end) + delay = count*((24 * 60)*60) + now = DateTime.utc_now() + start_date = DateTime.utc_now() + |> DateTime.shift_zone!("Europe/Paris", Tzdata.TimeZoneDatabase) + |> DateTime.add(-delay, :second, Tzdata.TimeZoneDatabase) + |> DateTime.to_date() + |> Date.to_erl() + filled = (:calendar.date_to_gregorian_days(start_date) .. :calendar.date_to_gregorian_days(DateTime.utc_now |> DateTime.to_date() |> Date.to_erl)) + |> Enum.to_list + |> Enum.map(&(:calendar.gregorian_days_to_date(&1))) + |> Enum.map(&Date.from_erl!(&1)) + |> Enum.map(fn(date) -> + {date, (for {a, _, _} <- members, into: Map.new, do: {Map.get(member_names, a.id, a.id), 0})} + end) + |> Enum.into(Map.new) + + gls = Enum.reduce(members, filled, fn({account, _, _}, gls) -> + Enum.reduce(LSG.IRC.AlcoologPlugin.user_over_time_gl(account, count), gls, fn({date, gl}, gls) -> + u = Map.get(gls, date, %{}) + |> Map.put(Map.get(member_names, account.id, account.id), gl) + Map.put(gls, date, u) + end) + end) + + dates = (:calendar.date_to_gregorian_days(start_date) .. :calendar.date_to_gregorian_days(DateTime.utc_now |> DateTime.to_date() |> Date.to_erl)) + |> Enum.to_list + |> Enum.map(&(:calendar.gregorian_days_to_date(&1))) + |> Enum.map(&Date.from_erl!(&1)) + + filled2 = Enum.map(member_names, fn({_, name}) -> + history = (:calendar.date_to_gregorian_days(start_date) .. :calendar.date_to_gregorian_days(DateTime.utc_now |> DateTime.to_date() |> Date.to_erl)) + |> Enum.to_list + |> Enum.map(&(:calendar.gregorian_days_to_date(&1))) + |> Enum.map(&Date.from_erl!(&1)) + |> Enum.map(fn(date) -> + get_in(gls, [date, name]) #%{date: date, gl: get_in(gls, [date, name])} + end) + if Enum.all?(history, fn(x) -> x == 0 end) do + nil + else + %{name: name, history: history} + end + end) + |> Enum.filter(fn(x) -> x end) + + conn + |> put_resp_content_type("application/json") + |> text(Jason.encode!(%{labels: dates, data: filled2})) + end + + def minisync(conn, %{"user_id" => user_id, "key" => key, "value" => value}) do + account = IRC.Account.get(user_id) + if account do + ds = LSG.IRC.AlcoologPlugin.data_state() + meta = LSG.IRC.AlcoologPlugin.get_user_meta(ds, account.id) + case Float.parse(value) do + {val, _} -> + new_meta = Map.put(meta, String.to_existing_atom(key), val) + LSG.IRC.AlcoologPlugin.put_user_meta(ds, account.id, new_meta) + _ -> + conn + |> put_status(:unprocessable_entity) + |> text("invalid value") + end + else + conn + |> put_status(:not_found) + |> text("not found") + end + end + end diff --git a/lib/lsg_web/controllers/irc_controller.ex b/lib/lsg_web/controllers/irc_controller.ex index e0bf24d..317bb27 100644 --- a/lib/lsg_web/controllers/irc_controller.ex +++ b/lib/lsg_web/controllers/irc_controller.ex @@ -52,11 +52,16 @@ defmodule LSGWeb.IrcController do conn.assigns[:chan] -> "/#{conn.assigns.network}/#{LSGWeb.format_chan(conn.assigns.chan)}" true -> "/-" end - if Map.has_key?(data, txt) do + if lines = Map.get(data, txt) do + lines = Enum.map(lines, fn(line) -> + line + |> String.split("\\\\") + |> Enum.intersperse(Phoenix.HTML.Tag.tag(:br)) + end) conn |> assign(:breadcrumbs, [{"txt", "#{base_url}/txt"}]) |> assign(:title, "#{txt}.txt") - |> render("txt.html", name: txt, data: data[txt], doc: nil) + |> render("txt.html", name: txt, data: lines, doc: nil) else conn |> put_status(404) diff --git a/lib/lsg_web/router.ex b/lib/lsg_web/router.ex index de7fafb..d681ed9 100644 --- a/lib/lsg_web/router.ex +++ b/lib/lsg_web/router.ex @@ -33,13 +33,20 @@ defmodule LSGWeb.Router do get "/-/alcoolog", AlcoologController, :index get "/-/alcoolog/~/:account_name", AlcoologController, :index get "/:network", NetworkController, :index + get "/:network/~:nick/alcoolog", AlcoologController, :nick + get "/:network/~:nick/alcoolog/log.json", AlcoologController, :nick_log_json + get "/:network/~:nick/alcoolog/gls.json", AlcoologController, :nick_gls_json + get "/:network/~:nick/alcoolog/volumes.json", AlcoologController, :nick_volumes_json + get "/:network/~:nick/alcoolog/history.json", AlcoologController, :nick_history_json + get "/:network/~:nick/alcoolog/stats.json", AlcoologController, :nick_stats_json + get "/:network/:chan/alcoolog", AlcoologController, :index + get "/:network/:chan/alcoolog/gls.json", AlcoologController, :index_gls_json + put "/api/alcoolog/minisync/:user_id/meta/:key", AlcoologController, :minisync_put_meta get "/:network/:chan", IrcController, :index get "/:network/:chan/txt", IrcController, :txt get "/:network/:chan/txt/:name", IrcController, :txt get "/:network/:channel/preums", IrcController, :preums - get "/:network/:chan/alcoolog", AlcoologController, :index get "/:network/:chan/alcoolog/t/:token", AlcoologController, :token - get "/:network/alcoolog/~/:nick", AlcoologController, :nick end end diff --git a/lib/lsg_web/templates/alcoolog/index.html.eex b/lib/lsg_web/templates/alcoolog/index.html.eex index e656e64..3f522e9 100644 --- a/lib/lsg_web/templates/alcoolog/index.html.eex +++ b/lib/lsg_web/templates/alcoolog/index.html.eex @@ -5,54 +5,202 @@ ol li { </style> <%= if @stats == [] do %> - </strong><i>:o personne ne boit</i></strong> + <div class="rounded-md bg-red-50 p-4"> + <div class="flex"> + <div class="flex-shrink-0"> + <svg class="h-5 w-5 text-red-400" viewBox="0 0 20 20" fill="currentColor"> + <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd" /> + </svg> + </div> + <div class="ml-3"> + <h3 class="text-sm leading-5 font-medium text-red-800"> + CATASTROPHE! Personne n'a bu!!!! + </h3> + </div> + </div> + </div> <% end %> -<ul> +<ul class="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3"> <%= for {nick, status} <- @stats do %> - <li><strong><%= nick %> <%= status.user_status %> - <%= status.trend_symbol %> <%= status.active %> g/l</strong><br/> - — 15m: <%= status.active15m %> g/l - 30m: <%= status.active30m %> g/l - 1h: <%= status.active1h %> g/l<br /> - — dernier verre: <%= status.last_type %> <%= status.last_descr %> (<%= status.last_points %>) - <%= LSGWeb.LayoutView.format_time(status.last_at) %> - <br /> - — sobre dans: <%= status.sober_in_s %> - <br /> - <small> - — aujourd'hui: <%= status.daily_volumes %> points, <%= status.daily_gl %> g/l - </small> + <li class="col-span-1 bg-white rounded-lg shadow"> + <div class="w-full flex items-center justify-between p-6 space-x-6"> + <div class="flex-1 truncate"> + <div class="flex items-center space-x-3"> + <h3 class="text-gray-900 text-base leading-5 font-semibold truncate"><%= link nick, to: alcoolog_path(@conn, :nick, @network, nick) %></h3> + <% rising_class = if status.rising, do: "teal", else: "red" %> + <span class="flex-shrink-0 inline-block px-2 py-0.5 text-<%= rising_class %>-800 text-sm leading-4 font-medium bg-<%= rising_class %>-100 rounded-full"> + <%= status.trend_symbol %> <%= Float.round(status.active, 4) %> g/l + </span> + </div> + <p class="mt-1 text-gray-700 text-sm leading-5 truncate"> + <span class="text-base"><%= status.last_cl %>cl @ <%= status.last_deg %>°</span> + <%= if status.last_descr && status.last_descr != "" do %> + <br /><%= status.last_descr %> + <% end %> + <br/><small><%= LSGWeb.LayoutView.format_time(status.last_at) %></small> + </p> + + <p class="mt-1 text-gray-500 text-sm leading-5 truncate"> + <br /> + — sobre dans: <%= status.sober_in_s %><br /> + <%= if status.since do %> + — depuis: <%= status.since_s %><br /> + <% end %> + <small> + — 15m: <%= status.active15m %> g/l - 30m: <%= status.active30m %> g/l - 1h: <%= status.active1h %> g/l<br /> + — aujourd'hui: <%= status.daily_volumes %> points, <%= status.daily_gl %> g/l + </small> + </p> + + + </div> + </div> </li> <% end %> </ul> <%= if @stats == %{} do %> - <strong><i>... et personne n'a bu :o :o :o</i></strong> + <div class="rounded-md bg-red-50 p-4"> + <div class="flex"> + <div class="flex-shrink-0"> + <svg class="h-5 w-5 text-red-400" viewBox="0 0 20 20" fill="currentColor"> + <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd" /> + </svg> + </div> + <div class="ml-3"> + <h3 class="text-sm leading-5 font-medium text-red-800"> + ENCORE PIRE! Aucune boisson enregistrée! + </h3> + </div> + </div> + </div> <% else %> - <p> - top consommateur par volume, les 7 derniers jours: <%= Enum.intersperse(for({nick, count} <- @top, do: "#{nick}: #{Float.round(count,4)}"), ", ") %> - </p> - - <table class="table"> - <thead> - <tr> - <th scope="col">date</th> - <th scope="col">nick</th> - <th scope="col">points</th> - <th scope="col">nom</th> - </tr> - </thead> - <tbody> - <%= for {{{account, date}, points, _, nom, comment}, nick} <- @drinks do %> - <% date = DateTime.from_unix!(date, :millisecond) %> - <th scope="row"><%= LSGWeb.LayoutView.format_time(date, false) %></th> - <td><%= nick %></td> - <td><%= Float.round(points+0.0, 5) %></td> - <td><%= nom||"" %> <%= comment||"" %></td> - </tr> - <% end %> - </tbody> - </table> + +<canvas id="myChart" class="w-full" height="200"></canvas> + + <h2 class="leading-8 m-4 font-semibold text-2xl">Classement <span class="font-medium text-gray-600 text-lg">15 jours</span></h2> + +<ul class="grid grid-cols-1 gap-6 sm:grid-cols-5 lg:grid-cols-5"> + <%= for {{nick, count}, rank} <- Enum.with_index(@top) do %> + <% rank = rank + 1 %> + <% trophy = rank <= 3 %> + <% {colour, text} = case rank do +1 -> {"yellow-500", "font-semibold text-base"} +2 -> {"gray-500", "font-medium text-base"} +3 -> {"orange-300", "font-medium text-base"} +_ -> {"gray-300", ""} + end %> + <li class="col-span-1 bg-white rounded-lg shadow text-center <%= text %>"> + <%= if trophy do %> + <span class="text-<%= colour %>"> + <svg style="width: 1.125em; height: 1.5em; display: inline-block;" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="trophy" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" data-fa-i2svg=""><path fill="currentColor" d="M552 64H448V24c0-13.3-10.7-24-24-24H152c-13.3 0-24 10.7-24 24v40H24C10.7 64 0 74.7 0 88v56c0 35.7 22.5 72.4 61.9 100.7 31.5 22.7 69.8 37.1 110 41.7C203.3 338.5 240 360 240 360v72h-48c-35.3 0-64 20.7-64 56v12c0 6.6 5.4 12 12 12h296c6.6 0 12-5.4 12-12v-12c0-35.3-28.7-56-64-56h-48v-72s36.7-21.5 68.1-73.6c40.3-4.6 78.6-19 110-41.7 39.3-28.3 61.9-65 61.9-100.7V88c0-13.3-10.7-24-24-24zM99.3 192.8C74.9 175.2 64 155.6 64 144v-16h64.2c1 32.6 5.8 61.2 12.8 86.2-15.1-5.2-29.2-12.4-41.7-21.4zM512 144c0 16.1-17.7 36.1-35.3 48.8-12.5 9-26.7 16.2-41.8 21.4 7-25 11.8-53.6 12.8-86.2H512v16z"></path></svg> + </span> + <% end %> + #<%= rank %>: <%= link nick, to: alcoolog_path(@conn, :nick, @network, nick) %> + <br /> + <span class="text-xs"><%= Float.round(count, 4) %></span> + </li> + <% end %> +</ul> + + <h2 class="leading-8 m-4 font-semibold text-2xl">Historique</h2> +<div class="flex flex-col"> + <div class="-my-2 py-2 overflow-x-auto sm:-mx-6 sm:px-6 lg:-mx-8 lg:px-8"> + <div class="align-middle inline-block min-w-full shadow overflow-hidden sm:rounded-lg border-b border-gray-200"> + <table class="min-w-full divide-y divide-gray-200"> + <thead> + <tr> + <th class="px-6 py-3 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider"> + date + </th> + <th class="px-6 py-3 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider"> + nick + </th> + <th class="px-6 py-3 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider"> + + </th> + <th class="px-6 py-3 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider"> + + </th> + </tr> + </thead> + <tbody> + <%= for {{{{account, date}, points, _active, cl, deg, nom, comment, _meta}, nick}, index} <- Enum.with_index(@drinks) do %> + <% class = if(Integer.is_even(index), do: "bg-gray-50", else: "bg-white") %> + <% date = DateTime.from_unix!(date, :millisecond) %> + <tr class="<%= class %>"> + <td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 font-medium text-gray-900"> + <%= LSGWeb.LayoutView.format_time(date, false) %> + </td> + <td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 font-medium text-gray-900"> + <%= link nick, to: alcoolog_path(@conn, :nick, @network, nick) %> + </td> + <td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500"><%= cl %>cl <%= deg %>°</td> + <td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500"><%= comment||"" %></td> + </tr> + <% end %> + </tbody> + </table> + </div> + </div> +</div> <% end %> <%= if @conn.assigns.account && (@network || @channel) do %> <%= link("alcoolog global", to: alcoolog_path(@conn, :index)) %> <% end %> + +<link href='/assets/css/metricsgraphics.css' rel='stylesheet' type='text/css'> +<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.css" integrity="sha512-SUJFImtiT87gVCOXl3aGC00zfDl6ggYAw5+oheJvRJ8KBXZrr/TMISSdVJ5bBarbQDRC2pR5Kto3xTR0kpZInA==" crossorigin="anonymous" /> +<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.min.js" integrity="sha512-vBmx0N/uQOXznm/Nbkp7h0P1RfLSj0HQrFSzV8m7rOGyj30fYAOKHYvCNez+yM8IrfnW0TCodDEjRqf6fodf/Q==" crossorigin="anonymous"></script> +<script src="/assets/js/jquery3.1.0.min.js"></script> +<script src="/assets/js/d3.v4.min.js"></script> +<script src="/assets/js/metricsgraphics.min.js"></script> + <script type="text/javascript"> + (function() { + // oui s trè moch :( :( :( +var ctx = document.getElementById('myChart').getContext('2d'); + d3.json('<%= alcoolog_path(@conn, :index_gls_json, @network, LSGWeb.format_chan(@channel)) %>', function(data) { + + var dynamicColors = function() { + var r = Math.floor(Math.random() * 255); + var g = Math.floor(Math.random() * 255); + var b = Math.floor(Math.random() * 255); + return "rgb(" + r + "," + g + "," + b + ")"; + }; + + labels = data.labels; + datasets = $.map($.makeArray(data.data), function(set) { + return {label: set.name, data: set.history, fill: false, borderColor: dynamicColors()} + }); + + +var myChart = new Chart(ctx, { + type: 'line', + data: { + labels: labels, + datasets: datasets + }, + options: { + scales: { + xAxes: [{ + type: 'time', + time: { + unit: 'day' + } + }], + yAxes: [{ + ticks: { + beginAtZero: true + } + }] + } + } +}); +}); + + +})(); +</script> + diff --git a/lib/lsg_web/templates/alcoolog/user.html.eex b/lib/lsg_web/templates/alcoolog/user.html.eex new file mode 100644 index 0000000..3b2b20b --- /dev/null +++ b/lib/lsg_web/templates/alcoolog/user.html.eex @@ -0,0 +1,170 @@ +<%= if @stats.active > 0 do %> + <h3 class="text-gray-900 text-xl leading-5 font-semibold truncate"> + <% rising_class = if @stats.rising, do: "teal", else: "red" %> + <span class="flex-shrink-0 inline-block px-3 py-3 text-<%= rising_class %>-800 text-2xl leading-4 font-medium bg-<%= rising_class %>-100 rounded-full"> + <%= @stats.trend_symbol %> <%= Float.round(@stats.active, 4) %> g/l + </span> + + <span class="px-3"><%= @stats.last_cl %>cl @ <%= @stats.last_deg %>°</span> + + <span class="px-3 text-lg text-gray-700"><%= if @stats.last_descr && @stats.last_descr != "" do %> + <%= @stats.last_descr %> + <% end %> + </span> + + <span class="px-3 text-gray-500 text-sm font-thin"><%= LSGWeb.LayoutView.format_time(@stats.last_at) %></span> + + </h3> + + <p class="text-gray-500 font-thin text-lg"> + a commencé il y a <span class="text-gray-700 font-semibold"><%= @stats.since_s %></span> + — + sobre dans <span class="text-gray-700 font-semibold"><%= @stats.sober_in_s %></span> + </p> +<% else %> + <h3 class="text-gray-900 text-xl leading-5 font-semibold truncate"> + est sobre! + + <p class="text-gray-500 font-thin text-lg"> + dernier verre + <span class="px-3"><%= @stats.last_cl %>cl @ <%= @stats.last_deg %>°</span> + + <span class="px-3 text-lg text-gray-700"><%= if @stats.last_descr && @stats.last_descr != "" do %> + <%= @stats.last_descr %> + <% end %> + </span> + + <span class="px-3 text-gray-500 text-sm font-thin"><%= LSGWeb.LayoutView.format_time(@stats.last_at) %></span> + </h3> +<% end %> + +<canvas id="myChart" class="w-full" height="200"></canvas> +<canvas id="myChartGl" class="w-full" height="200"></canvas> + + +<h2 class="leading-8 m-4 font-semibold text-2xl">Historique</h2> +<div class="flex flex-col"> + <div class="-my-2 py-2 overflow-x-auto sm:-mx-6 sm:px-6 lg:-mx-8 lg:px-8"> + <div class="align-middle inline-block min-w-full shadow overflow-hidden sm:rounded-lg border-b border-gray-200"> + <table class="min-w-full divide-y divide-gray-200"> + <thead> + <tr> + <th class="px-6 py-3 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider"> + date + </th> + <th class="px-6 py-3 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider"> + + </th> + <th class="px-6 py-3 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider"> + + </th> + </tr> + </thead> + <tbody> + <%= for {%{at: date, cl: cl, deg: deg, description: comment}, index} <- Enum.with_index(@history) do %> + <% class = if(Integer.is_even(index), do: "bg-gray-50", else: "bg-white") %> + <tr class="<%= class %>"> + <td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 font-medium text-gray-900"> + <%= LSGWeb.LayoutView.format_time(date, false) %> + </td> + <td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500"><%= cl %>cl <%= deg %>°</td> + <td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500"><%= comment||"" %></td> + </tr> + <% end %> + </tbody> + </table> + </div> + </div> +</div> + +<div id="metrics-gl" class="w-full"></div> + +<link href='/assets/css/metricsgraphics.css' rel='stylesheet' type='text/css'> +<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.css" integrity="sha512-SUJFImtiT87gVCOXl3aGC00zfDl6ggYAw5+oheJvRJ8KBXZrr/TMISSdVJ5bBarbQDRC2pR5Kto3xTR0kpZInA==" crossorigin="anonymous" /> +<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.min.js" integrity="sha512-vBmx0N/uQOXznm/Nbkp7h0P1RfLSj0HQrFSzV8m7rOGyj30fYAOKHYvCNez+yM8IrfnW0TCodDEjRqf6fodf/Q==" crossorigin="anonymous"></script> +<script src="/assets/js/jquery3.1.0.min.js"></script> +<script src="/assets/js/d3.v4.min.js"></script> +<script src="/assets/js/metricsgraphics.min.js"></script> + <script type="text/javascript"> + (function() { +var ctx = document.getElementById('myChart').getContext('2d'); + d3.json('<%= alcoolog_path(@conn, :nick_volumes_json, @network, @nick, days: @days) %>', function(data) { +var myChart = new Chart(ctx, { + type: 'bar', + data: { + labels: data.map(function(data) { return new Date(data.date) }), + datasets: [{ + label: 'Volumes d\'alcool', + data: data.map(function(data) { return data.volumes }), + borderWidth: 1 + }] + }, + options: { + scales: { + xAxes: [{ + type: 'time', + time: { + unit: 'day' + } + }], + yAxes: [{ + ticks: { + beginAtZero: true + } + }] + } + } +}); +}); + + + + +var ctxgl = document.getElementById('myChartGl').getContext('2d'); + d3.json('<%= alcoolog_path(@conn, :nick_gls_json, @network, @nick, days: @days) %>', function(data) { +var myChartgl = new Chart(ctxgl, { + type: 'bar', + data: { + labels: data.map(function(data) { return new Date(data.date) }), + datasets: [{ + label: 'g/l ingérés', + data: data.map(function(data) { return data.gls }), + borderWidth: 1 + }] + }, + options: { + scales: { + xAxes: [{ + type: 'time', + time: { + unit: 'day' + } + }], + yAxes: [{ + ticks: { + beginAtZero: true + } + }] + } + } +}); +}); + + + d3.json('<%= alcoolog_path(@conn, :nick_log_json, @network, @nick, days: @days) %>', function(data) { + data = data.map(function(d) { + date = new Date(d.at); + return {"date": date, "active": d.active}; + }); + MG.data_graphic({ + title: "g/l, All Time", + data: data, + width: 1000, + height: 400, + target: document.getElementById('metrics-gl'), + x_accessor: 'date', + y_accessor: 'active', + }); + }); +})(); +</script> diff --git a/lib/lsg_web/templates/irc/index.html.eex b/lib/lsg_web/templates/irc/index.html.eex index 9e4f724..a8544b3 100644 --- a/lib/lsg_web/templates/irc/index.html.eex +++ b/lib/lsg_web/templates/irc/index.html.eex @@ -1,19 +1,12 @@ -<style type="text/css"> -.help-entry h1 { - font-size: 18px; -} -.help-entry h2 { - font-size: 16px; -} -</style> - -<p> +<div class="hidden sm:block"> + <nav class="flex flex-wrap content-center"> <% list = for {identifier, _} <- @commands do %> <% name = String.replace(identifier, "_", " ") %> - <%= link(name, to: "##{identifier}") %> + <%= link(name, to: "##{identifier}", class: "px-3 py-2 font-medium text-sm leading-5 rounded-md text-gray-500 hover:text-gray-700 focus:outline-none focus:text-indigo-600 focus:bg-indigo-50") %> <% end %> - <small><%= Enum.intersperse(list, " - ") %></small> -</p> + <%= list %> + </nav> +</div> <%= if @members != [] do %> <% users = for {_acc, user, nick} <- @members, do: if(user, do: nick, else: content_tag(:i, nick)) %> @@ -22,10 +15,12 @@ <% end %> <% end %> -<div class="irchelps"> +<div class="irchelps space-y-6"> <%= for {identifier, help} <- @commands do %> <%= if help do %> - <div class="help-entry" id="<%= identifier %>"><%= LSGWeb.LayoutView.liquid_markdown(@conn, help) %></div> + <div class="bg-white border-b border-gray-200" id="<%= identifier %>"> + <div class="prose w-auto max-w-full"><%= LSGWeb.LayoutView.liquid_markdown(@conn, help) %></div> + </div> <% end %> <% end %> </div> diff --git a/lib/lsg_web/templates/irc/txt.html.eex b/lib/lsg_web/templates/irc/txt.html.eex index e9df681..fd4ea00 100644 --- a/lib/lsg_web/templates/irc/txt.html.eex +++ b/lib/lsg_web/templates/irc/txt.html.eex @@ -1,15 +1,27 @@ <style type="text/css"> -ol li { - margin-bottom: 5px +:target { + background-color: #ffa; + font-weight: bold; +} +ol > li > a { + display: none; +} +ol > li:hover > a { + display: inline-block; + color: gray; } </style> -<ol> +<ol class="prose space-y-3 w-auto max-w-full list-outside list-decimal m-4 leading-loose"> <%= for {txt, id} <- Enum.with_index(@data) do %> - <li id="<%= @name %>-<%= id %>"><%= txt %></li> + <li class="text-lg" id="q<%= id+1 %>"> + + <%= txt %> + <a href="#q<%= id+1 %>" class="text-xs text-gray-500 space-x-3">#</a> + </li> <% end %> </ol> <p> - <a href="/irc/txt/<%= @name %>.txt">télécharger au format texte</a> + <a href="/-/txt/<%= @name %>.txt" class="text-xs text-gray-500">télécharger au format texte</a> </p> diff --git a/lib/lsg_web/templates/irc/txts.html.eex b/lib/lsg_web/templates/irc/txts.html.eex index 5971ffa..66321b5 100644 --- a/lib/lsg_web/templates/irc/txts.html.eex +++ b/lib/lsg_web/templates/irc/txts.html.eex @@ -1,25 +1,26 @@ -<style type="text/css"> -.help-entry h1 { - font-size: 18px; -} -.help-entry h2 { - font-size: 16px; -} -</style> - -<p><strong><%= @lines %></strong> lignes dans <strong><%= @files %></strong> fichiers. -<a href="#help">Aide</a>. -</p> - -<ul> +<div> + <h2 class="text-gray-500 text-xs font-medium uppercase tracking-wide"> + <strong><%= @lines %></strong> lignes dans <strong><%= @files %></strong> fichiers + — + <a href="#help">Aide</a> + </h2> + <ul class="mt-3 grid grid-cols-1 gap-5 sm:gap-6 sm:grid-cols-4 lg:grid-cols-6"> <%= for {txt, data} <- @data do %> <% base_url = cond do @conn.assigns[:chan] -> "/#{@conn.assigns.network}/#{LSGWeb.format_chan(@conn.assigns.chan)}" true -> "/-" end %> - <li><a href="<%= base_url %>/txt/<%= txt %>"><%= txt %></a> <i>(<%= Enum.count(data) %>)</i></li> + <li class="col-span-1 flex shadow-sm rounded-m"> + <div class="flex-1 flex items-center justify-between border-l border-t border-r border-b border-gray-200 bg-white rounded-md truncate"> + <div class="flex-1 px-4 py-2 text-sm leading-5 truncate"> + <a href="<%= base_url %>/txt/<%= txt %>" class="text-gray-900 text-lg font-medium hover:text-gray-600 transition ease-in-out duration-150"><%= txt %></a> + <p class="text-gray-500"><%= Enum.count(data) %> lignes</p> + </div> + </div> + </li> <% end %> -</ul> + </ul> +</div> -<div class="help-entry" id="help"><%= LSGWeb.LayoutView.liquid_markdown(@conn, @doc) %></div> +<div class="prose" id="help"><%= LSGWeb.LayoutView.liquid_markdown(@conn, @doc) %></div> diff --git a/lib/lsg_web/templates/layout/app.html.eex b/lib/lsg_web/templates/layout/app.html.eex index 1871e8b..9e78e8e 100644 --- a/lib/lsg_web/templates/layout/app.html.eex +++ b/lib/lsg_web/templates/layout/app.html.eex @@ -8,28 +8,137 @@ <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="robots" content="noindex, noarchive, nofollow, nosnippet" /> <title><%= Map.get(assigns, :title, "") %></title> - <link rel="stylesheet" href="<%= static_path(@conn, "/assets/css/app.css") %>"> + <link rel="stylesheet" href="<%= static_path(@conn, "/assets/css/tailwind-ui.min.css") %>"> </head> <body> - <div class="container"> - <main role="main"> - <%= if !@conn.assigns[:no_header] do %> - <h1> - <small style="font-size: 14px;"> - <a href="/"><%= Keyword.get(Application.get_env(:lsg, :irc), :name, "ircbot") %></a> - <%= if @conn.assigns[:account], do: @conn.assigns.account.name %> - › +<div> + <div class="bg-gray-800 pb-32"> + <nav class="bg-gray-800"> + <div class="max-w-7xl mx-auto sm:px-6 lg:px-8"> + <div class="border-b border-gray-700"> + <div class="flex items-center justify-between h-16 px-4 sm:px-0"> + <div class="flex items-center"> + <div class="flex-shrink-0"> + <img class="h-8 w-8" src="https://tailwindui.com/img/logos/workflow-mark-on-dark.svg" alt="Workflow logo"> + </div> + <div class="hidden md:block"> + <div class="ml-10 flex items-baseline"> + <a href="/" class="px-3 py-2 rounded-md text-sm font-medium text-white bg-gray-900 focus:outline-none focus:text-white focus:bg-gray-700">bot.goulag.org</a> + <!--<a href="#" class="ml-4 px-3 py-2 rounded-md text-sm font-medium text-gray-300 hover:text-white hover:bg-gray-700 focus:outline-none focus:text-white focus:bg-gray-700">Team</a> + <a href="#" class="ml-4 px-3 py-2 rounded-md text-sm font-medium text-gray-300 hover:text-white hover:bg-gray-700 focus:outline-none focus:text-white focus:bg-gray-700">Projects</a> + <a href="#" class="ml-4 px-3 py-2 rounded-md text-sm font-medium text-gray-300 hover:text-white hover:bg-gray-700 focus:outline-none focus:text-white focus:bg-gray-700">Calendar</a> + <a href="#" class="ml-4 px-3 py-2 rounded-md text-sm font-medium text-gray-300 hover:text-white hover:bg-gray-700 focus:outline-none focus:text-white focus:bg-gray-700">Reports</a>--> + </div> + </div> + </div> + <div class="hidden md:block"> + <div class="ml-4 flex items-center md:ml-6"> + <!--<button class="p-1 border-2 border-transparent text-gray-400 rounded-full hover:text-white focus:outline-none focus:text-white focus:bg-gray-700" aria-label="Notifications"> + <svg class="h-6 w-6" stroke="currentColor" fill="none" viewBox="0 0 24 24"> + <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9" /> + </svg> + </button>--> + <!-- Profile dropdown --> + <div class="ml-3 relative"> + <div> + <button class="max-w-xs flex items-center text-sm rounded-full text-white focus:outline-none focus:shadow-solid" id="user-menu" aria-label="User menu" aria-haspopup="true"> + <!--<img class="h-8 w-8 rounded-full" src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt="">--> + ~<%= if @conn.assigns[:account], do: @conn.assigns.account.name %> + + </button> + </div> + <!-- + Profile dropdown panel, show/hide based on dropdown state. + + Entering: "transition ease-out duration-100" + From: "transform opacity-0 scale-95" + To: "transform opacity-100 scale-100" + Leaving: "transition ease-in duration-75" + From: "transform opacity-100 scale-100" + To: "transform opacity-0 scale-95" + --> + <!--<div class="origin-top-right absolute right-0 mt-2 w-48 rounded-md shadow-lg"> + <div class="py-1 rounded-md bg-white shadow-xs"> + <a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Your Profile</a> + <a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Settings</a> + <a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Sign out</a> + </div> + </div>--> + </div> + </div> + </div> + <div class="-mr-2 flex md:hidden"> + <!-- Mobile menu button --> + <button class="inline-flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-white hover:bg-gray-700 focus:outline-none focus:bg-gray-700 focus:text-white"> + <!-- Menu open: "hidden", Menu closed: "block" --> + <svg class="block h-6 w-6" stroke="currentColor" fill="none" viewBox="0 0 24 24"> + <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" /> + </svg> + <!-- Menu open: "block", Menu closed: "hidden" --> + <svg class="hidden h-6 w-6" stroke="currentColor" fill="none" viewBox="0 0 24 24"> + <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" /> + </svg> + </button> + </div> + </div> + </div> + </div> + + <!-- + Mobile menu, toggle classes based on menu state. + + Open: "block", closed: "hidden" + --> + <div class="hidden border-b border-gray-700 md:hidden"> + <div class="px-2 py-3 sm:px-3"> + <a href="#" class="block px-3 py-2 rounded-md text-base font-medium text-white bg-gray-900 focus:outline-none focus:text-white focus:bg-gray-700">Dashboard</a> + <a href="#" class="mt-1 block px-3 py-2 rounded-md text-base font-medium text-gray-300 hover:text-white hover:bg-gray-700 focus:outline-none focus:text-white focus:bg-gray-700">Team</a> + <a href="#" class="mt-1 block px-3 py-2 rounded-md text-base font-medium text-gray-300 hover:text-white hover:bg-gray-700 focus:outline-none focus:text-white focus:bg-gray-700">Projects</a> + <a href="#" class="mt-1 block px-3 py-2 rounded-md text-base font-medium text-gray-300 hover:text-white hover:bg-gray-700 focus:outline-none focus:text-white focus:bg-gray-700">Calendar</a> + <a href="#" class="mt-1 block px-3 py-2 rounded-md text-base font-medium text-gray-300 hover:text-white hover:bg-gray-700 focus:outline-none focus:text-white focus:bg-gray-700">Reports</a> + </div> + <div class="pt-4 pb-3 border-t border-gray-700"> + <div class="flex items-center px-5"> + <div class="flex-shrink-0"> + <img class="h-10 w-10 rounded-full" src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt=""> + </div> + <div class="ml-3"> + <div class="text-base font-medium leading-none text-white">Tom Cook</div> + <div class="mt-1 text-sm font-medium leading-none text-gray-400">tom@example.com</div> + </div> + </div> + <div class="mt-3 px-2" role="menu" aria-orientation="vertical" aria-labelledby="user-menu"> + <a href="#" class="block px-3 py-2 rounded-md text-base font-medium text-gray-400 hover:text-white hover:bg-gray-700 focus:outline-none focus:text-white focus:bg-gray-700" role="menuitem">Your Profile</a> + <a href="#" class="mt-1 block px-3 py-2 rounded-md text-base font-medium text-gray-400 hover:text-white hover:bg-gray-700 focus:outline-none focus:text-white focus:bg-gray-700" role="menuitem">Settings</a> + <a href="#" class="mt-1 block px-3 py-2 rounded-md text-base font-medium text-gray-400 hover:text-white hover:bg-gray-700 focus:outline-none focus:text-white focus:bg-gray-700" role="menuitem">Sign out</a> + </div> + </div> + </div> + </nav> + <header class="py-10"> + <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> + <h1 class="text-3xl leading-9 font-bold text-white"> <%= if n = @conn.assigns[:network] do %><a href="/<%= n %>"><%= n %></a> › <% end %> <%= if c = @conn.assigns[:chan] do %><a href="/<%= @conn.assigns.network %>/<%= LSGWeb.format_chan(c) %>"><%= c %></a> › <% end %> <%= for({name, href} <- @conn.assigns[:breadcrumbs]||[], do: [link(name, to: href), raw(" › ")]) %> - </small><br /> <%= @conn.assigns[:title] || @conn.assigns[:chan] || @conn.assigns[:network] %> - </h1> - <% end %> + </h1> + </div> + </header> + </div> + + <main class="-mt-32"> + <div class="max-w-7xl mx-auto pb-12 px-4 sm:px-6 lg:px-8"> + <!-- Replace with your content --> + <div class="bg-white rounded-lg shadow px-5 py-6 sm:px-6"> <%= render @view_module, @view_template, assigns %> - </main> + </div> + <!-- /End replace --> </div> + </main> +</div> + <script src="<%= static_path(@conn, "/assets/js/app.js") %>"></script> </body> </html> diff --git a/lib/lsg_web/templates/page/user.html.eex b/lib/lsg_web/templates/page/user.html.eex index 8a043a0..56fc485 100644 --- a/lib/lsg_web/templates/page/user.html.eex +++ b/lib/lsg_web/templates/page/user.html.eex @@ -1,3 +1,4 @@ +<div class="prose prose-lg"> <ul> <li><%= link("Help", to: "/-") %></li> </ul> @@ -36,3 +37,4 @@ <li><%= net %>: <%= to_string(predicate) %>, <%= v %></li> <% end %> </ul> +</div> diff --git a/lib/lsg_web/views/alcoolog_view.ex b/lib/lsg_web/views/alcoolog_view.ex index 2c55c09..ed3c9b4 100644 --- a/lib/lsg_web/views/alcoolog_view.ex +++ b/lib/lsg_web/views/alcoolog_view.ex @@ -1,4 +1,6 @@ defmodule LSGWeb.AlcoologView do use LSGWeb, :view + require Integer + end diff --git a/lib/lsg_web/views/layout_view.ex b/lib/lsg_web/views/layout_view.ex index b28d3c5..41c5341 100644 --- a/lib/lsg_web/views/layout_view.ex +++ b/lib/lsg_web/views/layout_view.ex @@ -60,11 +60,14 @@ defmodule LSGWeb.LayoutView do now_last_week = {y, w-1} now_last_roll = 7-Timex.days_to_beginning_of_week(now) + date_date = DateTime.to_date(date) + now_date = DateTime.to_date(date) + format = cond do date.year != now.year -> "{D}/{M}/{YYYY} {h24}:{m}" - date.day == now.day -> "{h24}:{m}" + date_date == now_date -> "{h24}:{m}" (now_week == date_week) || (date_week == now_last_week && (Date.day_of_week(date) >= now_last_roll)) -> "{WDfull} {h24}:{m}" - (now.month == date.month) -> "{WDfull} {D} {h24}:{m}" + (now.year == date.year && now.month == date.month) -> "{WDfull} {D} {h24}:{m}" true -> "{WDfull} {D} {M} {h24}:{m}" end |