ShipDesk
Task Manager
ShipDesk
Progress
05

Dashboard Pages Migration

User, Doctor, Hospital, Admin, Founder — all pages, dynamic routes

Week 4–614–18 daysEstimated: 47h totalLargest Phase
Why this matters
This is your largest phase — 13+ pages across 5 user types. The pattern is mechanical but mistakes here cascade. Follow the exact rule: add 'use client', swap router imports, keep everything else identical.
Rule for every dashboard page
Add 'use client' at top. Replace useNavigate → useRouter. Replace useParams → useParams from next/navigation. Everything else stays identical.
User Dashboard — app/dashboard/
app/dashboard/page.jsx ← Dashboard.jsx
3 hrs
app/dashboard/reports/page.jsx ← Reports.jsx
2 hrs
app/dashboard/upload/page.jsx ← Upload.jsx
2 hrs
app/dashboard/profile/page.jsx ← Profile.jsx
2 hrs
app/dashboard/notifications/page.jsx
1 hr
app/dashboard/digital-prescriptions/page.jsx
3 hrs
app/dashboard/digital-prescriptions/[id]/page.jsx
2 hrs
app/dashboard/digital-prescriptions/reminders/page.jsx
1 hr
Doctor + Hospital + Admin + Founder
app/doctor/dashboard/page.jsx
3 hrs
app/hospital/dashboard/ + find-patient/
3 hrs
app/founder/dashboard/ + staff-directory/
4 hrs
app/admin/ — all pages
6 hrs
app/medical/dashboard/page.jsx
2 hrs
hooks/useSocket.js — Socket.io in Next.js
'use client'
import { useEffect, useRef } from 'react'
import { io } from 'socket.io-client'

export function useSocket(userId) {
  const socketRef = useRef(null)

  useEffect(() => {
    // Only connect on client side
    if (typeof window === 'undefined') return

    socketRef.current = io(process.env.NEXT_PUBLIC_SOCKET_URL, {
      query: { userId },
      transports: ['websocket'],
    })

    socketRef.current.on('connect', () => {
      console.log('Socket connected:', socketRef.current.id)
    })

    return () => {
      socketRef.current?.disconnect()
    }
  }, [userId])

  return socketRef
}
app/dashboard/digital-prescriptions/[id]/page.jsx — dynamic route
'use client'
import { useParams } from 'next/navigation'

export default function PrescriptionDetail() {
  const { id } = useParams() // reads [id] from URL

  // Use 'id' to fetch prescription data
  // Everything else is identical to your Vite component
}
store/useAuthStore.js — add 'use client'
// BEFORE (Vite — no directive needed)
import { create } from 'zustand'

// AFTER (Next.js — MUST add 'use client' as line 1)
'use client'
import { create } from 'zustand'
import { persist } from 'zustand/middleware'

// Rest of your store is identical
Previous
Phase 04Middleware + Dashboard Layout
Next
Phase 06UI Upgrade — shadcn/ui