diff --git a/src/components/dashboard/Dashboard.tsx b/src/components/dashboard/Dashboard.tsx index 4838e65..8934f4d 100644 --- a/src/components/dashboard/Dashboard.tsx +++ b/src/components/dashboard/Dashboard.tsx @@ -157,6 +157,7 @@ export default function Dashboard({ cloud_storage: 0, gaming: 0, social_media: 0, + music_streaming: 0, }; footprints diff --git a/src/components/demo/ComparisonDemo.tsx b/src/components/demo/ComparisonDemo.tsx index ac85331..c700458 100644 --- a/src/components/demo/ComparisonDemo.tsx +++ b/src/components/demo/ComparisonDemo.tsx @@ -17,6 +17,7 @@ const mockDashboardData: DashboardData = { cloud_storage: 20, gaming: 30, social_media: 10, + music_streaming: 30, }, trend: [ { date: "Mon", co2: 320 }, diff --git a/src/components/forms/ActivityForm.tsx b/src/components/forms/ActivityForm.tsx index 953d4b9..357ed0d 100644 --- a/src/components/forms/ActivityForm.tsx +++ b/src/components/forms/ActivityForm.tsx @@ -27,6 +27,7 @@ export default function ActivityForm({ onSubmit, initialValues }: ActivityFormPr cloudStorageGB: initialValues?.cloudStorageGB || 0, gamingHours: initialValues?.gamingHours || 0, socialMediaHours: initialValues?.socialMediaHours || 0, + musicStreamingHours: initialValues?.musicStreamingHours || 0, }); const [isSubmitting, setIsSubmitting] = useState(false); @@ -96,6 +97,7 @@ export default function ActivityForm({ onSubmit, initialValues }: ActivityFormPr cloudStorageGB: 0, gamingHours: 0, socialMediaHours: 0, + musicStreamingHours: 0, }); setErrors({}); setTouched({}); @@ -165,6 +167,14 @@ export default function ActivityForm({ onSubmit, initialValues }: ActivityFormPr step: 0.5, icon: '📱', }, + { + key: 'musicStreamingHours' as keyof ActivityInput, + label: ACTIVITY_LABELS.music_streaming, + description: ACTIVITY_DESCRIPTIONS.music_streaming, + max: 24, + step: 0.5, + icon: '🎵', + }, ]; const hasActivity = Object.values(activities).some((v) => v > 0); return ( diff --git a/src/constants/co2Factors.ts b/src/constants/co2Factors.ts index 61dbfb4..45a8368 100644 --- a/src/constants/co2Factors.ts +++ b/src/constants/co2Factors.ts @@ -9,6 +9,7 @@ export const CO2_FACTORS: Record = { cloud_storage: 0.5, // grams per GB per day gaming: 60, // grams per hour social_media: 12, // grams per hour + music_streaming: 8, }; // Real-world equivalents for context @@ -44,9 +45,10 @@ export const ACTIVITY_LABELS: Record = { cloud_storage: ACTIVITY_TYPES.cloud_storage.label, gaming: ACTIVITY_TYPES.gaming.label, social_media: ACTIVITY_TYPES.social_media.label, + music_streaming: ACTIVITY_TYPES.music_streaming.label, }; -// Activity descriptions - derived from ACTIVITY_TYPES (concise, under 10 words each) +// Activity descriptions export const ACTIVITY_DESCRIPTIONS: Record = { emails: ACTIVITY_TYPES.emails.description, streaming: ACTIVITY_TYPES.streaming.description, @@ -55,4 +57,5 @@ export const ACTIVITY_DESCRIPTIONS: Record = { cloud_storage: ACTIVITY_TYPES.cloud_storage.description, gaming: ACTIVITY_TYPES.gaming.description, social_media: ACTIVITY_TYPES.social_media.description, + music_streaming: ACTIVITY_TYPES.music_streaming.description, }; \ No newline at end of file diff --git a/src/constants/quickActions.ts b/src/constants/quickActions.ts index 5a75bc8..ebdcbed 100644 --- a/src/constants/quickActions.ts +++ b/src/constants/quickActions.ts @@ -18,6 +18,7 @@ export const defaultActivities: ActivityInput = { cloudStorageGB: 0, gamingHours: 0, socialMediaHours: 0, + musicStreamingHours:0, }; // Define all your presets here, matching the GitHub issue @@ -58,4 +59,11 @@ export const QUICK_ACTIONS: QuickAction[] = [ // Note: Mapping 'Browsing' to 'socialMediaHours' as it's the closest available field activities: { socialMediaHours: 1 }, }, + { + id: "music_1h", + icon: "🎵", + label: "1 Hr Music Streaming", + toastMessage: "✅ Added 1 hour music streaming (XXg CO2)", + activities: { musicStreamingHours: 1 }, + }, ]; \ No newline at end of file diff --git a/src/lib/calculations/carbonFootprint.ts b/src/lib/calculations/carbonFootprint.ts index 9870487..7aa7529 100644 --- a/src/lib/calculations/carbonFootprint.ts +++ b/src/lib/calculations/carbonFootprint.ts @@ -16,6 +16,7 @@ export const calculateCarbonFootprint = (activities: ActivityInput): Calculation cloud_storage: activities.cloudStorageGB * CO2_FACTORS.cloud_storage, gaming: activities.gamingHours * CO2_FACTORS.gaming, social_media: activities.socialMediaHours * CO2_FACTORS.social_media, + music_streaming: activities.musicStreamingHours * CO2_FACTORS.music_streaming, }; const totalCO2 = Object.values(breakdown).reduce((sum, value) => sum + value, 0); @@ -124,6 +125,10 @@ export const suggestReductions = (breakdown: Record): Arra suggestion = 'Set time limits for social media browsing'; potentialSaving = emissions * 0.3; break; + case 'music_streaming': + suggestion = 'Download music for offline listening or reduce streaming quality'; + potentialSaving = emissions * 0.25; + break; } suggestions.push({ diff --git a/src/types/index.ts b/src/types/index.ts index ecb7890..24cdea7 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -15,7 +15,8 @@ export type ActivityType = | "video_calls" | "cloud_storage" | "gaming" - | "social_media"; + | "social_media" + | "music_streaming"; export interface ActivityTypeInfo { id: ActivityType; @@ -27,38 +28,43 @@ export const ACTIVITY_TYPES: Record = { emails: { id: "emails", label: "Email", - description: "Sending and receiving emails" + description: "Sending and receiving emails", }, video_calls: { id: "video_calls", label: "Video Calls", - description: "Zoom, Teams, Google Meet calls" + description: "Zoom, Teams, Google Meet calls", }, streaming: { id: "streaming", label: "Streaming", - description: "Netflix, YouTube, Spotify" + description: "Netflix, YouTube, Spotify", }, coding: { id: "coding", label: "Coding", - description: "Using IDEs, compiling code" + description: "Using IDEs, compiling code", }, cloud_storage: { id: "cloud_storage", label: "Cloud Storage", - description: "Google Drive, Dropbox, iCloud" + description: "Google Drive, Dropbox, iCloud", }, gaming: { id: "gaming", label: "Gaming", - description: "Online gaming and downloads" + description: "Online gaming and downloads", }, social_media: { id: "social_media", label: "Social Media", - description: "Facebook, Instagram, Twitter" - } + description: "Facebook, Instagram, Twitter", + }, + music_streaming: { + id: "music_streaming", + label: "Music Streaming", + description: "Hours spent listening to Spotify, Apple Music, or YouTube Music", + }, }; export interface ActivityInput { @@ -69,6 +75,7 @@ export interface ActivityInput { cloudStorageGB: number; gamingHours: number; socialMediaHours: number; + musicStreamingHours: number; } export interface CarbonFootprint {