mirror of
https://github.com/Freika/dawarich.git
synced 2026-01-09 08:47:11 -05:00
* fix: move foreman to global gems to fix startup crash (#1971) * Update exporting code to stream points data to file in batches to red… (#1980) * Update exporting code to stream points data to file in batches to reduce memory usage * Update changelog * Update changelog * Feature/maplibre frontend (#1953) * Add a plan to use MapLibre GL JS for the frontend map rendering, replacing Leaflet * Implement phase 1 * Phases 1-3 + part of 4 * Fix e2e tests * Phase 6 * Implement fog of war * Phase 7 * Next step: fix specs, phase 7 done * Use our own map tiles * Extract v2 map logic to separate manager classes * Update settings panel on v2 map * Update v2 e2e tests structure * Reimplement location search in maps v2 * Update speed routes * Implement visits and places creation in v2 * Fix last failing test * Implement visits merging * Fix a routes e2e test and simplify the routes layer styling. * Extract js to modules from maps_v2_controller.js * Implement area creation * Fix spec problem * Fix some e2e tests * Implement live mode in v2 map * Update icons and panel * Extract some styles * Remove unused file * Start adding dark theme to popups on MapLibre maps * Make popups respect dark theme * Move v2 maps to maplibre namespace * Update v2 references to maplibre * Put place, area and visit info into side panel * Update API to use safe settings config method * Fix specs * Fix method name to config in SafeSettings and update usages accordingly * Add missing public files * Add handling for real time points * Fix remembering enabled/disabled layers of the v2 map * Fix lots of e2e tests * Add settings to select map version * Use maps/v2 as main path for MapLibre maps * Update routing * Update live mode * Update maplibre controller * Update changelog * Remove some console.log statements * Pull only necessary data for map v2 points * Feature/raw data archive (#2009) * 0.36.2 (#2007) * fix: move foreman to global gems to fix startup crash (#1971) * Update exporting code to stream points data to file in batches to red… (#1980) * Update exporting code to stream points data to file in batches to reduce memory usage * Update changelog * Update changelog * Feature/maplibre frontend (#1953) * Add a plan to use MapLibre GL JS for the frontend map rendering, replacing Leaflet * Implement phase 1 * Phases 1-3 + part of 4 * Fix e2e tests * Phase 6 * Implement fog of war * Phase 7 * Next step: fix specs, phase 7 done * Use our own map tiles * Extract v2 map logic to separate manager classes * Update settings panel on v2 map * Update v2 e2e tests structure * Reimplement location search in maps v2 * Update speed routes * Implement visits and places creation in v2 * Fix last failing test * Implement visits merging * Fix a routes e2e test and simplify the routes layer styling. * Extract js to modules from maps_v2_controller.js * Implement area creation * Fix spec problem * Fix some e2e tests * Implement live mode in v2 map * Update icons and panel * Extract some styles * Remove unused file * Start adding dark theme to popups on MapLibre maps * Make popups respect dark theme * Move v2 maps to maplibre namespace * Update v2 references to maplibre * Put place, area and visit info into side panel * Update API to use safe settings config method * Fix specs * Fix method name to config in SafeSettings and update usages accordingly * Add missing public files * Add handling for real time points * Fix remembering enabled/disabled layers of the v2 map * Fix lots of e2e tests * Add settings to select map version * Use maps/v2 as main path for MapLibre maps * Update routing * Update live mode * Update maplibre controller * Update changelog * Remove some console.log statements --------- Co-authored-by: Robin Tuszik <mail@robin.gg> * Remove esbuild scripts from package.json * Remove sideEffects field from package.json * Raw data archivation * Add tests * Fix tests * Fix tests * Update ExceptionReporter * Add schedule to run raw data archival job monthly * Change file structure for raw data archival feature * Update changelog and version for raw data archival feature --------- Co-authored-by: Robin Tuszik <mail@robin.gg> * Set raw_data to an empty hash instead of nil when archiving * Fix storage configuration and file extraction * Consider MIN_MINUTES_SPENT_IN_CITY during stats calculation (#2018) * Consider MIN_MINUTES_SPENT_IN_CITY during stats calculation * Remove raw data from visited cities api endpoint * Use user timezone to show dates on maps (#2020) * Fix/pre epoch time (#2019) * Use user timezone to show dates on maps * Limit timestamps to valid range to prevent database errors when users enter pre-epoch dates. * Limit timestamps to valid range to prevent database errors when users enter pre-epoch dates. * Fix tests failing due to new index on stats table * Fix failing specs * Update redis client configuration to support unix socket connection * Update changelog * Fix kml kmz import issues (#2023) * Fix kml kmz import issues * Refactor KML importer to improve readability and maintainability * Implement moving points in map v2 and fix route rendering logic to ma… (#2027) * Implement moving points in map v2 and fix route rendering logic to match map v1. * Fix route spec * fix(maplibre): update date format to ISO 8601 (#2029) * Add verification step to raw data archival process (#2028) * Add verification step to raw data archival process * Add actual verification of raw data archives after creation, and only clear raw_data for verified archives. * Fix failing specs * Eliminate zip-bomb risk * Fix potential memory leak in js * Return .keep files * Use Toast instead of alert for notifications * Add help section to navbar dropdown * Update changelog * Remove raw_data_archival_job * Ensure file is being closed properly after reading in Archivable concern --------- Co-authored-by: Robin Tuszik <mail@robin.gg>
164 lines
6 KiB
Text
164 lines
6 KiB
Text
<div class="container mx-auto px-4 py-8">
|
|
<!-- 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 py-8">
|
|
<div class="max-w-lg">
|
|
<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="pt-6 pb-2">Monthly Digest</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="stats shadow mx-auto mb-8 w-full">
|
|
<div class="stat place-items-center text-center">
|
|
<div class="stat-title">Distance traveled</div>
|
|
<div class="stat-value"><%= distance_traveled(@user, @stat) %></div>
|
|
<div class="stat-desc">Total distance for this month</div>
|
|
</div>
|
|
|
|
<div class="stat place-items-center text-center">
|
|
<div class="stat-title">Active days</div>
|
|
<div class="stat-value text-secondary">
|
|
<%= active_days(@stat) %>
|
|
</div>
|
|
<div class="stat-desc text-secondary">
|
|
Days with tracked activity
|
|
</div>
|
|
</div>
|
|
|
|
<div class="stat place-items-center text-center">
|
|
<div class="stat-title">Countries visited</div>
|
|
<div class="stat-value">
|
|
<%= countries_visited(@stat) %>
|
|
</div>
|
|
<div class="stat-desc">
|
|
Different countries
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Map Summary - Hexagon View -->
|
|
<div class="card bg-base-100 shadow-xl mb-8">
|
|
<div class="card-body p-0">
|
|
<!-- Map Controls -->
|
|
<div class="p-4 border-b border-base-300 bg-base-50">
|
|
<div class="flex justify-between items-center">
|
|
<div class="flex items-center gap-4">
|
|
<h3 class="font-semibold text-lg flex items-center gap-2">
|
|
<%= icon 'map' %> Location Hexagons
|
|
</h3>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Hexagon Map Container -->
|
|
<div class="w-full h-96 border border-base-300 relative overflow-hidden">
|
|
<div id="public-monthly-stats-map" class="w-full h-full"
|
|
data-controller="public-stat-map"
|
|
data-public-stat-map-year-value="<%= @year %>"
|
|
data-public-stat-map-month-value="<%= @month %>"
|
|
data-public-stat-map-uuid-value="<%= @stat.sharing_uuid %>"
|
|
data-public-stat-map-data-bounds-value="<%= @data_bounds.to_json if @data_bounds %>"
|
|
data-public-stat-map-hexagons-available-value="<%= @hexagons_available.to_s %>"
|
|
data-public-stat-map-self-hosted-value="<%= @self_hosted %>"
|
|
data-public-stat-map-timezone-value="<%= @user.timezone %>"></div>
|
|
|
|
<!-- Loading overlay -->
|
|
<div id="map-loading" class="absolute inset-0 bg-base-200 bg-opacity-80 flex items-center justify-center z-50">
|
|
<div class="text-center">
|
|
<span class="loading loading-spinner loading-lg text-primary"></span>
|
|
<p class="text-sm mt-2 text-base-content">Loading hexagons...</p>
|
|
</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 'trending-up' %> 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, 'km').round]
|
|
},
|
|
height: '200px',
|
|
suffix: " km",
|
|
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>
|
|
|
|
<!-- Countries & Cities - General Info Only -->
|
|
<div class="card bg-base-100 shadow-xl mb-8">
|
|
<div class="card-body">
|
|
<h2 class="card-title">
|
|
<%= icon 'earth' %> Countries & Cities
|
|
</h2>
|
|
<div class="space-y-4">
|
|
<% @stat.toponyms.each_with_index do |country, index| %>
|
|
<div class="space-y-2">
|
|
<div class="flex justify-between items-center">
|
|
<span class="font-semibold"><%= country['country'] %></span>
|
|
<span class="text-sm"><%= country['cities'].length %> cities</span>
|
|
</div>
|
|
<progress class="progress progress-primary w-full" value="<%= 100 - (index * 20) %>" max="100"></progress>
|
|
</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'].first(5).each do |city| %>
|
|
<div class="badge badge-outline"><%= city['city'] %></div>
|
|
<% end %>
|
|
<% if country['cities'].length > 5 %>
|
|
<div class="badge badge-ghost">+<%= country['cities'].length - 5 %> more</div>
|
|
<% end %>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Footer -->
|
|
<div class="text-center py-8">
|
|
<div class="text-sm text-gray-500">
|
|
Powered by <a href="https://dawarich.app" class="link link-primary" target="_blank">Dawarich</a>, your personal memories mapper.
|
|
</div>
|
|
</div>
|
|
</div>
|