Files
thrillwiki_django_no_react/.agent/workflows/migrate-page.md
pacnpal 1adba1b804 lol
2026-01-02 07:58:58 -05:00

3.5 KiB

description
description
Migrate a React page from thrillwiki-87 to Nuxt 4

Migrate Page Workflow

Port a React page from thrillwiki-87 (the authoritative source) to a Nuxt 4 page.

Step 1: Locate Source Page

Find the React page in thrillwiki-87:

/Volumes/macminissd/Projects/thrillwiki-87/src/pages/

Key pages:

  • Index.tsx - Homepage
  • Parks.tsx - Parks listing
  • ParkDetail.tsx - Individual park (36KB - complex)
  • Rides.tsx - Rides listing
  • RideDetail.tsx - Individual ride (54KB - most complex)
  • Profile.tsx - User profile (51KB - complex)
  • Search.tsx - Global search
  • AdminDashboard.tsx - Admin panel

Step 2: Analyze Page Structure

Extract from React page:

// Route params
const { id } = useParams()

// Data fetching
const { data, isLoading, error } = useQuery(...)

// SEO
// (usually react-helmet or similar)

// Page layout structure
return (
  <Layout>
    <Tabs>...</Tabs>
    <Content>...</Content>
  </Layout>
)

Step 3: Create Nuxt Page

Route Params

// React
const { parkSlug } = useParams()

<!-- Nuxt -->
<script setup lang="ts">
const route = useRoute()
const parkSlug = route.params.park_slug as string
</script>

Data Fetching

// React (React Query)
const { data, isLoading } = useQuery(['park', id], () => fetchPark(id))

<!-- Nuxt -->
<script setup lang="ts">
const { data, pending } = await useAsyncData(
  `park-${parkSlug}`,
  () => useParksApi().getPark(parkSlug)
)
</script>

SEO Meta

// React (Helmet)
<Helmet>
  <title>{park.name} | ThrillWiki</title>
</Helmet>

<!-- Nuxt -->
<script setup lang="ts">
useSeoMeta({
  title: () => `${data.value?.name} | ThrillWiki`,
  description: () => data.value?.description
})
</script>

Page Meta

<script setup lang="ts">
definePageMeta({
  middleware: ['auth'],  // if authentication required
  layout: 'default'
})
</script>

Step 4: Port Page Sections

Common patterns:

Tabs Structure

// React
<Tabs defaultValue="overview">
  <TabsList>
    <TabsTrigger value="overview">Overview</TabsTrigger>
  </TabsList>
  <TabsContent value="overview">...</TabsContent>
</Tabs>

<!-- Nuxt -->
<UTabs :items="tabs" v-model="activeTab">
  <template #default="{ item }">
    <component :is="item.component" v-bind="item.props" />
  </template>
</UTabs>

Loading States

// React
{isLoading ? <Skeleton /> : <Content />}

<!-- Nuxt -->
<template>
  <div v-if="pending">
    <USkeleton class="h-48" />
  </div>
  <div v-else-if="data">
    <!-- Content -->
  </div>
</template>

Step 5: Target Location

Nuxt pages use file-based routing:

React Route Nuxt File Path
/parks pages/parks/index.vue
/parks/:slug pages/parks/[park_slug]/index.vue
/parks/:slug/rides/:ride pages/parks/[park_slug]/rides/[ride_slug].vue
/manufacturers/:id pages/manufacturers/[slug].vue

Step 6: Verify Feature Parity

Compare source page with target:

  • All tabs/sections present
  • All data displayed
  • All actions work (edit, delete, etc.)
  • Responsive layout matches
  • Loading states present
  • Error handling works
  • SEO meta correct

Reference: Page Complexity

Page Source Size Priority
RideDetail.tsx 54KB High
Profile.tsx 51KB High
AdminSettings.tsx 44KB Medium
ParkDetail.tsx 36KB High
Auth.tsx 29KB Medium
Parks.tsx 22KB High
Rides.tsx 20KB High