// components/workout/WorkoutCard.tsx import React from 'react'; import { View, TouchableOpacity } from 'react-native'; import { Text } from '@/components/ui/text'; import { ChevronRight, CloudIcon, SmartphoneIcon, CloudOffIcon } from 'lucide-react-native'; import { Card, CardContent } from '@/components/ui/card'; import { Workout } from '@/types/workout'; import { format } from 'date-fns'; import { useRouter } from 'expo-router'; import { cn } from '@/lib/utils'; export interface EnhancedWorkoutCardProps { workout: Workout; showDate?: boolean; showExercises?: boolean; source?: 'local' | 'nostr' | 'both'; publishStatus?: { isPublished: boolean; relayCount?: number; lastPublished?: number; }; onShare?: () => void; onImport?: () => void; } // Calculate duration in hours and minutes const formatDuration = (startTime: number, endTime: number) => { const durationMs = endTime - startTime; const hours = Math.floor(durationMs / (1000 * 60 * 60)); const minutes = Math.floor((durationMs % (1000 * 60 * 60)) / (1000 * 60)); if (hours > 0) { return `${hours}h ${minutes}m`; } return `${minutes}m`; }; export const WorkoutCard: React.FC = ({ workout, showDate = true, showExercises = true, source, publishStatus, onShare, onImport }) => { const router = useRouter(); const handlePress = () => { // Navigate to workout details console.log(`Navigate to workout ${workout.id}`); router.push(`/workout/${workout.id}`); }; // Determine source if not explicitly provided const workoutSource = source || (workout.availability?.source?.includes('nostr') && workout.availability?.source?.includes('local') ? 'both' : workout.availability?.source?.includes('nostr') ? 'nostr' : 'local'); // Determine publish status if not explicitly provided const workoutPublishStatus = publishStatus || { isPublished: Boolean(workout.availability?.nostrEventId), relayCount: workout.availability?.nostrRelayCount, lastPublished: workout.availability?.nostrPublishedAt }; // Debug: Log exercises console.log(`WorkoutCard for ${workout.id} has ${workout.exercises?.length || 0} exercises`); if (workout.exercises && workout.exercises.length > 0) { console.log(`First exercise: ${workout.exercises[0].title}`); } // Define colors for icons const primaryColor = "#8b5cf6"; // Purple color const mutedColor = "#9ca3af"; // Gray color return ( {workout.title} {/* Source indicator */} {workoutSource === 'local' && ( )} {workoutSource === 'nostr' && ( )} {workoutSource === 'both' && ( )} {showDate && ( {format(workout.startTime, 'EEEE, MMM d')} )} {/* Publish status indicator */} {workoutSource !== 'nostr' && ( {workoutPublishStatus.isPublished ? ( Published to {workoutPublishStatus.relayCount || 0} relays {workoutPublishStatus.lastPublished && ` on ${format(workoutPublishStatus.lastPublished, 'MMM d')}`} {onShare && ( Republish )} ) : ( Local only {onShare && ( Publish )} )} )} {/* Import button for Nostr-only workouts */} {workoutSource === 'nostr' && onImport && ( Import to local )} ⏱️ {formatDuration(workout.startTime, workout.endTime || Date.now())} ⚖️ {workout.totalVolume ? `${workout.totalVolume} lb` : '0 lb'} {workout.totalReps && ( 🔄 {workout.totalReps} reps )} {/* Show exercises if requested */} {showExercises && ( Exercise {/* In a real implementation, you would map through actual exercises */} {workout.exercises && workout.exercises.length > 0 ? ( workout.exercises.slice(0, 3).map((exercise, idx) => ( {exercise.title} )) ) : ( No exercises recorded )} {workout.exercises && workout.exercises.length > 3 && ( +{workout.exercises.length - 3} more exercises )} )} ); }; export default WorkoutCard;