diff options
Diffstat (limited to 'lib/nola_web/templates/alcoolog')
-rw-r--r-- | lib/nola_web/templates/alcoolog/auth.html.eex | 43 | ||||
-rw-r--r-- | lib/nola_web/templates/alcoolog/index.html.eex | 205 | ||||
-rw-r--r-- | lib/nola_web/templates/alcoolog/user.html.eex | 170 |
3 files changed, 418 insertions, 0 deletions
diff --git a/lib/nola_web/templates/alcoolog/auth.html.eex b/lib/nola_web/templates/alcoolog/auth.html.eex new file mode 100644 index 0000000..6e5cedc --- /dev/null +++ b/lib/nola_web/templates/alcoolog/auth.html.eex @@ -0,0 +1,43 @@ +<div class="grid grid-cols-2"> + <h1 class="text-2xl font-bold">authentication</h1> + <div class="text-right"> + <%= link("connect using random.sh", to: "/login/oidc", class: "inline-block font-medium underline") %> + </div> +</div> + +<div id="authenticator" class="mt-12 h-32 place-self-end justify-self-start"> + <p> + <%= if @bot, do: "Send this to #{@bot} on #{@network}:", else: "Find your bot nickname and send:" %><br /><br /> + <strong>/msg <%= @bot || "the-bot-nickname" %> web</strong> + <br /><br /> + ... then come back to this address. + </p> +</div> + +<script type="text/javascript"> + var authSse = new EventSource("/api/irc-auth.sse?redirect_to=" + window.location.pathname); + authSse.addEventListener("token", function(event) { + html = "<%= if @bot, do: "Send this to #{@bot} on #{@network}:", else: "Find your bot nickname and send:" %><br /><br /><strong class='text-xl font-mono ml-12'>/msg <%= @bot || "<the-bot-nickname>" %> "+event.data+"</strong>"; + elem = document.getElementById("authenticator"); + elem.innerHTML = html; + }); + authSse.addEventListener("authenticated", function(event) { + elem = document.getElementById("authenticator"); + elem.innerHTML = "<strong>success, redirecting...</strong>"; + window.keepInner = true; + window.location.pathname = event.data; + }); + authSse.addEventListener("expire", function(event) { + elem = document.getElementById("authenticator"); + elem.innerHTML = "<strong>authentication expired</strong>"; + window.keepInner = true; + }); + authSse.onerror = function() { + authSse.close(); + if (!window.keepInner) { + elem = document.getElementById("authenticator"); + elem.innerHTML = "<strong>server closed connection :(</strong>"; + } + }; + +</script> diff --git a/lib/nola_web/templates/alcoolog/index.html.eex b/lib/nola_web/templates/alcoolog/index.html.eex new file mode 100644 index 0000000..5a5423a --- /dev/null +++ b/lib/nola_web/templates/alcoolog/index.html.eex @@ -0,0 +1,205 @@ +<style type="text/css"> +ol li { + margin-bottom: 5px +} +</style> + +<%= if @stats == [] do %> + <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 class="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3"> + <%= for {nick, status} <- @stats do %> + <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><%= NolaWeb.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 %> + <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 %> + +<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"> + <%= NolaWeb.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='/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="/js/jquery3.1.0.min.js"></script> +<script src="/js/d3.v4.min.js"></script> +<script src="/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, NolaWeb.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/nola_web/templates/alcoolog/user.html.eex b/lib/nola_web/templates/alcoolog/user.html.eex new file mode 100644 index 0000000..d7f716b --- /dev/null +++ b/lib/nola_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"><%= NolaWeb.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"><%= NolaWeb.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"> + <%= NolaWeb.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='/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="/js/jquery3.1.0.min.js"></script> +<script src="/js/d3.v4.min.js"></script> +<script src="/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> |