finish activity ui

This commit is contained in:
2025-06-22 08:51:48 +02:00
parent e79626972f
commit 7c14e469c9
19 changed files with 378 additions and 101 deletions

View File

@@ -1,16 +1,16 @@
<h2>Forgot your password?</h2>
<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| %>
<%= render "devise/shared/error_messages", resource: resource %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email" %>
<div class="login-card">
<h2 class="login-heading">Forgot your password?</h2>
<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| %>
<%= render "devise/shared/error_messages", resource: resource %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email" %>
</div>
<div class="actions">
<%= f.submit "Send me reset password instructions" %>
</div>
<% end %>
<div style="margin-top: 1.5em;">
<%= render "devise/shared/links" %>
</div>
<div class="actions">
<%= f.submit "Send me reset password instructions" %>
</div>
<% end %>
<%= render "devise/shared/links" %>
</div>

View File

@@ -1,29 +1,27 @@
<h2>Sign up</h2>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= render "devise/shared/error_messages", resource: resource %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email" %>
<div class="login-card">
<h2 class="login-heading">Sign up</h2>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= render "devise/shared/error_messages", resource: resource %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email" %>
</div>
<div class="field">
<%= f.label :password %>
<% if @minimum_password_length %>
<em>(<%= @minimum_password_length %> characters minimum)</em>
<% end %><br />
<%= f.password_field :password, autocomplete: "new-password" %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "new-password" %>
</div>
<div class="actions">
<%= f.submit "Sign up" %>
</div>
<% end %>
<div style="margin-top: 1.5em;">
<%= render "devise/shared/links" %>
</div>
<div class="field">
<%= f.label :password %>
<% if @minimum_password_length %>
<em>(<%= @minimum_password_length %> characters minimum)</em>
<% end %><br />
<%= f.password_field :password, autocomplete: "new-password" %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "new-password" %>
</div>
<div class="actions">
<%= f.submit "Sign up" %>
</div>
<% end %>
<%= render "devise/shared/links" %>
</div>

View File

@@ -1,26 +1,28 @@
<h2>Log in</h2>
<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email" %>
</div>
<div class="field">
<%= f.label :password %><br />
<%= f.password_field :password, autocomplete: "current-password" %>
</div>
<% if devise_mapping.rememberable? %>
<div class="login-card">
<h2 class="login-heading">Log in</h2>
<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
<div class="field">
<%= f.check_box :remember_me %>
<%= f.label :remember_me %>
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email" %>
</div>
<div class="field">
<%= f.label :password %><br />
<%= f.password_field :password, autocomplete: "current-password" %>
</div>
<% if devise_mapping.rememberable? %>
<div class="field">
<%= f.check_box :remember_me %>
<%= f.label :remember_me %>
</div>
<% end %>
<div class="actions">
<%= f.submit "Log in" %>
</div>
<% end %>
<div class="actions">
<%= f.submit "Log in" %>
<div style="margin-top: 1.5em;">
<%= render "devise/shared/links" %>
</div>
<% end %>
<%= render "devise/shared/links" %>
</div>

View File

@@ -1,17 +0,0 @@
<div style="display: flex; justify-content: flex-end; margin-bottom: 1.5em;">
<%= link_to 'Statistics Dashboard', statistics_path, style: 'background: #0071e3; color: #fff; padding: 0.6em 1.5em; border-radius: 10px; text-decoration: none; font-weight: 500; font-size: 1.05em; box-shadow: 0 1px 4px rgba(0,0,0,0.05); transition: background 0.2s;'
%>
</div>
<h1>Hello, <%= @user.email %>!</h1>
<h2>Your Logins</h2>
<ul>
<% @logins.each do |login| %>
<li>
Platform: <%= login.platform %> | Last refreshed: <%= login.last_refresh_at || 'Never' %>
</li>
<% end %>
</ul>
<button disabled style="margin-top: 20px;">Add New Login (Coming Soon)</button>

View File

@@ -0,0 +1,19 @@
<header class="site-header">
<div class="logo">
<a href="/" style="display: flex; align-items: center; gap: 0.5em; text-decoration: none;">
<img src="/plays_hub_logo.svg" alt="Plays Hub Logo" width="64" height="64" style="display: inline-block; vertical-align: middle;" />
<span style="font-weight: bold; font-size: 1.4em; color: #0071e3;">Plays Hub</span>
</a>
</div>
<% if user_signed_in? %>
<nav>
<a href="/statistics">Statistics</a>
<%= button_to "Logout", destroy_user_session_path, method: :delete, class: "logout-btn logout-link-btn", form: {style: 'display:inline'} %>
</nav>
<% else %>
<nav>
<a href="/users/sign_in">Login</a>
<a href="/users/sign_up">Sign up</a>
</nav>
<% end %>
</header>

View File

@@ -23,6 +23,7 @@
</head>
<body>
<%= render partial: 'layouts/header' %>
<%= yield %>
<% if notice %>
<p class="notice"><%= notice %></p>

View File

@@ -1,4 +1,4 @@
<div style="background: #fff; border-radius: 16px; box-shadow: 0 2px 12px rgba(0,0,0,0.06); padding: 2em 2.5em; margin: 2em 0 2.5em 0; width: 100%; max-width: 1200px; margin-left: auto; margin-right: auto;">
<div style="background: #fff; border-radius: 16px; box-shadow: 0 2px 12px rgba(0,0,0,0.06); padding: 2em 2.5em; margin: 2em 0 2.5em 0; width: 100%; max-width: 1110px; margin-left: auto; margin-right: auto;">
<h2 style="margin-top:0; font-size: 1.4em; color: #0071e3;">Activity History</h2>
<div id="activity-heatmap" style="margin-top: 1em;"></div>
<script>

View File

@@ -0,0 +1,12 @@
<div class="dashboard-widget dashboard-longest-streak">
<% if streak %>
<h3 class="widget-title">Longest Listening Streak</h3>
<div class="widget-content">
<div><strong>Streak:</strong> <%= streak[:length] %> days (<%= streak[:start_date].strftime('%b %d, %Y') %> <%= streak[:end_date].strftime('%b %d, %Y') %>)</div>
<div><strong>Total Plays:</strong> <%= streak[:total_plays] %></div>
<div><strong>Most Played Song:</strong> <%= streak[:most_played_song] || 'N/A' %> <%= "(#{streak[:most_played_song_count]} plays)" if streak[:most_played_song] %></div>
</div>
<% else %>
<div style="color: #888;">No listening streak yet. Start playing to build your first streak!</div>
<% end %>
</div>

View File

@@ -1,3 +0,0 @@
<div style="background: #fff; border-radius: 16px; box-shadow: 0 2px 12px rgba(0,0,0,0.06); padding: 2em 2.5em; color: #888; display: flex; align-items: center; justify-content: center; min-height: 100px;">
<span>(Placeholder widget)</span>
</div>

View File

@@ -4,8 +4,11 @@
<%= @total_plays %>
</div>
<% if defined?(@since_date) && @since_date.present? %>
<div style="margin-top: 0.8em; color: #888; font-size: 1em; font-weight: 400;">
<div style="margin-top: 0.4em; color: #888; font-size: 1em; font-weight: 400;">
since <%= @since_date.strftime('%b %-d, %Y') %>
</div>
<% end %>
<div class="widget-content" style="margin-top: 1.2em;">
<strong>This year:</strong> <%= @year_plays %> plays
</div>
</div>

View File

@@ -1,5 +1,5 @@
<main>
<h1>Statistics Dashboard</h1>
<h1>Statistics Dashboard - <%= current_user.email %></h1>
<%= javascript_include_tag 'activity_heatmap', 'data-turbo-track': 'reload' %>
<!-- Activity Heatmap (full width) -->
@@ -10,11 +10,11 @@
<!-- Top 5 Artists Widget -->
<%= render partial: 'statistics/top_artists', locals: { top_artists_all_time: @top_artists_all_time, top_artists_year: @top_artists_year, top_artists_upcoming: @top_artists_upcoming } %>
<!-- Right column: Total Plays + Placeholder stacked -->
<div style="display: flex; flex-direction: column; gap: 2em; flex: 1 1 220px; min-width: 220px; max-width: 320px; align-self: flex-start;">
<div style="display: flex; flex-direction: column; gap: 2em; flex: 1 1 220px; min-width: 220px; max-width: 620px; align-self: flex-start;">
<!-- Total Plays Widget -->
<%= render partial: 'statistics/total_plays', locals: { total_plays: @total_plays } %>
<!-- Placeholder Widget -->
<%= render partial: 'statistics/placeholder' %>
<%= render partial: 'statistics/longest_streak', locals: { streak: @streak } %>
</div>
</div>
</main>