Something went wrong on our end
-
Trivikram Battalapalli authoredTrivikram Battalapalli authored
WorkoutAnalysisScreen.js 6.50 KiB
import React, { useEffect, useState } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { getWorkoutById } from '../api/workout_api';
import {
getWorkoutReportsByWorkoutId,
refreshWorkoutReport,
} from '../api/workout_report_api';
import RepCard from '../components/RepCard';
import HeaderBar from '../components/HeaderBar';
function WorkoutAnalysisScreen() {
const navigate = useNavigate();
const { workoutId } = useParams();
const [workoutData, setWorkoutData] = useState(null);
const [workoutReport, setWorkoutReport] = useState(null);
const [loading, setLoading] = useState(true);
const [reportLoading, setReportLoading] = useState(false);
useEffect(() => {
const fetchWorkoutData = async () => {
try {
const response = await getWorkoutById(workoutId);
setWorkoutData(response);
} catch (error) {
console.error('Error fetching workout data:', error);
} finally {
setLoading(false);
}
};
const fetchWorkoutReport = async () => {
try {
const reportResponse = await getWorkoutReportsByWorkoutId(
workoutId
);
if (reportResponse && reportResponse.length > 0) {
setWorkoutReport(reportResponse[0]);
}
} catch (error) {
console.error('Error fetching workout report:', error);
}
};
fetchWorkoutData();
fetchWorkoutReport();
}, [workoutId]);
const handleRefreshReport = async () => {
setReportLoading(true);
try {
const newReportResponse = await refreshWorkoutReport(workoutId);
if (newReportResponse) {
setWorkoutReport(newReportResponse);
alert('Workout report refreshed successfully!');
}
} catch (error) {
alert('Error: Failed to refresh the workout report.');
console.error('Error refreshing workout report:', error);
} finally {
setReportLoading(false);
}
};
if (loading) {
return (
<div className="flex justify-center items-center h-screen bg-theme_bg">
<div className="spinner-border text-blue-500" role="status" />
</div>
);
}
if (!workoutData) {
return (
<div className="flex justify-center items-center h-screen bg-theme_bg">
<p className="text-white">No workout data available</p>
</div>
);
}
const {
startTime,
groundContactTimeAvg,
angularVelocityAccAvg,
angularVelocityDriveAvg,
reps,
} = workoutData;
const formattedDate = new Intl.DateTimeFormat('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
hour12: true,
}).format(new Date(startTime));
return (
<div className="bg-theme_bg min-h-screen">
<HeaderBar title="Workout Analysis" />
<div className="text-center py-4 px-4">
<h2 className="text-2xl font-bold text-blue-500">
Workout on {formattedDate}
</h2>
</div>
<div className="grid gap-4 px-4">
<div className="p-4 bg-primary rounded-lg shadow">
<p className="text-white text-sm">
Ground Contact Time Avg
</p>
<p className="text-gray-300 text-2xl font-bold">
{groundContactTimeAvg || 'N/A'} ms
</p>
</div>
<div className="grid grid-cols-2 gap-4">
<div className="p-4 bg-primary rounded-lg shadow">
<p className="text-white text-sm">
Angular Velocity (Acc.)
</p>
<p className="text-gray-300 text-2xl font-bold">
{angularVelocityAccAvg || 'N/A'} deg/s
</p>
</div>
<div className="p-4 bg-primary rounded-lg shadow">
<p className="text-white text-sm">
Angular Velocity (Drive)
</p>
<p className="text-gray-300 text-2xl font-bold">
{angularVelocityDriveAvg || 'N/A'} deg/s
</p>
</div>
</div>
</div>
<div className="px-4 py-4">
{reps && reps.length > 0 ? (
reps.map((rep, index) => (
<RepCard key={index} rep={rep} repNumber={index + 1} />
))
) : (
<p className="text-gray-300 text-center">
No reps available for this workout.
</p>
)}
</div>
{workoutReport && (
<div className="mx-4 my-6 p-4 bg-white rounded-lg shadow">
<h3 className="text-lg font-bold mb-2">Workout Report</h3>
<p className="mb-2">
Overall Analysis: {workoutReport.overallAnalysis}
</p>
<p className="mb-2">
Comparison to Previous:{' '}
{workoutReport.comparisonToPrevious}
</p>
<p className="mb-2">
Training Recommendations:{' '}
{workoutReport.trainingRecommendations}
</p>
<button
className="w-full mt-4 bg-primary text-white p-3 rounded-lg"
onClick={handleRefreshReport}
disabled={reportLoading}
>
{reportLoading ? 'Refreshing...' : 'Refresh Report'}
</button>
</div>
)}
{/* Return to Home button */}
<div className="mx-4 my-4">
<button
className="w-full bg-primary text-white p-3 rounded-lg"
onClick={() => navigate('/home')}
>
Return to Home
</button>
</div>
</div>
);
}
export default WorkoutAnalysisScreen;