From b1e17be7fd3f016c63f822ab893a43a4924fdada Mon Sep 17 00:00:00 2001 From: elpatron Date: Sat, 6 Jun 2026 11:51:07 +0200 Subject: [PATCH] feat(analytics): add Plausible custom event VOICE_MEMO_TRANSCRIBED with status and mode properties --- client/src/components/EventRemarksCell.tsx | 9 +++++++++ client/src/components/LiveLogView.tsx | 10 +++++++++- client/src/services/analytics.ts | 1 + docs/plausible-events.md | 2 ++ 4 files changed, 21 insertions(+), 1 deletion(-) diff --git a/client/src/components/EventRemarksCell.tsx b/client/src/components/EventRemarksCell.tsx index dfa83d8..7b58d28 100644 --- a/client/src/components/EventRemarksCell.tsx +++ b/client/src/components/EventRemarksCell.tsx @@ -7,6 +7,7 @@ import { formatEventSummary } from '../utils/formatEventSummary.js' import VoiceMemoPlayer, { type PreloadedVoiceMemo } from './VoiceMemoPlayer.tsx' import { useDialog } from './ModalDialog.tsx' import { updateVoiceMemoTranscript } from '../services/voiceAttachments.js' +import { PlausibleEvents, trackPlausibleEvent } from '../services/analytics.js' interface EventRemarksCellProps { event: LogEventPayload @@ -66,9 +67,17 @@ export default function EventRemarksCell({ throw new Error('Transcription returned empty text') } await updateVoiceMemoTranscript(logbookId, voiceId, text) + trackPlausibleEvent(PlausibleEvents.VOICE_MEMO_TRANSCRIBED, { + status: 'success', + mode: 'manual' + }) } catch (err) { clearTimeout(timeoutId) console.error('[EventRemarksCell] Transcription failed:', err) + trackPlausibleEvent(PlausibleEvents.VOICE_MEMO_TRANSCRIBED, { + status: 'failed', + mode: 'manual' + }) void showAlert(t('logs.live_voice_transcribe_failed'), t('logs.live_voice_btn')) } finally { setTranscribing(false) diff --git a/client/src/components/LiveLogView.tsx b/client/src/components/LiveLogView.tsx index 3a8624a..4a17d2a 100644 --- a/client/src/components/LiveLogView.tsx +++ b/client/src/components/LiveLogView.tsx @@ -885,9 +885,17 @@ export default function LiveLogView({ setVoiceCaption('') showUndo('voice') trackPlausibleEvent(PlausibleEvents.LIVE_LOG_EVENT_LOGGED, { action: 'voice' }) - if (transcriptionError) { + trackPlausibleEvent(PlausibleEvents.VOICE_MEMO_TRANSCRIBED, { + status: 'failed', + mode: 'auto' + }) void showAlert(t('logs.live_voice_transcribe_failed'), t('logs.live_voice_btn')) + } else { + trackPlausibleEvent(PlausibleEvents.VOICE_MEMO_TRANSCRIBED, { + status: 'success', + mode: 'auto' + }) } } catch (err: unknown) { console.error('Live log voice save failed:', err) diff --git a/client/src/services/analytics.ts b/client/src/services/analytics.ts index a85bfd1..9ad6fa1 100644 --- a/client/src/services/analytics.ts +++ b/client/src/services/analytics.ts @@ -42,6 +42,7 @@ export const PlausibleEvents = { LIVE_LOG_OPENED: 'Live Log Opened', LIVE_LOG_EVENT_LOGGED: 'Live Log Event Logged', VOICE_MEMO_UPLOADED: 'Voice Memo Uploaded', + VOICE_MEMO_TRANSCRIBED: 'Voice Memo Transcribed', OWM_WEATHER_FETCHED: 'OWM Weather Fetched', AI_SUMMARY_GENERATED: 'AI Summary Generated', PWA_BOOT_WATCHDOG_SOFT: 'PWA Boot Watchdog Soft', diff --git a/docs/plausible-events.md b/docs/plausible-events.md index b6e8336..415d49d 100644 --- a/docs/plausible-events.md +++ b/docs/plausible-events.md @@ -47,6 +47,7 @@ Das Script wird über `plausible-bootstrap.js` geladen; `data-domain` ist der ak | CSV Shared | CSV über Web Share API geteilt (`LogEntriesList.tsx`) | — | | Photo Uploaded | Foto hochgeladen (`photoAttachments.ts`, `PhotoCapture.tsx`, `CrewForm.tsx`) | `context`: `logbook` \| `live_log` \| `crew`, bei Crew zusätzlich `role`: `skipper` \| `crew` | | Voice Memo Uploaded | Sprachnotiz gespeichert (`voiceAttachments.ts`) | `context`: `logbook` \| `live_log` | +| Voice Memo Transcribed | Sprachmemo transkribiert (`LiveLogView.tsx`, `EventRemarksCell.tsx`) | `status`: `success` \| `failed`, `mode`: `auto` (beim Speichern) \| `manual` (nachträglich) | | OWM Weather Fetched | Erfolgreicher OpenWeatherMap-API-Abruf (`weather.ts`, zentral nach HTTP 200) | `source`: siehe [OWM-Quellen](#owm-quellen) | | AI Summary Generated | Erfolgreiche KI-Zusammenfassung eines Reisetags (`aiSummary.ts`) | — | | Backup Exported | Backup-Datei heruntergeladen (`LogbookBackupPanel.tsx`, v2 ZIP) | `entries`, `photos`, `voiceMemos`, `bytes` (Anzahlen/Größe, keine Inhalte) | @@ -161,6 +162,7 @@ trackPlausibleEvent(PlausibleEvents.LANGUAGE_CHANGED, { from: 'de', to: 'da' }) trackPlausibleEvent(PlausibleEvents.LIVE_LOG_EVENT_LOGGED, { action: 'course' }) trackPlausibleEvent(PlausibleEvents.PHOTO_UPLOADED, { context: 'live_log' }) trackPlausibleEvent(PlausibleEvents.VOICE_MEMO_UPLOADED, { context: 'live_log' }) +trackPlausibleEvent(PlausibleEvents.VOICE_MEMO_TRANSCRIBED, { status: 'success', mode: 'auto' }) trackPlausibleEvent(PlausibleEvents.OWM_WEATHER_FETCHED, { source: 'live_log' }) trackPlausibleEvent(PlausibleEvents.NMEA_UPLOADED, { lines: 1200, candidates: 8, duplicate: false, has_position: true }) trackPlausibleEvent(PlausibleEvents.NMEA_IMPORTED, { mode: 'both', events: 6, track: true })