feat(analytics): add event tracking to picture, storage, clock, mukke, planta

Track key user actions in remaining web apps:

- Picture: image_generated (with model ID), generation_failed
- Storage: file_uploaded (with size in KB), folder_created
- Clock: timer_started (with timer type)
- Mukke: song_uploaded
- Planta: plant_created

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Till JS 2026-03-22 19:07:06 +01:00
parent cc9679dc9f
commit 45c11a1730
5 changed files with 12 additions and 0 deletions

View file

@ -7,6 +7,7 @@ import { api } from '$lib/api/client';
import { sessionTimersStore } from './session-timers.svelte';
import { authStore } from './auth.svelte';
import type { Timer, CreateTimerInput, UpdateTimerInput } from '@clock/shared';
import { ClockEvents } from '@manacore/shared-utils/analytics';
// State
let timers = $state<Timer[]>([]);
@ -134,6 +135,7 @@ export const timersStore = {
if (response.data) {
timers = timers.map((t) => (t.id === id ? response.data! : t));
ClockEvents.timerStarted(response.data.type as 'pomodoro' | 'stopwatch' | 'countdown');
}
return { success: true, data: response.data };
},

View file

@ -8,6 +8,7 @@ import type {
SortDirection,
} from '@mukke/shared';
import { authStore } from './auth.svelte';
import { trackEvent } from '@manacore/shared-utils/analytics';
interface LibraryState {
songs: Song[];
@ -267,6 +268,7 @@ function createLibraryStore() {
});
state.songs = [uploadData.song, ...state.songs];
trackEvent('song_uploaded');
return uploadData.song;
},

View file

@ -9,6 +9,7 @@
import Button from '../ui/Button.svelte';
import Card from '../ui/Card.svelte';
import { XCircle, Lightning } from '@manacore/shared-icons';
import { PictureEvents } from '@manacore/shared-utils/analytics';
let prompt = $state('');
let negativePrompt = $state('');
@ -86,12 +87,14 @@
// Success - redirect to gallery
generationProgress.set('Complete!');
PictureEvents.imageGenerated(selectedModelId);
setTimeout(() => {
goto('/app/gallery');
}, 1000);
} catch (error) {
console.error('Generation error:', error);
generationError.set(error instanceof Error ? error.message : 'Failed to generate image');
PictureEvents.generationFailed(error instanceof Error ? error.message : 'unknown');
} finally {
isGenerating.set(false);
}

View file

@ -4,6 +4,7 @@
import { fetchApi } from './client';
import type { Plant, PlantWithDetails, CreatePlantDto, UpdatePlantDto } from '@planta/shared';
import { trackEvent } from '@manacore/shared-utils/analytics';
export const plantsApi = {
async getAll(): Promise<Plant[]> {
@ -33,6 +34,7 @@ export const plantsApi = {
console.error('Failed to create plant:', error);
return null;
}
trackEvent('plant_created');
return data;
},

View file

@ -4,6 +4,7 @@
import { filesApi, foldersApi } from '$lib/api/client';
import type { StorageFile, StorageFolder } from '$lib/api/client';
import { trackEvent } from '@manacore/shared-utils/analytics';
let files = $state<StorageFile[]>([]);
let folders = $state<StorageFolder[]>([]);
@ -95,6 +96,7 @@ export const filesStore = {
const result = await filesApi.upload(file, currentFolder?.id);
if (result.data) {
files = [...files, result.data];
trackEvent('file_uploaded', { size: Math.round(file.size / 1024) });
}
return result;
},
@ -103,6 +105,7 @@ export const filesStore = {
const result = await foldersApi.create(name, currentFolder?.id, color);
if (result.data) {
folders = [...folders, result.data];
trackEvent('folder_created');
}
return result;
},