From a4c7fcfc6f364325f29b2d551bb3a1ff7c82a076 Mon Sep 17 00:00:00 2001 From: elpatron Date: Fri, 29 May 2026 19:20:50 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20Plausible-Event=20Photo=20Uploaded=20f?= =?UTF-8?q?=C3=BCr=20Logbuch=20und=20Crew?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Trackt Foto-Uploads in Reisetagen und Crew-Profilen mit context- und role-Properties. Co-authored-by: Cursor --- client/src/components/CrewForm.tsx | 2 ++ client/src/components/PhotoCapture.tsx | 4 +++- client/src/services/analytics.ts | 3 ++- docs/plausible-events.md | 1 + 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/client/src/components/CrewForm.tsx b/client/src/components/CrewForm.tsx index 3d33dc1..d8da019 100644 --- a/client/src/components/CrewForm.tsx +++ b/client/src/components/CrewForm.tsx @@ -455,6 +455,7 @@ export default function CrewForm({ logbookId, readOnly = false, preloadedData }: try { const resized = await resizeImageFile(file) setSkipPhoto(resized) + trackPlausibleEvent(PlausibleEvents.PHOTO_UPLOADED, { context: 'crew', role: 'skipper' }) } catch (err: any) { setSkipPhotoError(err.message || 'Failed to process image') } @@ -662,6 +663,7 @@ export default function CrewForm({ logbookId, readOnly = false, preloadedData }: try { const resized = await resizeImageFile(file) setMemPhoto(resized) + trackPlausibleEvent(PlausibleEvents.PHOTO_UPLOADED, { context: 'crew', role: 'crew' }) } catch (err: any) { setMemPhotoError(err.message || 'Failed to process image') } diff --git a/client/src/components/PhotoCapture.tsx b/client/src/components/PhotoCapture.tsx index 090bed2..d98dcfd 100644 --- a/client/src/components/PhotoCapture.tsx +++ b/client/src/components/PhotoCapture.tsx @@ -5,6 +5,7 @@ import { getActiveMasterKey } from '../services/auth.js' import { getLogbookKey } from '../services/logbookKeys.js' import { encryptJson, decryptJson } from '../services/crypto.js' import { syncLogbook } from '../services/sync.js' +import { PlausibleEvents, trackPlausibleEvent } from '../services/analytics.js' import { useLiveQuery } from 'dexie-react-hooks' import { useDialog } from './ModalDialog.tsx' import { Camera, Trash2 } from 'lucide-react' @@ -159,7 +160,8 @@ export default function PhotoCapture({ entryId, logbookId, readOnly = false, pre setCaption('') if (fileInputRef.current) fileInputRef.current.value = '' - + trackPlausibleEvent(PlausibleEvents.PHOTO_UPLOADED, { context: 'logbook' }) + syncLogbook(logbookId).catch((err) => console.warn('Background sync failed:', err)) } catch (err: any) { console.error('Failed to process image:', err) diff --git a/client/src/services/analytics.ts b/client/src/services/analytics.ts index 4c25fb6..8b2e703 100644 --- a/client/src/services/analytics.ts +++ b/client/src/services/analytics.ts @@ -16,7 +16,8 @@ export const PlausibleEvents = { INVITE_ACCEPTED: 'Invite Accepted', PDF_EXPORTED: 'PDF Exported', CSV_EXPORTED: 'CSV Exported', - CSV_SHARED: 'CSV Shared' + CSV_SHARED: 'CSV Shared', + PHOTO_UPLOADED: 'Photo Uploaded' } as const export type PlausibleEventName = (typeof PlausibleEvents)[keyof typeof PlausibleEvents] diff --git a/docs/plausible-events.md b/docs/plausible-events.md index d082dc4..bb71708 100644 --- a/docs/plausible-events.md +++ b/docs/plausible-events.md @@ -31,6 +31,7 @@ Kapteins Daagbok nutzt [Plausible Analytics](https://plausible.io/) mit dem Scri | PDF Exported | PDF-Export eines Reisetags (`LogEntryEditor.tsx`, `LogEntriesList.tsx`) | `scope`: `entry` | | CSV Exported | CSV-Download aus der Eintragsliste (`LogEntriesList.tsx`) | — | | CSV Shared | CSV über Web Share API geteilt (`LogEntriesList.tsx`) | — | +| Photo Uploaded | Foto hochgeladen (`PhotoCapture.tsx`, `CrewForm.tsx`) | `context`: `logbook` \| `crew`, bei Crew zusätzlich `role`: `skipper` \| `crew` | ## Bewusst nicht getrackt