mirror of
https://github.com/Freika/dawarich.git
synced 2026-01-11 09:41:40 -05:00
Show QR code by default and use map tiles based on self-hosted setting
This commit is contained in:
parent
e583a8fb52
commit
cc1fecfd22
9 changed files with 90 additions and 25 deletions
1
app/assets/svg/icons/lucide/outline/flower.svg
Normal file
1
app/assets/svg/icons/lucide/outline/flower.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-flower-icon lucide-flower"><circle cx="12" cy="12" r="3"/><path d="M12 16.5A4.5 4.5 0 1 1 7.5 12 4.5 4.5 0 1 1 12 7.5a4.5 4.5 0 1 1 4.5 4.5 4.5 4.5 0 1 1-4.5 4.5"/><path d="M12 7.5V9"/><path d="M7.5 12H9"/><path d="M16.5 12H15"/><path d="M12 16.5V15"/><path d="m8 8 1.88 1.88"/><path d="M14.12 9.88 16 8"/><path d="m8 16 1.88-1.88"/><path d="M14.12 14.12 16 16"/></svg>
|
||||
|
After Width: | Height: | Size: 572 B |
1
app/assets/svg/icons/lucide/outline/leaf.svg
Normal file
1
app/assets/svg/icons/lucide/outline/leaf.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-leaf-icon lucide-leaf"><path d="M11 20A7 7 0 0 1 9.8 6.1C15.5 5 17 4.48 19 2c1 2 2 4.18 2 8 0 5.5-4.78 10-10 10Z"/><path d="M2 21c0-3 1.85-5.36 5.08-6C9.5 14.52 12 13 13 12"/></svg>
|
||||
|
After Width: | Height: | Size: 384 B |
1
app/assets/svg/icons/lucide/outline/tree-palm.svg
Normal file
1
app/assets/svg/icons/lucide/outline/tree-palm.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-tree-palm-icon lucide-tree-palm"><path d="M13 8c0-2.76-2.46-5-5.5-5S2 5.24 2 8h2l1-1 1 1h4"/><path d="M13 7.14A5.82 5.82 0 0 1 16.5 6c3.04 0 5.5 2.24 5.5 5h-3l-1-1-1 1h-3"/><path d="M5.89 9.71c-2.15 2.15-2.3 5.47-.35 7.43l4.24-4.25.7-.7.71-.71 2.12-2.12c-1.95-1.96-5.27-1.8-7.42.35"/><path d="M11 15.5c.5 2.5-.17 4.5-1 6.5h4c2-5.5-.5-12-1-14"/></svg>
|
||||
|
After Width: | Height: | Size: 553 B |
|
|
@ -3,6 +3,8 @@
|
|||
class ApplicationController < ActionController::Base
|
||||
include Pundit::Authorization
|
||||
|
||||
rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
|
||||
|
||||
before_action :unread_notifications, :set_self_hosted_status
|
||||
|
||||
protected
|
||||
|
|
@ -16,13 +18,13 @@ class ApplicationController < ActionController::Base
|
|||
def authenticate_admin!
|
||||
return if current_user&.admin?
|
||||
|
||||
redirect_to root_path, notice: 'You are not authorized to perform this action.', status: :see_other
|
||||
user_not_authorized
|
||||
end
|
||||
|
||||
def authenticate_self_hosted!
|
||||
return if DawarichSettings.self_hosted?
|
||||
|
||||
redirect_to root_path, notice: 'You are not authorized to perform this action.', status: :see_other
|
||||
user_not_authorized
|
||||
end
|
||||
|
||||
def authenticate_active_user!
|
||||
|
|
@ -34,7 +36,7 @@ class ApplicationController < ActionController::Base
|
|||
def authenticate_non_self_hosted!
|
||||
return unless DawarichSettings.self_hosted?
|
||||
|
||||
redirect_to root_path, notice: 'You are not authorized to perform this action.', status: :see_other
|
||||
user_not_authorized
|
||||
end
|
||||
|
||||
private
|
||||
|
|
@ -42,4 +44,10 @@ class ApplicationController < ActionController::Base
|
|||
def set_self_hosted_status
|
||||
@self_hosted = DawarichSettings.self_hosted?
|
||||
end
|
||||
|
||||
def user_not_authorized
|
||||
redirect_back_or_to root_path,
|
||||
alert: 'You are not authorized to perform this action.',
|
||||
status: :see_other
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,18 +1,22 @@
|
|||
import { Controller } from "@hotwired/stimulus";
|
||||
import L from "leaflet";
|
||||
import { createHexagonGrid } from "../maps/hexagon_grid";
|
||||
import { createAllMapLayers } from "../maps/layers";
|
||||
import BaseController from "./base_controller";
|
||||
|
||||
export default class extends Controller {
|
||||
export default class extends BaseController {
|
||||
static targets = ["container"];
|
||||
static values = {
|
||||
year: Number,
|
||||
month: Number,
|
||||
uuid: String,
|
||||
dataBounds: Object
|
||||
dataBounds: Object,
|
||||
selfHosted: String
|
||||
};
|
||||
|
||||
connect() {
|
||||
super.connect();
|
||||
console.log('🏁 Controller connected - loading overlay should be visible');
|
||||
this.selfHosted = this.selfHostedValue || 'false';
|
||||
this.initializeMap();
|
||||
this.loadHexagons();
|
||||
}
|
||||
|
|
@ -37,14 +41,36 @@ export default class extends Controller {
|
|||
keyboard: false
|
||||
});
|
||||
|
||||
// Add tile layer
|
||||
// Add dynamic tile layer based on self-hosted setting
|
||||
this.addMapLayers();
|
||||
|
||||
// Default view
|
||||
this.map.setView([40.0, -100.0], 4);
|
||||
}
|
||||
|
||||
addMapLayers() {
|
||||
try {
|
||||
// Use appropriate default layer based on self-hosted mode
|
||||
const selectedLayerName = this.selfHosted === "true" ? "OpenStreetMap" : "Light";
|
||||
const maps = createAllMapLayers(this.map, selectedLayerName, this.selfHosted);
|
||||
|
||||
// If no layers were created, fall back to OSM
|
||||
if (Object.keys(maps).length === 0) {
|
||||
console.warn('No map layers available, falling back to OSM');
|
||||
this.addFallbackOSMLayer();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error creating map layers:', error);
|
||||
console.log('Falling back to OSM tile layer');
|
||||
this.addFallbackOSMLayer();
|
||||
}
|
||||
}
|
||||
|
||||
addFallbackOSMLayer() {
|
||||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
attribution: '© OpenStreetMap contributors',
|
||||
maxZoom: 15
|
||||
}).addTo(this.map);
|
||||
|
||||
// Default view
|
||||
this.map.setView([40.0, -100.0], 4);
|
||||
}
|
||||
|
||||
async loadHexagons() {
|
||||
|
|
|
|||
|
|
@ -1,17 +1,20 @@
|
|||
import { Controller } from "@hotwired/stimulus";
|
||||
import L from "leaflet";
|
||||
import "leaflet.heat";
|
||||
import { createAllMapLayers } from "../maps/layers";
|
||||
import BaseController from "./base_controller";
|
||||
|
||||
export default class extends Controller {
|
||||
export default class extends BaseController {
|
||||
static targets = ["map", "loading", "heatmapBtn", "pointsBtn"];
|
||||
|
||||
connect() {
|
||||
super.connect();
|
||||
console.log("StatPage controller connected");
|
||||
|
||||
// Get data attributes from the element (will be passed from the view)
|
||||
this.year = parseInt(this.element.dataset.year || new Date().getFullYear());
|
||||
this.month = parseInt(this.element.dataset.month || new Date().getMonth() + 1);
|
||||
this.apiKey = this.element.dataset.apiKey;
|
||||
this.selfHosted = this.element.dataset.selfHosted || this.selfHostedValue;
|
||||
|
||||
console.log(`Loading data for ${this.month}/${this.year} with API key: ${this.apiKey ? 'present' : 'missing'}`);
|
||||
|
||||
|
|
@ -46,11 +49,8 @@ export default class extends Controller {
|
|||
touchZoom: true
|
||||
}).setView([52.520008, 13.404954], 10); // Default to Berlin
|
||||
|
||||
// Add tile layer
|
||||
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
maxZoom: 19,
|
||||
attribution: '© OpenStreetMap contributors'
|
||||
}).addTo(this.map);
|
||||
// Add dynamic tile layer based on self-hosted setting
|
||||
this.addMapLayers();
|
||||
|
||||
// Add small scale control
|
||||
L.control.scale({
|
||||
|
|
@ -259,4 +259,29 @@ export default class extends Controller {
|
|||
this.loadingTarget.style.display = 'flex';
|
||||
}
|
||||
}
|
||||
|
||||
addMapLayers() {
|
||||
try {
|
||||
// Use appropriate default layer based on self-hosted mode
|
||||
const selectedLayerName = this.selfHosted === "true" ? "OpenStreetMap" : "Light";
|
||||
const maps = createAllMapLayers(this.map, selectedLayerName, this.selfHosted);
|
||||
|
||||
// If no layers were created, fall back to OSM
|
||||
if (Object.keys(maps).length === 0) {
|
||||
console.warn('No map layers available, falling back to OSM');
|
||||
this.addFallbackOSMLayer();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error creating map layers:', error);
|
||||
console.log('Falling back to OSM tile layer');
|
||||
this.addFallbackOSMLayer();
|
||||
}
|
||||
}
|
||||
|
||||
addFallbackOSMLayer() {
|
||||
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
maxZoom: 19,
|
||||
attribution: '© OpenStreetMap contributors'
|
||||
}).addTo(this.map);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,12 +2,10 @@
|
|||
<p class='py-2'>Use this API key to authenticate your requests.</p>
|
||||
<code><%= current_user.api_key %></code>
|
||||
|
||||
<% if ENV['QR_CODE_ENABLED'] == 'true' %>
|
||||
<p class='py-2'>
|
||||
Or you can scan it in your Dawarich iOS app:
|
||||
<%= api_key_qr_code(current_user) %>
|
||||
</p>
|
||||
<% end %>
|
||||
<p class='py-2'>
|
||||
Or you can scan it in your Dawarich iOS app:
|
||||
<%= api_key_qr_code(current_user) %>
|
||||
</p>
|
||||
|
||||
<p class='py-2'>
|
||||
<p>Docs: <%= link_to "API documentation", '/api-docs', class: 'underline hover:no-underline' %></p>
|
||||
|
|
|
|||
|
|
@ -55,7 +55,8 @@
|
|||
data-controller="stat-page"
|
||||
data-api-key="<%= current_user.api_key %>"
|
||||
data-year="<%= year %>"
|
||||
data-month="<%= month %>">
|
||||
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">
|
||||
|
|
|
|||
|
|
@ -19,6 +19,9 @@
|
|||
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
|
||||
integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
|
||||
crossorigin=""></script>
|
||||
|
||||
<!-- ProtomapsL for vector tiles -->
|
||||
<script src="https://unpkg.com/protomaps-leaflet@5.0.0/dist/protomaps-leaflet.js"></script>
|
||||
</head>
|
||||
<body data-theme="dark">
|
||||
<div class="min-h-screen bg-base-100 mx-auto">
|
||||
|
|
@ -74,7 +77,8 @@
|
|||
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 %>"></div>
|
||||
data-public-stat-map-data-bounds-value="<%= @data_bounds.to_json if @data_bounds %>"
|
||||
data-public-stat-map-self-hosted-value="<%= @self_hosted %>"></div>
|
||||
|
||||
<!-- Loading overlay -->
|
||||
<div id="map-loading" class="absolute inset-0 bg-base-200 bg-opacity-80 flex items-center justify-center z-50">
|
||||
|
|
|
|||
Loading…
Reference in a new issue