6.6 KiB
6.6 KiB
Profile Tabs URL Routing Implementation
Overview
Currently, the profile settings use local tab state which resets to the first tab after page refresh. Need to implement URL-based routing for each profile tab to maintain state persistence and enable direct linking.
Current Issue
- Profile settings tabs (Profile, Balance, Billing, Services, Security, Danger Zone) use React state
- After page refresh, always defaults to "Profile" tab
- No way to directly link to specific tabs (e.g.,
/profile?tab=balance
) - Poor UX for users who want to bookmark specific sections
Proposed Solution
Option 1: Query Parameters (Recommended)
Use URL query parameters to maintain tab state while keeping single page structure:
/profile
- Default to Profile tab/profile?tab=balance
- Balance tab/profile?tab=billing
- Billing tab/profile?tab=services
- Services tab/profile?tab=security
- Security tab/profile?tab=danger-zone
- Danger Zone tab
Option 2: Dedicated Routes
Create separate routes for each section (more complex but better SEO):
/profile
- Profile settings/profile/balance
- Balance management/profile/billing
- Billing history/profile/services
- Active services/profile/security
- Security settings/profile/settings
- Danger zone/account deletion
Implementation Details
Query Parameter Approach (Recommended)
1. Update Profile Page
// app/profile/page.tsx
'use client'
import { useSearchParams, useRouter } from 'next/navigation'
import { useEffect, useState } from 'react'
export default function ProfilePage() {
const searchParams = useSearchParams()
const router = useRouter()
const [activeTab, setActiveTab] = useState('profile')
useEffect(() => {
const tab = searchParams.get('tab')
if (tab && ['profile', 'balance', 'billing', 'services', 'security', 'danger-zone'].includes(tab)) {
setActiveTab(tab)
}
}, [searchParams])
const handleTabChange = (tab: string) => {
setActiveTab(tab)
const params = new URLSearchParams(searchParams.toString())
params.set('tab', tab)
router.push(`/profile?${params.toString()}`)
}
return (
<ProfileSettings activeTab={activeTab} onTabChange={handleTabChange} />
)
}
2. Update ProfileSettings Component
// components/profile/ProfileSettings.tsx
interface ProfileSettingsProps {
activeTab?: string
onTabChange?: (tab: string) => void
}
export function ProfileSettings({ activeTab = 'profile', onTabChange }: ProfileSettingsProps) {
return (
<Tabs value={activeTab} onValueChange={onTabChange} className="space-y-6">
{/* Rest of component */}
</Tabs>
)
}
Dedicated Routes Approach
1. Create Route Structure
app/profile/
├── page.tsx # Profile settings (default)
├── balance/
│ └── page.tsx # Balance management
├── billing/
│ └── page.tsx # Billing history
├── services/
│ └── page.tsx # Active services
├── security/
│ └── page.tsx # Security settings
└── settings/
└── page.tsx # Danger zone
2. Create Layout Component
// app/profile/layout.tsx
export default function ProfileLayout({ children }: { children: React.ReactNode }) {
return (
<div className="min-h-screen bg-background">
<Header />
<RequireAuth>
<div className="container py-8">
<div className="grid grid-cols-1 lg:grid-cols-4 gap-8">
<ProfileCard />
<div className="lg:col-span-3">
<ProfileNavigation />
{children}
</div>
</div>
</div>
</RequireAuth>
<Footer />
</div>
)
}
Benefits
Query Parameters
- ✅ Simple implementation
- ✅ Maintains current component structure
- ✅ Bookmarkable URLs
- ✅ State persistence after refresh
- ✅ Easy to implement with existing codebase
Dedicated Routes
- ✅ Better SEO (each section has unique URL)
- ✅ More granular loading states
- ✅ Better analytics tracking
- ✅ Cleaner URL structure
- ❌ More complex implementation
- ❌ Requires restructuring existing components
Recommended Approach
Use Query Parameters for the following reasons:
- Minimal changes to existing codebase
- Maintains current component structure
- Quick implementation
- Solves the immediate UX issue
- Can be upgraded to dedicated routes later if needed
Implementation Steps
Phase 1: Basic Query Parameter Support
- Update
/app/profile/page.tsx
to read query parameters - Modify
ProfileSettings
component to accept props for active tab - Implement tab change handler that updates URL
- Test state persistence after refresh
Phase 2: Enhanced URL Handling
- Add URL validation for tab names
- Handle invalid tab parameters gracefully
- Add default tab fallback logic
- Implement browser back/forward navigation
Phase 3: User Experience Improvements
- Add loading states for tab transitions
- Scroll to top when switching tabs via URL
- Update page metadata based on active tab
- Add breadcrumbs for better navigation
Technical Considerations
Next.js App Router
- Use
useSearchParams
hook for reading query parameters - Use
useRouter
for programmatic navigation - Ensure components are client-side rendered when using hooks
State Management
- Sync URL state with component state
- Handle race conditions between URL changes and component updates
- Preserve form state when switching tabs
SEO & Accessibility
- Update page title based on active tab
- Add proper meta descriptions for each section
- Ensure keyboard navigation works with URL routing
- Add skip links for accessibility
Future Enhancements
Advanced Features
- Deep linking to specific items (e.g.,
/profile?tab=billing&invoice=123
) - Tab history tracking
- Keyboard shortcuts for tab navigation
- Share buttons for specific sections
Analytics Integration
- Track tab usage patterns
- Monitor user navigation flows
- Identify most/least used sections
Testing Requirements
Manual Testing
- ✅ Tab state persists after page refresh
- ✅ Direct URLs work correctly (e.g.,
/profile?tab=balance
) - ✅ Browser back/forward navigation works
- ✅ Invalid tab parameters handle gracefully
- ✅ Default tab loads when no parameter specified
Automated Testing
- Unit tests for tab routing logic
- Integration tests for URL parameter handling
- E2E tests for full user navigation flows
Created: 2025-08-06
Priority: High - UX improvement
Estimated Time: 2-3 hours implementation
Dependencies: None
Status: Ready for implementation