All files / web/src/app/create/worksheets page.tsx

0% Statements 0/100
0% Branches 0/1
0% Functions 0/1
0% Lines 0/100

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101                                                                                                                                                                                                         
import { eq, and } from 'drizzle-orm'
import { db, schema } from '@/db'
import { getUserId } from '@/lib/viewer'
import { parseAdditionConfig, defaultAdditionConfig } from '@/app/create/worksheets/config-schemas'
import { AdditionWorksheetClient } from './components/AdditionWorksheetClient'
import { WorksheetErrorBoundary } from './components/WorksheetErrorBoundary'
import type { WorksheetFormState } from '@/app/create/worksheets/types'

/**
 * Get current date formatted as "Month Day, Year"
 */
function getDefaultDate(): string {
  const now = new Date()
  return now.toLocaleDateString('en-US', {
    month: 'long',
    day: 'numeric',
    year: 'numeric',
  })
}

/**
 * Load worksheet settings from database (server-side)
 */
async function loadWorksheetSettings(): Promise<
  Omit<WorksheetFormState, 'date' | 'rows' | 'total'>
> {
  try {
    const userId = await getUserId()

    // Look up user's saved settings
    const [row] = await db
      .select()
      .from(schema.worksheetSettings)
      .where(
        and(
          eq(schema.worksheetSettings.userId, userId),
          eq(schema.worksheetSettings.worksheetType, 'addition')
        )
      )
      .limit(1)

    if (!row) {
      // No saved settings, return defaults with a new seed
      return {
        ...defaultAdditionConfig,
        seed: Date.now() % 2147483647,
        prngAlgorithm: 'mulberry32',
      } as unknown as Omit<WorksheetFormState, 'date' | 'rows' | 'total'>
    }

    // Parse and validate config (auto-migrates to latest version)
    const config = parseAdditionConfig(row.config)

    // CRITICAL: Use saved seed if present, otherwise generate new one
    // This ensures reloading the page shows the same problems
    const savedSeed = (config as any).seed
    const finalSeed = savedSeed ?? Date.now() % 2147483647

    return {
      ...config,
      seed: finalSeed,
      prngAlgorithm: (config as any).prngAlgorithm ?? 'mulberry32',
    } as unknown as Omit<WorksheetFormState, 'date' | 'rows' | 'total'>
  } catch (error) {
    console.error('Failed to load worksheet settings:', error)
    // Return defaults on error with a new seed
    return {
      ...defaultAdditionConfig,
      seed: Date.now() % 2147483647,
      prngAlgorithm: 'mulberry32',
    } as unknown as Omit<WorksheetFormState, 'date' | 'rows' | 'total'>
  }
}

/**
 * Worksheet page - loads settings fast, preview fetched client-side
 *
 * Performance optimization:
 * - Settings load fast (~50ms) - page shell renders immediately
 * - Preview is fetched via API after initial render (non-blocking)
 * - User sees the page UI in ~200ms, preview appears when API completes
 */
export default async function AdditionWorksheetPage() {
  const pageStart = Date.now()

  // Fast path: load settings from DB
  const initialSettings = await loadWorksheetSettings()
  console.log(`[SSR] Settings loaded in ${Date.now() - pageStart}ms`)

  // Page renders immediately - preview will be fetched client-side
  // This avoids embedding the 1.25MB SVG in the initial HTML
  return (
    <WorksheetErrorBoundary>
      <AdditionWorksheetClient
        initialSettings={initialSettings}
        // No initial preview - will be fetched via API
      />
    </WorksheetErrorBoundary>
  )
}