fix(practice): disable auto-scroll and add modern PWA meta tag

- 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 <noreply@anthropic.com>
This commit is contained in:
Thomas Hallock
2025-12-09 11:25:53 -06:00
parent 43e7db4e88
commit 8a9afa86bc
6 changed files with 18 additions and 12 deletions

View File

@@ -68,6 +68,11 @@ export const metadata: Metadata = {
title: 'Abaci.One', title: 'Abaci.One',
}, },
// Modern web app capable meta tag (non-Apple browsers)
other: {
'mobile-web-app-capable': 'yes',
},
// Category // Category
category: 'education', category: 'education',
} }

View File

@@ -38,7 +38,7 @@ export function PracticeClient({ initialPlayers }: PracticeClientProps) {
// Handle student selection - navigate to student's practice page // Handle student selection - navigate to student's practice page
const handleSelectStudent = useCallback( const handleSelectStudent = useCallback(
(student: StudentWithProgress) => { (student: StudentWithProgress) => {
router.push(`/practice/${student.id}`) router.push(`/practice/${student.id}`, { scroll: false })
}, },
[router] [router]
) )

View File

@@ -154,7 +154,7 @@ export function StudentPracticeClient({
// Handle continue practice - navigate to configuration page // Handle continue practice - navigate to configuration page
const handleContinuePractice = useCallback(() => { const handleContinuePractice = useCallback(() => {
router.push(`/practice/${studentId}/configure`) router.push(`/practice/${studentId}/configure`, { scroll: false })
}, [studentId, router]) }, [studentId, router])
// Handle resuming an existing session // Handle resuming an existing session
@@ -187,7 +187,7 @@ export function StudentPracticeClient({
{ {
onSuccess: () => { onSuccess: () => {
// Navigate to configure page for a fresh start // 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 }, { playerId: studentId, planId: currentPlan.id },
{ {
onSuccess: () => { onSuccess: () => {
router.push(`/practice/${studentId}/configure`) router.push(`/practice/${studentId}/configure`, { scroll: false })
}, },
} }
) )
} else { } else {
router.push(`/practice/${studentId}/configure`) router.push(`/practice/${studentId}/configure`, { scroll: false })
} }
}, [studentId, currentPlan, abandonSession, router]) }, [studentId, currentPlan, abandonSession, router])
@@ -275,7 +275,7 @@ export function StudentPracticeClient({
endEarly.reset() endEarly.reset()
abandonSession.reset() abandonSession.reset()
// Navigate to configure page for new session // Navigate to configure page for new session
router.push(`/practice/${studentId}/configure`) router.push(`/practice/${studentId}/configure`, { scroll: false })
}, [ }, [
generatePlan, generatePlan,
approvePlan, approvePlan,
@@ -314,7 +314,7 @@ export function StudentPracticeClient({
// Handle opening placement test - navigate to placement test route // Handle opening placement test - navigate to placement test route
const handleRunPlacementTest = useCallback(() => { const handleRunPlacementTest = useCallback(() => {
router.push(`/practice/${studentId}/placement-test`) router.push(`/practice/${studentId}/placement-test`, { scroll: false })
}, [studentId, router]) }, [studentId, router])
// Handle opening manual skill selector // Handle opening manual skill selector

View File

@@ -59,7 +59,7 @@ export function ConfigureClient({ studentId, playerName }: ConfigureClientProps)
{ {
onSuccess: () => { onSuccess: () => {
// Redirect to main practice page - view will derive from session data // Redirect to main practice page - view will derive from session data
router.push(`/practice/${studentId}`) router.push(`/practice/${studentId}`, { scroll: false })
}, },
onError: (err) => { onError: (err) => {
// If an active session already exists, use it and redirect // 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 // Update the cache with the existing plan so the practice page has it
queryClient.setQueryData(sessionPlanKeys.active(studentId), err.existingPlan) queryClient.setQueryData(sessionPlanKeys.active(studentId), err.existingPlan)
// Redirect to practice page // 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(() => { const handleCancel = useCallback(() => {
generatePlan.reset() generatePlan.reset()
router.push(`/practice/${studentId}`) router.push(`/practice/${studentId}`, { scroll: false })
}, [studentId, generatePlan, router]) }, [studentId, generatePlan, router])
return ( return (

View File

@@ -53,6 +53,7 @@ export default function StudentNotFound() {
</p> </p>
<Link <Link
href="/practice" href="/practice"
scroll={false}
className={css({ className={css({
display: 'inline-block', display: 'inline-block',
padding: '0.75rem 2rem', padding: '0.75rem 2rem',

View File

@@ -29,13 +29,13 @@ export function PlacementTestClient({ studentId, playerName }: PlacementTestClie
// TODO: Save results to curriculum via API // TODO: Save results to curriculum via API
console.log('Placement test complete:', results) console.log('Placement test complete:', results)
// Return to main practice page // Return to main practice page
router.push(`/practice/${studentId}`) router.push(`/practice/${studentId}`, { scroll: false })
}, },
[studentId, router] [studentId, router]
) )
const handleCancel = useCallback(() => { const handleCancel = useCallback(() => {
router.push(`/practice/${studentId}`) router.push(`/practice/${studentId}`, { scroll: false })
}, [studentId, router]) }, [studentId, router])
return ( return (