mirror of
https://github.com/Freika/dawarich.git
synced 2026-01-10 01:01:39 -05:00
353 lines
13 KiB
Text
353 lines
13 KiB
Text
<!-- Monthly Digest Header -->
|
|
<div class="hero text-white rounded-lg shadow-lg mb-8"
|
|
style="background-image: url('<%= month_bg_image(stat) %>');">
|
|
<div class="hero-overlay bg-opacity-60"></div>
|
|
<div class="hero-content text-center relative w-full">
|
|
<div class="max-w-md mt-5">
|
|
<h1 class="text-4xl font-bold flex items-center justify-center gap-2">
|
|
<%= "#{icon month_icon(stat)} #{Date::MONTHNAMES[month]} #{year}".html_safe %>
|
|
</h1>
|
|
<p class="py-4">Monthly Digest</p>
|
|
<button class="btn btn-outline btn-sm text-neutral border-neutral hover:bg-white hover:text-primary"
|
|
onclick="sharing_modal.showModal()">
|
|
<%= icon 'share' %> Share
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="stats shadow shadow-lg mx-auto mb-8 w-full">
|
|
<div class="stat place-items-center text-center">
|
|
<div class="stat-title flex items-center justify-center gap-1">
|
|
<%= icon 'map-plus' %> Distance traveled
|
|
</div>
|
|
<div class="stat-value text-success">~<%= distance_traveled(current_user, stat) %></div>
|
|
<div class="stat-desc"><%= x_than_average_distance(stat, @average_distance_this_year) %></div>
|
|
</div>
|
|
|
|
<div class="stat place-items-center text-center">
|
|
<div class="stat-title flex items-center justify-center gap-1">
|
|
<%= icon 'calendar-check-2' %> Active days
|
|
</div>
|
|
<div class="stat-value text-secondary">
|
|
<%= active_days(stat) %>
|
|
</div>
|
|
<div class="stat-desc">
|
|
<%= x_than_previous_active_days(stat, previous_stat) %>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="stat place-items-center text-center">
|
|
<div class="stat-title flex items-center justify-center gap-1">
|
|
<%= icon 'map-pin-plus' %> Countries visited
|
|
</div>
|
|
<div class="stat-value text-accent">
|
|
<%= countries_visited(stat) %>
|
|
</div>
|
|
<div class="stat-desc">
|
|
<%= x_than_previous_countries_visited(stat, previous_stat) %>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Map Summary - Full Width -->
|
|
<div class="card bg-base-100 shadow-xl mb-8"
|
|
data-controller="stat-page"
|
|
data-api-key="<%= current_user.api_key %>"
|
|
data-year="<%= year %>"
|
|
data-month="<%= month %>"
|
|
data-self-hosted="<%= @self_hosted %>">
|
|
<div class="card-body">
|
|
<div class="flex justify-between items-center mb-4">
|
|
<h2 class="card-title">
|
|
<%= icon 'map' %>
|
|
Map Summary
|
|
</h2>
|
|
<div class="flex gap-2">
|
|
<button class="btn btn-sm btn-outline btn-active" data-stat-page-target="heatmapBtn" data-action="click->stat-page#toggleHeatmap">
|
|
<%= icon 'flame' %> Heatmap
|
|
</button>
|
|
<button class="btn btn-sm btn-outline" data-stat-page-target="pointsBtn" data-action="click->stat-page#togglePoints">
|
|
<%= icon 'map-pin' %> Points
|
|
</button>
|
|
<button class="btn btn-sm btn-outline" data-stat-page-target="placesBtn" data-action="click->stat-page#togglePlaces">
|
|
<%= icon 'map-pin-plus' %> Places
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Leaflet Map Container -->
|
|
<div class="w-full h-96 rounded-lg border border-base-300 relative overflow-hidden">
|
|
<div id="monthly-stats-map" data-stat-page-target="map" class="w-full h-full"></div>
|
|
|
|
<!-- Loading overlay -->
|
|
<div data-stat-page-target="loading" class="absolute inset-0 bg-base-200 flex items-center justify-center">
|
|
<span class="loading loading-spinner loading-lg text-primary"></span>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Tag Filters -->
|
|
<% if current_user.tags.any? %>
|
|
<div class="mt-4 p-4 bg-base-200 rounded-lg">
|
|
<h3 class="font-semibold mb-3 flex items-center gap-2">
|
|
<%= icon 'filter' %> Filter Places by Tags
|
|
</h3>
|
|
<div class="flex flex-wrap gap-3">
|
|
<% current_user.tags.ordered.each do |tag| %>
|
|
<label class="flex items-center gap-2 cursor-pointer hover:bg-base-300 px-3 py-2 rounded-lg transition-colors">
|
|
<input type="checkbox"
|
|
data-tag-id="<%= tag.id %>"
|
|
data-action="change->stat-page#filterPlacesByTags"
|
|
class="checkbox checkbox-sm checkbox-primary">
|
|
<span class="text-xl"><%= tag.icon %></span>
|
|
<span class="text-sm font-medium">#<%= tag.name %></span>
|
|
<% if tag.color.present? %>
|
|
<span class="w-3 h-3 rounded-full ml-1" style="background-color: <%= tag.color %>;"></span>
|
|
<% end %>
|
|
</label>
|
|
<% end %>
|
|
</div>
|
|
<div class="mt-2 text-sm text-base-content/70">
|
|
<%= icon 'info' %> Select tags to filter places on the map. Uncheck all to show all places.
|
|
</div>
|
|
</div>
|
|
<% end %>
|
|
|
|
<!-- Map Stats -->
|
|
<!--div class="stats grid grid-cols-2 md:grid-cols-4 gap-4 mt-4">
|
|
<div class="stat">
|
|
<div class="stat-title text-xs">Most visited</div>
|
|
<div class="stat-value text-sm">Downtown Area</div>
|
|
<div class="stat-desc text-xs">42 visits</div>
|
|
</div>
|
|
<div class="stat">
|
|
<div class="stat-title text-xs">Longest trip</div>
|
|
<div class="stat-value text-sm">156km</div>
|
|
<div class="stat-desc text-xs">Jan 15th</div>
|
|
</div>
|
|
<div class="stat">
|
|
<div class="stat-title text-xs">Total points</div>
|
|
<div class="stat-value text-sm">2,847</div>
|
|
<div class="stat-desc text-xs">tracked locations</div>
|
|
</div>
|
|
<div class="stat">
|
|
<div class="stat-title text-xs">Coverage area</div>
|
|
<div class="stat-value text-sm">45km²</div>
|
|
<div class="stat-desc text-xs">explored</div>
|
|
</div>
|
|
</div-->
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Daily Activity Chart -->
|
|
<div class="card bg-base-100 shadow-xl mb-8">
|
|
<div class="card-body">
|
|
<h2 class="card-title">
|
|
<%= icon 'activity' %> Daily Activity
|
|
</h2>
|
|
<div class="w-full h-48 bg-base-200 rounded-lg p-4 relative">
|
|
<%= column_chart(
|
|
stat.daily_distance.map { |day, distance_meters|
|
|
[day, Stat.convert_distance(distance_meters, current_user.safe_settings.distance_unit).round]
|
|
},
|
|
height: '200px',
|
|
suffix: " #{current_user.safe_settings.distance_unit}",
|
|
xtitle: 'Day',
|
|
ytitle: 'Distance',
|
|
colors: [
|
|
'#570df8', '#f000b8', '#ffea00',
|
|
'#00d084', '#3abff8', '#ff5724',
|
|
'#8e24aa', '#3949ab', '#00897b',
|
|
'#d81b60', '#5e35b1', '#039be5',
|
|
'#43a047', '#f4511e', '#6d4c41',
|
|
'#757575', '#546e7a', '#d32f2f'
|
|
],
|
|
library: {
|
|
plugins: {
|
|
legend: { display: false }
|
|
},
|
|
scales: {
|
|
x: {
|
|
grid: { color: 'rgba(0,0,0,0.1)' }
|
|
},
|
|
y: {
|
|
grid: { color: 'rgba(0,0,0,0.1)' }
|
|
}
|
|
}
|
|
}
|
|
) %>
|
|
</div>
|
|
<div class="text-sm opacity-70 text-center mt-2">
|
|
Peak day: <%= peak_day(stat) %> • Quietest week: <%= quietest_week(stat) %>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Top Destinations -->
|
|
<!--div class="card bg-base-100 shadow-xl mb-8">
|
|
<div class="card-body">
|
|
<h2 class="card-title">
|
|
<%= icon 'trophy' %> Top Destinations
|
|
</h2>
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
<div class="flex items-center space-x-4 p-4 bg-base-200 rounded-lg">
|
|
<div class="text-2xl">
|
|
<%= icon 'building' %>
|
|
</div>
|
|
<div class="flex-1">
|
|
<div class="font-bold">Downtown Office</div>
|
|
<div class="text-sm opacity-70">42 visits • 8.5 hrs</div>
|
|
</div>
|
|
<div class="badge badge-primary">1st</div>
|
|
</div>
|
|
<div class="flex items-center space-x-4 p-4 bg-base-200 rounded-lg">
|
|
<div class="text-2xl">
|
|
<%= icon 'house' %>
|
|
</div>
|
|
<div class="flex-1">
|
|
<div class="font-bold">Home Area</div>
|
|
<div class="text-sm opacity-70">31 visits • 156 hrs</div>
|
|
</div>
|
|
<div class="badge badge-secondary">2nd</div>
|
|
</div>
|
|
<div class="flex items-center space-x-4 p-4 bg-base-200 rounded-lg">
|
|
<div class="text-2xl">
|
|
<%= icon 'shopping-cart' %>
|
|
</div>
|
|
<div class="flex-1">
|
|
<div class="font-bold">Shopping District</div>
|
|
<div class="text-sm opacity-70">18 visits • 3.2 hrs</div>
|
|
</div>
|
|
<div class="badge badge-accent">3rd</div>
|
|
</div>
|
|
<div class="flex items-center space-x-4 p-4 bg-base-200 rounded-lg">
|
|
<div class="text-2xl">
|
|
<%= icon 'plane' %>
|
|
</div>
|
|
<div class="flex-1">
|
|
<div class="font-bold">Airport</div>
|
|
<div class="text-sm opacity-70">4 visits • 2.1 hrs</div>
|
|
</div>
|
|
<div class="badge badge-neutral">4th</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div-->
|
|
|
|
<!-- Countries & Cities -->
|
|
<div class="card bg-base-100 shadow-xl mb-8">
|
|
<div class="card-body">
|
|
<h2 class="card-title">
|
|
<%= icon 'globe' %> Countries & Cities
|
|
</h2>
|
|
<div class="space-y-4">
|
|
<% if stat.toponyms.present? %>
|
|
<% max_cities = stat.toponyms.map { |country| country['cities'].length }.max %>
|
|
<% progress_colors = ['progress-primary', 'progress-secondary', 'progress-accent', 'progress-info', 'progress-success', 'progress-warning'] %>
|
|
|
|
<% stat.toponyms.each_with_index do |country, index| %>
|
|
<% cities_count = country['cities'].length %>
|
|
<% progress_value = max_cities > 0 ? (cities_count.to_f / max_cities * 100).round : 0 %>
|
|
<% color_class = progress_colors[index % progress_colors.length] %>
|
|
|
|
<div class="space-y-2">
|
|
<div class="flex justify-between items-center">
|
|
<span class="font-semibold"><%= country['country'] %></span>
|
|
<span class="text-sm">
|
|
<%= pluralize(cities_count, 'city') %>
|
|
<% if progress_value > 0 %>
|
|
(<%= progress_value %>%)
|
|
<% end %>
|
|
</span>
|
|
</div>
|
|
<progress class="progress <%= color_class %> w-full" value="<%= progress_value %>" max="100"></progress>
|
|
</div>
|
|
<% end %>
|
|
<% else %>
|
|
<div class="text-center text-gray-500">
|
|
<p>No location data available for this month</p>
|
|
</div>
|
|
<% end %>
|
|
</div>
|
|
|
|
<div class="divider"></div>
|
|
|
|
<div class="flex flex-wrap gap-2">
|
|
<span class="text-sm font-medium">Cities visited:</span>
|
|
<% stat.toponyms.each do |country| %>
|
|
<% country['cities'].each do |city| %>
|
|
<div class="badge badge-outline"><%= city['city'] %></div>
|
|
<% end %>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Month Highlights -->
|
|
<!--div class="card bg-gradient-to-br from-primary to-secondary text-primary-content shadow-xl">
|
|
<div class="card-body">
|
|
<h2 class="card-title text-white">
|
|
<%= icon 'camera' %> Month Highlights
|
|
</h2>
|
|
|
|
<div class="stats grid grid-cols-2 md:grid-cols-4 gap-4 my-4">
|
|
<div class="stat">
|
|
<div class="stat-title text-white opacity-70">Photos taken</div>
|
|
<div class="stat-value text-white">127</div>
|
|
</div>
|
|
<div class="stat">
|
|
<div class="stat-title text-white opacity-70">Longest trip</div>
|
|
<div class="stat-value text-white">156km</div>
|
|
</div>
|
|
<div class="stat">
|
|
<div class="stat-title text-white opacity-70">New areas</div>
|
|
<div class="stat-value text-white">5</div>
|
|
</div>
|
|
<div class="stat">
|
|
<div class="stat-title text-white opacity-70">Travel time</div>
|
|
<div class="stat-value text-white">28.5h</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 my-4">
|
|
<div class="flex items-center space-x-2">
|
|
<span class="text-white"><%= icon 'flame' %> Walking:</span>
|
|
<span class="font-bold text-white">45km</span>
|
|
</div>
|
|
<div class="flex items-center space-x-2">
|
|
<span class="text-white"><%= icon 'bus' %> Public transport:</span>
|
|
<span class="font-bold text-white">12km</span>
|
|
</div>
|
|
<div class="flex items-center space-x-2">
|
|
<span class="text-white"><%= icon 'car' %> Driving:</span>
|
|
<span class="font-bold text-white">1,190km</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="alert bg-white bg-opacity-10 border-white border-opacity-20">
|
|
<div>
|
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="stroke-info shrink-0 w-6 h-6"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
|
|
<div class="text-white">
|
|
<h3 class="font-bold">
|
|
<%= icon 'lightbulb' %> Monthly Insights
|
|
</h3>
|
|
<p class="text-sm">You explored 3 new neighborhoods this month and visited your favorite coffee shop 15 times - that's every other day! ☕</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div-->
|
|
|
|
<!-- Action Buttons -->
|
|
<div class="flex flex-wrap gap-4 mt-8 justify-center">
|
|
<a href="/stats/<%= year %>" class="btn btn-outline">← Back to <%= year %></a>
|
|
<button class="btn btn-outline" onclick="sharing_modal.showModal()">
|
|
<%= icon 'share' %> Share
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Include Sharing Modal -->
|
|
<%= render 'shared/sharing_modal' %>
|
|
|
|
<!-- Include Place Creation Modal -->
|
|
<%= render 'shared/place_creation_modal' %>
|