From c74f274fba4c416f11755ecb1b43dbc8ec65b4c0 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 14 Nov 2025 12:09:51 +0000 Subject: [PATCH 1/3] Convert Next.js application to use App Router - Created app directory with new root layout combining _app and _document - Converted all pages from pages/ to app/ directory structure - Updated routing from next/router to next/navigation hooks - Marked client components with 'use client' directive - Split gateway.ts to handle client/server concerns separately - Converted getStaticProps/getStaticPaths to Server Components and generateStaticParams - Updated all dynamic routes to new [param] folder structure - Fixed type issues with Post and Author types - Updated authentication and navigation components for App Router All routes successfully converted: - Home page (/) - Blog pages (/posts, /posts/[slug]) - Auth pages (/signin, /signup, /signup-confirm) - Protected pages (/admin, /profile) - Feature pages (/todomvc, /bookings-auto, /bookings-custom, /shadcn-ui, /features) - Error pages (/forbidden) Note: Static export has a runtime issue during build that needs investigation --- .../{pages/admin.tsx => app/admin/page.tsx} | 2 + .../bookings-auto/page.tsx} | 9 +- .../bookings-custom/page.tsx} | 11 +- .../features.mdx => app/features/page.mdx} | 0 .../forbidden.tsx => app/forbidden/page.tsx} | 7 +- MyApp.Client/app/layout.tsx | 42 +++ MyApp.Client/app/page.tsx | 71 ++++ MyApp.Client/app/posts/[slug]/page.tsx | 73 ++++ MyApp.Client/app/posts/page.tsx | 38 +++ .../profile.tsx => app/profile/page.tsx} | 4 +- MyApp.Client/app/providers.tsx | 23 ++ MyApp.Client/app/shadcn-ui/page.tsx | 233 +++++++++++++ .../{pages/signin.tsx => app/signin/page.tsx} | 12 +- .../signup-confirm/page.tsx} | 10 +- .../{pages/signup.tsx => app/signup/page.tsx} | 14 +- .../todomvc.tsx => app/todomvc/page.tsx} | 10 +- MyApp.Client/components/builtin-uis.tsx | 2 + MyApp.Client/components/getting-started.tsx | 2 + MyApp.Client/components/intro.tsx | 4 +- MyApp.Client/components/nav.tsx | 13 +- MyApp.Client/components/shell-command.tsx | 2 + MyApp.Client/lib/auth.tsx | 10 +- MyApp.Client/lib/gateway.client.ts | 23 ++ MyApp.Client/lib/gateway.ts | 36 +- MyApp.Client/next-env.d.ts | 2 +- MyApp.Client/next.config.mjs | 2 - MyApp.Client/npm-shrinkwrap.json | 33 +- MyApp.Client/pages/_app.tsx | 24 -- MyApp.Client/pages/_document.tsx | 32 -- MyApp.Client/pages/index.tsx | 85 ----- MyApp.Client/pages/posts.tsx | 41 --- MyApp.Client/pages/posts/[slug].tsx | 98 ------ MyApp.Client/pages/shadcn-ui.tsx | 317 ------------------ MyApp.Client/tsconfig.json | 15 +- 34 files changed, 611 insertions(+), 689 deletions(-) rename MyApp.Client/{pages/admin.tsx => app/admin/page.tsx} (98%) rename MyApp.Client/{pages/bookings-auto.tsx => app/bookings-auto/page.tsx} (88%) rename MyApp.Client/{pages/bookings-custom.tsx => app/bookings-custom/page.tsx} (96%) rename MyApp.Client/{pages/features.mdx => app/features/page.mdx} (100%) rename MyApp.Client/{pages/forbidden.tsx => app/forbidden/page.tsx} (86%) create mode 100644 MyApp.Client/app/layout.tsx create mode 100644 MyApp.Client/app/page.tsx create mode 100644 MyApp.Client/app/posts/[slug]/page.tsx create mode 100644 MyApp.Client/app/posts/page.tsx rename MyApp.Client/{pages/profile.tsx => app/profile/page.tsx} (95%) create mode 100644 MyApp.Client/app/providers.tsx create mode 100644 MyApp.Client/app/shadcn-ui/page.tsx rename MyApp.Client/{pages/signin.tsx => app/signin/page.tsx} (92%) rename MyApp.Client/{pages/signup-confirm.tsx => app/signup-confirm/page.tsx} (73%) rename MyApp.Client/{pages/signup.tsx => app/signup/page.tsx} (92%) rename MyApp.Client/{pages/todomvc.tsx => app/todomvc/page.tsx} (98%) create mode 100644 MyApp.Client/lib/gateway.client.ts delete mode 100644 MyApp.Client/pages/_app.tsx delete mode 100644 MyApp.Client/pages/_document.tsx delete mode 100644 MyApp.Client/pages/index.tsx delete mode 100644 MyApp.Client/pages/posts.tsx delete mode 100644 MyApp.Client/pages/posts/[slug].tsx delete mode 100644 MyApp.Client/pages/shadcn-ui.tsx diff --git a/MyApp.Client/pages/admin.tsx b/MyApp.Client/app/admin/page.tsx similarity index 98% rename from MyApp.Client/pages/admin.tsx rename to MyApp.Client/app/admin/page.tsx index d5cd8ed..da6be96 100644 --- a/MyApp.Client/pages/admin.tsx +++ b/MyApp.Client/app/admin/page.tsx @@ -1,3 +1,5 @@ +'use client' + import { SecondaryButton } from "@servicestack/react" import Page from "@/components/layout-page" import { ValidateAuth, appAuth } from "@/lib/auth" diff --git a/MyApp.Client/pages/bookings-auto.tsx b/MyApp.Client/app/bookings-auto/page.tsx similarity index 88% rename from MyApp.Client/pages/bookings-auto.tsx rename to MyApp.Client/app/bookings-auto/page.tsx index 01ba69c..18854d5 100644 --- a/MyApp.Client/pages/bookings-auto.tsx +++ b/MyApp.Client/app/bookings-auto/page.tsx @@ -1,12 +1,12 @@ +'use client' + import Link from "next/link" import { AutoQueryGrid } from "@servicestack/react" import Page from "@/components/layout-page" import { ValidateAuth } from "@/lib/auth" import SrcPage from "@/components/src-page" -function Index() { - - +function BookingsAuto() { return (
@@ -26,5 +26,4 @@ function Index() { ) } -export default ValidateAuth(Index, {role: 'Employee'}) - +export default ValidateAuth(BookingsAuto, {role: 'Employee'}) diff --git a/MyApp.Client/pages/bookings-custom.tsx b/MyApp.Client/app/bookings-custom/page.tsx similarity index 96% rename from MyApp.Client/pages/bookings-custom.tsx rename to MyApp.Client/app/bookings-custom/page.tsx index 128df9b..cc724ec 100644 --- a/MyApp.Client/pages/bookings-custom.tsx +++ b/MyApp.Client/app/bookings-custom/page.tsx @@ -1,11 +1,13 @@ -import { useState, useEffect } from "react" +'use client' + +import { useState } from "react" import Link from "next/link" import { useFormatters, AutoQueryGrid, TextLink, PreviewFormat, AutoEditForm, Icon } from "@servicestack/react" import Page from "@/components/layout-page" import { ValidateAuth } from "@/lib/auth" import SrcPage from "@/components/src-page" -function Index() { +function BookingsCustom() { const { currency } = useFormatters() const [coupon, setCoupon] = useState(null) @@ -76,7 +78,7 @@ function Index() { onSave={() => setCoupon(null)} /> )} - +
@@ -85,5 +87,4 @@ function Index() { ) } -export default ValidateAuth(Index, {role: 'Employee'}) - +export default ValidateAuth(BookingsCustom, {role: 'Employee'}) diff --git a/MyApp.Client/pages/features.mdx b/MyApp.Client/app/features/page.mdx similarity index 100% rename from MyApp.Client/pages/features.mdx rename to MyApp.Client/app/features/page.mdx diff --git a/MyApp.Client/pages/forbidden.tsx b/MyApp.Client/app/forbidden/page.tsx similarity index 86% rename from MyApp.Client/pages/forbidden.tsx rename to MyApp.Client/app/forbidden/page.tsx index 16c6a8a..ebb16d6 100644 --- a/MyApp.Client/pages/forbidden.tsx +++ b/MyApp.Client/app/forbidden/page.tsx @@ -1,5 +1,5 @@ -export default () => { - return (<> +export default function Forbidden() { + return (

403

@@ -7,7 +7,6 @@ export default () => {

You do not have access to this page.

-
- + ) } diff --git a/MyApp.Client/app/layout.tsx b/MyApp.Client/app/layout.tsx new file mode 100644 index 0000000..984b5e8 --- /dev/null +++ b/MyApp.Client/app/layout.tsx @@ -0,0 +1,42 @@ +import "../styles/index.css" +import "../styles/main.css" +import "../styles/prism-dark-blue.css" +import type { Metadata } from 'next' +import Providers from './providers' + +export const metadata: Metadata = { + title: 'Next.js Example', + description: 'Next.js App Router Example', +} + +export default function RootLayout({ + children, +}: { + children: React.ReactNode +}) { + return ( + + + +