Minor History fix

This commit is contained in:
AG
2025-11-20 23:57:00 +02:00
parent e6a3a5b0ff
commit ada10d52e8
3 changed files with 312 additions and 305 deletions

10
App.tsx
View File

@@ -94,13 +94,19 @@ function App() {
setCurrentTab('TRACK');
};
const handleEndSession = () => {
const handleEndSession = async () => {
if (activeSession && currentUser) {
const finishedSession = { ...activeSession, endTime: Date.now() };
saveSession(currentUser.id, finishedSession);
await saveSession(currentUser.id, finishedSession);
setSessions(prev => [finishedSession, ...prev]);
setActiveSession(null);
setActivePlan(null);
// Refetch user to get updated weight
const res = await getMe();
if (res.success && res.user) {
setCurrentUser(res.user);
}
}
};

View File

@@ -102,7 +102,7 @@ const History: React.FC<HistoryProps> = ({ sessions, onUpdateSession, onDeleteSe
{new Date(session.startTime).toLocaleDateString(lang === 'ru' ? 'ru-RU' : 'en-US', { weekday: 'long', day: 'numeric', month: 'long' })}
</div>
<div className="text-xs text-on-surface-variant flex items-center gap-2">
<span>{new Date(session.startTime).toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'})}</span>
<span>{new Date(session.startTime).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}</span>
{session.userBodyWeight && <span className="px-2 py-0.5 rounded-full bg-surface-container-high text-on-surface">{session.userBodyWeight}kg</span>}
</div>
</div>
@@ -135,7 +135,7 @@ const History: React.FC<HistoryProps> = ({ sessions, onUpdateSession, onDeleteSe
else if (bestSet.type === ExerciseType.STRENGTH) detail = `${t('upto', lang)} ${Math.max(...sets.map(s => s.weight || 0))}kg`;
return (
<div key={exName} className="flex justify-between text-sm items-center">
<div key={`${session.id}-${exName}`} className="flex justify-between text-sm items-center">
<span className="text-on-surface">{exName}</span>
<span className="text-on-surface-variant flex gap-2 items-center">
{detail && <span className="text-[10px] bg-surface-container-high px-2 py-0.5 rounded text-on-surface-variant">{detail}</span>}
@@ -167,7 +167,8 @@ const History: React.FC<HistoryProps> = ({ sessions, onUpdateSession, onDeleteSe
</div>
</div>
</div>
)})}
)
})}
</div>
{/* DELETE CONFIRMATION DIALOG (MD3) */}
@@ -216,7 +217,7 @@ const History: React.FC<HistoryProps> = ({ sessions, onUpdateSession, onDeleteSe
<input
type="datetime-local"
value={formatDateForInput(editingSession.startTime)}
onChange={(e) => setEditingSession({...editingSession, startTime: parseDateFromInput(e.target.value)})}
onChange={(e) => setEditingSession({ ...editingSession, startTime: parseDateFromInput(e.target.value) })}
className="w-full bg-transparent text-on-surface focus:outline-none text-sm mt-1"
/>
</div>
@@ -225,7 +226,7 @@ const History: React.FC<HistoryProps> = ({ sessions, onUpdateSession, onDeleteSe
<input
type="datetime-local"
value={editingSession.endTime ? formatDateForInput(editingSession.endTime) : ''}
onChange={(e) => setEditingSession({...editingSession, endTime: parseDateFromInput(e.target.value)})}
onChange={(e) => setEditingSession({ ...editingSession, endTime: parseDateFromInput(e.target.value) })}
className="w-full bg-transparent text-on-surface focus:outline-none text-sm mt-1"
/>
</div>
@@ -235,7 +236,7 @@ const History: React.FC<HistoryProps> = ({ sessions, onUpdateSession, onDeleteSe
<input
type="number"
value={editingSession.userBodyWeight || ''}
onChange={(e) => setEditingSession({...editingSession, userBodyWeight: parseFloat(e.target.value)})}
onChange={(e) => setEditingSession({ ...editingSession, userBodyWeight: parseFloat(e.target.value) })}
className="w-full bg-transparent text-on-surface focus:outline-none text-lg mt-1"
/>
</div>
@@ -258,7 +259,7 @@ const History: React.FC<HistoryProps> = ({ sessions, onUpdateSession, onDeleteSe
<div className="grid grid-cols-3 gap-2">
{(set.type === ExerciseType.STRENGTH || set.type === ExerciseType.BODYWEIGHT || set.type === ExerciseType.STATIC) && (
<div className="bg-surface-container-high rounded px-2 py-1">
<label className="text-[10px] text-on-surface-variant flex gap-1 items-center"><Dumbbell size={10}/> {t('weight_kg', lang)}</label>
<label className="text-[10px] text-on-surface-variant flex gap-1 items-center"><Dumbbell size={10} /> {t('weight_kg', lang)}</label>
<input
type="number"
className="w-full bg-transparent text-sm text-on-surface focus:outline-none"
@@ -269,7 +270,7 @@ const History: React.FC<HistoryProps> = ({ sessions, onUpdateSession, onDeleteSe
)}
{(set.type === ExerciseType.STRENGTH || set.type === ExerciseType.BODYWEIGHT || set.type === ExerciseType.PLYOMETRIC) && (
<div className="bg-surface-container-high rounded px-2 py-1">
<label className="text-[10px] text-on-surface-variant flex gap-1 items-center"><Activity size={10}/> {t('reps', lang)}</label>
<label className="text-[10px] text-on-surface-variant flex gap-1 items-center"><Activity size={10} /> {t('reps', lang)}</label>
<input
type="number"
className="w-full bg-transparent text-sm text-on-surface focus:outline-none"
@@ -280,7 +281,7 @@ const History: React.FC<HistoryProps> = ({ sessions, onUpdateSession, onDeleteSe
)}
{(set.type === ExerciseType.BODYWEIGHT || set.type === ExerciseType.STATIC) && (
<div className="bg-surface-container-high rounded px-2 py-1">
<label className="text-[10px] text-on-surface-variant flex gap-1 items-center"><Percent size={10}/> {t('body_weight_percent', lang)}</label>
<label className="text-[10px] text-on-surface-variant flex gap-1 items-center"><Percent size={10} /> {t('body_weight_percent', lang)}</label>
<input
type="number"
className="w-full bg-transparent text-sm text-on-surface focus:outline-none"

View File

@@ -18,6 +18,24 @@ interface TrackerProps {
lang: Language;
}
const FilledInput = ({ label, value, onChange, type = "number", icon, autoFocus, step }: any) => (
<div className="relative group bg-surface-container-high rounded-t-lg border-b border-outline-variant hover:bg-white/5 focus-within:border-primary transition-colors">
<label className="absolute top-2 left-4 text-[10px] font-medium text-on-surface-variant flex items-center gap-1">
{icon} {label}
</label>
<input
type={type}
step={step}
inputMode="decimal"
autoFocus={autoFocus}
className="w-full pt-6 pb-2 px-4 bg-transparent text-2xl text-on-surface focus:outline-none placeholder-transparent"
placeholder="0"
value={value}
onChange={onChange}
/>
</div>
);
const Tracker: React.FC<TrackerProps> = ({ userId, userWeight, activeSession, activePlan, onSessionStart, onSessionEnd, onSetAdded, onRemoveSet, lang }) => {
const [exercises, setExercises] = useState<ExerciseDef[]>([]);
const [plans, setPlans] = useState<WorkoutPlan[]>([]);
@@ -107,11 +125,11 @@ const Tracker: React.FC<TrackerProps> = ({ userId, userWeight, activeSession, ac
setLastSet(set);
if (set) {
if (set.weight !== undefined) setWeight(set.weight.toString());
if (set.reps !== undefined) setReps(set.reps.toString());
if (set.durationSeconds !== undefined) setDuration(set.durationSeconds.toString());
if (set.distanceMeters !== undefined) setDistance(set.distanceMeters.toString());
if (set.height !== undefined) setHeight(set.height.toString());
if (set.weight != null) setWeight(set.weight.toString());
if (set.reps != null) setReps(set.reps.toString());
if (set.durationSeconds != null) setDuration(set.durationSeconds.toString());
if (set.distanceMeters != null) setDistance(set.distanceMeters.toString());
if (set.height != null) setHeight(set.height.toString());
} else {
setWeight(''); setReps(''); setDuration(''); setDistance(''); setHeight('');
}
@@ -189,24 +207,6 @@ const Tracker: React.FC<TrackerProps> = ({ userId, userWeight, activeSession, ac
const isPlanFinished = activePlan && currentStepIndex >= activePlan.steps.length;
const FilledInput = ({ label, value, onChange, type = "number", icon, autoFocus, step }: any) => (
<div className="relative group bg-surface-container-high rounded-t-lg border-b border-outline-variant hover:bg-white/5 focus-within:border-primary transition-colors">
<label className="absolute top-2 left-4 text-[10px] font-medium text-on-surface-variant flex items-center gap-1">
{icon} {label}
</label>
<input
type={type}
step={step}
inputMode="decimal"
autoFocus={autoFocus}
className="w-full pt-6 pb-2 px-4 bg-transparent text-2xl text-on-surface focus:outline-none placeholder-transparent"
placeholder="0"
value={value}
onChange={onChange}
/>
</div>
);
const exerciseTypeLabels: Record<ExerciseType, string> = {
[ExerciseType.STRENGTH]: t('type_strength', lang),
[ExerciseType.BODYWEIGHT]: t('type_bodyweight', lang),