From 8a9afa86bc6bf38b0668dd63fd0b1a43d65e2763 Mon Sep 17 00:00:00 2001 From: Thomas Hallock Date: Tue, 9 Dec 2025 11:25:53 -0600 Subject: [PATCH] fix(practice): disable auto-scroll and add modern PWA meta tag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add scroll: false to all router.push() calls in practice pages - Add scroll={false} to Link component in not-found page - Fixes Next.js warning about auto-scroll with fixed position header - Add mobile-web-app-capable meta tag alongside deprecated apple-mobile-web-app-capable 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- apps/web/src/app/layout.tsx | 5 +++++ apps/web/src/app/practice/PracticeClient.tsx | 2 +- .../practice/[studentId]/StudentPracticeClient.tsx | 12 ++++++------ .../[studentId]/configure/ConfigureClient.tsx | 6 +++--- apps/web/src/app/practice/[studentId]/not-found.tsx | 1 + .../placement-test/PlacementTestClient.tsx | 4 ++-- 6 files changed, 18 insertions(+), 12 deletions(-) diff --git a/apps/web/src/app/layout.tsx b/apps/web/src/app/layout.tsx index 762ae771..0a0ee240 100644 --- a/apps/web/src/app/layout.tsx +++ b/apps/web/src/app/layout.tsx @@ -68,6 +68,11 @@ export const metadata: Metadata = { title: 'Abaci.One', }, + // Modern web app capable meta tag (non-Apple browsers) + other: { + 'mobile-web-app-capable': 'yes', + }, + // Category category: 'education', } diff --git a/apps/web/src/app/practice/PracticeClient.tsx b/apps/web/src/app/practice/PracticeClient.tsx index ecd54822..178e066d 100644 --- a/apps/web/src/app/practice/PracticeClient.tsx +++ b/apps/web/src/app/practice/PracticeClient.tsx @@ -38,7 +38,7 @@ export function PracticeClient({ initialPlayers }: PracticeClientProps) { // Handle student selection - navigate to student's practice page const handleSelectStudent = useCallback( (student: StudentWithProgress) => { - router.push(`/practice/${student.id}`) + router.push(`/practice/${student.id}`, { scroll: false }) }, [router] ) diff --git a/apps/web/src/app/practice/[studentId]/StudentPracticeClient.tsx b/apps/web/src/app/practice/[studentId]/StudentPracticeClient.tsx index b880d2d8..5e5d2c31 100644 --- a/apps/web/src/app/practice/[studentId]/StudentPracticeClient.tsx +++ b/apps/web/src/app/practice/[studentId]/StudentPracticeClient.tsx @@ -154,7 +154,7 @@ export function StudentPracticeClient({ // Handle continue practice - navigate to configuration page const handleContinuePractice = useCallback(() => { - router.push(`/practice/${studentId}/configure`) + router.push(`/practice/${studentId}/configure`, { scroll: false }) }, [studentId, router]) // Handle resuming an existing session @@ -187,7 +187,7 @@ export function StudentPracticeClient({ { onSuccess: () => { // Navigate to configure page for a fresh start - router.push(`/practice/${studentId}/configure`) + router.push(`/practice/${studentId}/configure`, { scroll: false }) }, } ) @@ -220,12 +220,12 @@ export function StudentPracticeClient({ { playerId: studentId, planId: currentPlan.id }, { onSuccess: () => { - router.push(`/practice/${studentId}/configure`) + router.push(`/practice/${studentId}/configure`, { scroll: false }) }, } ) } else { - router.push(`/practice/${studentId}/configure`) + router.push(`/practice/${studentId}/configure`, { scroll: false }) } }, [studentId, currentPlan, abandonSession, router]) @@ -275,7 +275,7 @@ export function StudentPracticeClient({ endEarly.reset() abandonSession.reset() // Navigate to configure page for new session - router.push(`/practice/${studentId}/configure`) + router.push(`/practice/${studentId}/configure`, { scroll: false }) }, [ generatePlan, approvePlan, @@ -314,7 +314,7 @@ export function StudentPracticeClient({ // Handle opening placement test - navigate to placement test route const handleRunPlacementTest = useCallback(() => { - router.push(`/practice/${studentId}/placement-test`) + router.push(`/practice/${studentId}/placement-test`, { scroll: false }) }, [studentId, router]) // Handle opening manual skill selector diff --git a/apps/web/src/app/practice/[studentId]/configure/ConfigureClient.tsx b/apps/web/src/app/practice/[studentId]/configure/ConfigureClient.tsx index aa585b90..ee10ced5 100644 --- a/apps/web/src/app/practice/[studentId]/configure/ConfigureClient.tsx +++ b/apps/web/src/app/practice/[studentId]/configure/ConfigureClient.tsx @@ -59,7 +59,7 @@ export function ConfigureClient({ studentId, playerName }: ConfigureClientProps) { onSuccess: () => { // Redirect to main practice page - view will derive from session data - router.push(`/practice/${studentId}`) + router.push(`/practice/${studentId}`, { scroll: false }) }, onError: (err) => { // If an active session already exists, use it and redirect @@ -67,7 +67,7 @@ export function ConfigureClient({ studentId, playerName }: ConfigureClientProps) // Update the cache with the existing plan so the practice page has it queryClient.setQueryData(sessionPlanKeys.active(studentId), err.existingPlan) // Redirect to practice page - router.push(`/practice/${studentId}`) + router.push(`/practice/${studentId}`, { scroll: false }) } }, } @@ -76,7 +76,7 @@ export function ConfigureClient({ studentId, playerName }: ConfigureClientProps) const handleCancel = useCallback(() => { generatePlan.reset() - router.push(`/practice/${studentId}`) + router.push(`/practice/${studentId}`, { scroll: false }) }, [studentId, generatePlan, router]) return ( diff --git a/apps/web/src/app/practice/[studentId]/not-found.tsx b/apps/web/src/app/practice/[studentId]/not-found.tsx index cd9fe4bb..33da6206 100644 --- a/apps/web/src/app/practice/[studentId]/not-found.tsx +++ b/apps/web/src/app/practice/[studentId]/not-found.tsx @@ -53,6 +53,7 @@ export default function StudentNotFound() {

{ - router.push(`/practice/${studentId}`) + router.push(`/practice/${studentId}`, { scroll: false }) }, [studentId, router]) return (