mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2026-02-05 16:35:18 -05:00
3.5 KiB
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- HomepageParks.tsx- Parks listingParkDetail.tsx- Individual park (36KB - complex)Rides.tsx- Rides listingRideDetail.tsx- Individual ride (54KB - most complex)Profile.tsx- User profile (51KB - complex)Search.tsx- Global searchAdminDashboard.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 |