hensei-web/app/[locale]/saved/page.tsx
Justin Edmund 2f757fc2a4 Fix Railway build errors by marking dynamic routes
- Add 'force-dynamic' export to API routes using cookies/searchParams
- Add 'force-dynamic' export to page components using dynamic features
- Create proper error pages without i18n complexity
- Fix "Dynamic server usage" errors during static generation

Routes now properly marked as dynamic will render at request time
instead of failing during build-time static generation.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-04 02:38:37 -07:00

96 lines
No EOL
2.6 KiB
TypeScript

import { Metadata } from 'next'
import { redirect } from 'next/navigation'
import { cookies } from 'next/headers'
import { getFavorites, getRaidGroups } from '~/app/lib/data'
import SavedPageClient from './SavedPageClient'
// Force dynamic rendering because we use cookies and searchParams
export const dynamic = 'force-dynamic'
// Metadata
export const metadata: Metadata = {
title: 'Your saved teams / granblue.team',
description: 'View and manage the teams you have saved to your account'
}
// Check if user is logged in server-side
function isAuthenticated() {
const cookieStore = cookies()
const accountCookie = cookieStore.get('account')
if (accountCookie) {
try {
const accountData = JSON.parse(accountCookie.value)
return accountData.token ? true : false
} catch (e) {
return false
}
}
return false
}
export default async function SavedPage({
searchParams
}: {
searchParams: { element?: string; raid?: string; recency?: string; page?: string }
}) {
// Redirect to teams page if not logged in
if (!isAuthenticated()) {
redirect('/teams')
}
try {
// Extract query parameters with type safety
const element = searchParams.element ? parseInt(searchParams.element, 10) : undefined;
const raid = searchParams.raid;
const recency = searchParams.recency;
// Parallel fetch data with Promise.all for better performance
const [savedTeamsData, raidGroupsData] = await Promise.all([
getFavorites(),
getRaidGroups()
])
// Filter teams by element/raid if needed
let filteredTeams = savedTeamsData.results || [];
if (element) {
filteredTeams = filteredTeams.filter((party: any) => party.element === element)
}
if (raid) {
filteredTeams = filteredTeams.filter((party: any) => party.raid?.id === raid)
}
// Prepare data for client component
const initialData = {
teams: filteredTeams,
raidGroups: raidGroupsData || [],
totalCount: savedTeamsData.results?.length || 0
}
return (
<div className="saved-page">
<SavedPageClient
initialData={initialData}
initialElement={element}
initialRaid={raid}
initialRecency={recency}
/>
</div>
)
} catch (error) {
console.error("Error fetching saved teams:", error)
// Provide empty data for error case
return (
<div className="saved-page">
<SavedPageClient
initialData={{ teams: [], raidGroups: [], totalCount: 0 }}
error={true}
/>
</div>
)
}
}