diff --git a/src/components/DashboardView.js b/src/components/DashboardView.js index fbd66e1..ed893a5 100644 --- a/src/components/DashboardView.js +++ b/src/components/DashboardView.js @@ -196,6 +196,15 @@ const DashboardView = ({ onCopyLink={onNotificationCopy} copyFeedback={copyFeedback} ntfyPreviewUrl={ntfyPreviewUrl} + location={userLocation} + locationLoading={locationLoading} + locationSaving={locationSaving || geoBusy} + locationError={locationError || geoError} + onDetectLocation={() => { + setGeoError(''); + handleDetectLocation(); + }} + onClearLocation={handleClearLocation} /> )} @@ -275,52 +284,6 @@ const DashboardView = ({ )} -
-
-
-

Standort für Entfernungssortierung

-

- Damit die Monitoring-Liste nach Entfernung sortieren kann, hinterlege hier deinen Standort. -

-
-
- - {userLocation && ( - - )} -
-
-
- {locationLoading ? ( -

Standort wird geladen...

- ) : userLocation ? ( -

- Aktueller Standort: {userLocation.lat.toFixed(4)}, {userLocation.lon.toFixed(4)} ( - {userLocation.updatedAt ? new Date(userLocation.updatedAt).toLocaleString('de-DE') : 'Zeit unbekannt'}) -

- ) : ( -

Kein Standort hinterlegt.

- )} -
- {(locationError || geoError) && ( -

{locationError || geoError}

- )} -
-
diff --git a/src/components/NotificationPanel.js b/src/components/NotificationPanel.js index 6557cfb..3dbcd89 100644 --- a/src/components/NotificationPanel.js +++ b/src/components/NotificationPanel.js @@ -12,7 +12,13 @@ const NotificationPanel = ({ onSendTest, onCopyLink, copyFeedback, - ntfyPreviewUrl + ntfyPreviewUrl, + location, + locationLoading, + locationSaving, + locationError, + onDetectLocation, + onClearLocation }) => { return (
@@ -171,6 +177,50 @@ const NotificationPanel = ({
+
+
+
+

Standort für Entfernungssortierung

+

+ Der Standort wird für die Entfernungskalkulation im Monitoring genutzt. Nur für dich sichtbar. +

+
+
+ + {location && ( + + )} +
+
+
+ {locationLoading ? ( +

Standort wird geladen...

+ ) : location ? ( +

+ Aktueller Standort: {location.lat.toFixed(4)}, {location.lon.toFixed(4)} ( + {location.updatedAt ? new Date(location.updatedAt).toLocaleString('de-DE') : 'Zeit unbekannt'}) +

+ ) : ( +

Kein Standort hinterlegt.

+ )} +
+ {locationError &&

{locationError}

} +
+
+ +
+ ), + cell: ({ getValue }) => { + const value = getValue(); + return ( + + {value ? 'Ja' : 'Nein'} + + ); + }, + filterFn: (row, columnId, value) => { + if (value === undefined) { + return true; + } + const boolValue = value === 'true'; + return row.getValue(columnId) === boolValue; + }, + sortingFn: (rowA, rowB, columnId) => { + const a = rowA.getValue(columnId); + const b = rowB.getValue(columnId); + return Number(b) - Number(a); + } + }), columnHelper.accessor('membership', { header: ({ column }) => (
@@ -397,9 +460,19 @@ const StoreWatchPage = ({ authorizedFetch, knownStores = [], userLocation }) => const data = await response.json(); const normalized = Array.isArray(data.regions) ? data.regions : []; setRegions(normalized); - if (!selectedRegionId && normalized.length > 0) { - setSelectedRegionId(String(normalized[0].id)); - } + setSelectedRegionId((prev) => { + if (!prev) { + return 'all'; + } + if (prev === 'all') { + return prev; + } + const exists = normalized.some((region) => String(region.id) === String(prev)); + if (!exists) { + return normalized.length > 0 ? String(normalized[0].id) : 'all'; + } + return prev; + }); } catch (err) { setError(`Regionen konnten nicht geladen werden: ${err.message}`); } finally { @@ -582,11 +655,10 @@ const StoreWatchPage = ({ authorizedFetch, knownStores = [], userLocation }) =>