import React, { useState, useEffect } from 'react'; import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer, BarChart, Bar } from 'recharts'; import { Card, CardHeader, CardContent } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { Bluetooth, Activity, Goal, Settings, Download, HelpCircle, RefreshCw, User } from 'lucide-react'; import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui/dialog'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; const generateMockData = () => { return [...Array(20)].map((_, i) => ({ timestamp: new Date(Date.now() - (19 - i) * 60000).toISOString(), lapTime: Math.random() * 10 + 20, heartRate: Math.floor(Math.random() * 30 + 140), strokeRate: Math.floor(Math.random() * 10 + 30), velocity: Math.random() * 0.5 + 1.5, dps: Math.random() * 0.5 + 1.8, pace: Math.floor(Math.random() * 20 + 60), strokeEfficiency: Math.random() * 20 + 70, force: Math.random() * 50 + 150, })); }; const SwimSyncDashboard = () => { const [connected, setConnected] = useState(false); const [deviceName, setDeviceName] = useState(''); const [performanceData, setPerformanceData] = useState(generateMockData()); const [alertMessage, setAlertMessage] = useState(''); const [isSessionActive, setIsSessionActive] = useState(false); const [availableDevices, setAvailableDevices] = useState([]); const [showDeviceList, setShowDeviceList] = useState(false); const [swimmer, setSwimmer] = useState({ name: '', age: '', gender: '', focus: '' }); const [raceSession, setRaceSession] = useState({ event: '', stroke: '', time: '', poolType: '' }); const [analysis, setAnalysis] = useState(null); const showAlert = (message) => { setAlertMessage(message); setTimeout(() => setAlertMessage(''), 3000); }; const scanForDevices = async () => { try { const devices = await navigator.bluetooth.requestDevices({ filters: [ { services: ['heart_rate'] }, { services: ['fitness_machine'] }, { namePrefix: 'SwimSync' } ], optionalServices: ['battery_service'] }); setAvailableDevices(devices); setShowDeviceList(true); } catch (error) { console.error('Error scanning for devices:', error); showAlert('Error scanning for devices. Please try again.'); } }; const connectToDevice = async (device) => { try { const server = await device.gatt.connect(); const services = await server.getPrimaryServices(); for (const service of services) { const characteristics = await service.getCharacteristics(); for (const characteristic of characteristics) { if (characteristic.properties.notify) { await characteristic.startNotifications(); characteristic.addEventListener('characteristicvaluechanged', handleDataChange); } } } setDeviceName(device.name); setConnected(true); setShowDeviceList(false); showAlert(`Connected to ${device.name}`); } catch (error) { console.error('Error connecting to device:', error); showAlert('Error connecting to device. Please try again.'); } }; const handleDataChange = (event) => { const value = event.target.value; // Parse the data based on the characteristic UUID // This is a simplified example; you'd need to implement proper parsing based on the device's data format const newData = { timestamp: new Date().toISOString(), heartRate: value.getUint8(1), // Add other metrics here based on the device's data format }; setPerformanceData(prevData => [...prevData.slice(-19), newData]); }; const startSession = () => { if (!connected) { showAlert('Please connect a device before starting a session.'); return; } setIsSessionActive(true); showAlert('Swimming session started'); }; const endSession = () => { setIsSessionActive(false); showAlert('Swimming session ended'); analyzePerformance(); }; const syncData = () => { // In a real app, this would trigger a data sync with the connected device showAlert('Syncing data from device...'); // For this example, we'll just generate new mock data setPerformanceData(generateMockData()); showAlert('Data synced successfully'); analyzePerformance(); }; const exportData = () => { const dataStr = JSON.stringify(performanceData, null, 2); const dataUri = 'data:application/json;charset=utf-8,'+ encodeURIComponent(dataStr); const exportFileDefaultName = 'swimsync_data.json'; const linkElement = document.createElement('a'); linkElement.setAttribute('href', dataUri); linkElement.setAttribute('download', exportFileDefaultName); linkElement.click(); showAlert('Data exported successfully'); }; const analyzePerformance = () => { // This is a mock analysis. In a real application, you'd use more sophisticated algorithms const lastData = performanceData[performanceData.length - 1]; const avgHeartRate = performanceData.reduce((sum, data) => sum + data.heartRate, 0) / performanceData.length; const avgPace = performanceData.reduce((sum, data) => sum + data.pace, 0) / performanceData.length; const avgStrokeEfficiency = performanceData.reduce((sum, data) => sum + data.strokeEfficiency, 0) / performanceData.length; const analysis = { avgHeartRate: Math.round(avgHeartRate), avgPace: Math.round(avgPace), avgStrokeEfficiency: Math.round(avgStrokeEfficiency), peakVelocity: Math.max(...performanceData.map(data => data.velocity)), enduranceScore: Math.round((avgHeartRate / lastData.heartRate) * 100), techniqueSuggestion: avgStrokeEfficiency < 80 ? "Focus on improving stroke efficiency" : "Maintain current technique", paceConsistency: Math.round((1 - (Math.max(...performanceData.map(data => data.pace)) - Math.min(...performanceData.map(data => data.pace))) / avgPace) * 100) }; setAnalysis(analysis); }; const handleSwimmerChange = (field, value) => { setSwimmer(prev => ({ ...prev, [field]: value })); }; const handleRaceSessionChange = (field, value) => { setRaceSession(prev => ({ ...prev, [field]: value })); }; return (
{alertMessage && ( Notification {alertMessage} )}

SwimSync 2024

Available Devices
    {availableDevices.map((device, index) => (
  • ))}
Dashboard Swimmer Profile Performance Analysis

Current Session

Avg. Lap Time

{performanceData[performanceData.length - 1].lapTime.toFixed(1)}s

Heart Rate

{performanceData[performanceData.length - 1].heartRate} bpm

Performance Metrics

Stroke Rate

{performanceData[performanceData.length - 1].strokeRate} spm

Velocity

{performanceData[performanceData.length - 1].velocity.toFixed(2)} m/s

DPS

{performanceData[performanceData.length - 1].dps.toFixed(2)} m

Pace

{performanceData[performanceData.length - 1].pace} s/100m

Quick Actions

Heart Rate & Pace

new Date(timestamp).toLocaleTimeString()} />

Stroke Efficiency & Force

new Date(timestamp).toLocaleTimeString()} />

Swimmer Profile