Complete "Layout Routes".

This commit is contained in:
2025-04-01 12:17:04 +02:00
parent 276bea81b0
commit 298d25a579
7 changed files with 112 additions and 45 deletions

View File

@@ -0,0 +1,49 @@
import React, { Suspense } from "react";
import Link from "next/link";
import Form from "next/form";
import ContactList from "./sidebar-contacts";
import { getContacts } from "@/app/data";
import type { Metadata } from "next";
export default function SidebarRootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
const contacts = getContacts();
return (
<>
<div id="sidebar">
<h1>
<Link href="/about">React Router Contacts</Link>
</h1>
<div>
<Form id="search-form" role="search" action="." formMethod="get">
<input
aria-label="Search contacts"
id="q"
name="q"
placeholder="Search"
type="search"/>
<div
aria-hidden
hidden={true}
id="search-spinner"/>
</Form>
<Form action="." formMethod="post">
<button type="submit">New</button>
</Form>
</div>
<nav>
<Suspense fallback={<div>Loading...</div>}>
<ContactList contacts={contacts}/>
</Suspense>
</nav>
</div>
<div id={'detail'}>
{children}
</div>
</>
);
}

View File

@@ -0,0 +1,15 @@
import React from "react";
export default function Home() {
return (
<p id="index-page">
This is a demo for React Router.
<br/>
Check out{" "}
<a href="https://reactrouter.com">
the docs at reactrouter.com
</a>
.
</p>
);
}

45
src/app/about/page.tsx Normal file
View File

@@ -0,0 +1,45 @@
import Link from "next/link";
export default function About() {
return (
<div id="about">
<Link href="/"> Go to demo</Link>
<h1>About React Router Contacts</h1>
<div>
<p>
This is a demo application showing off some of the
powerful features of React Router, including
dynamic routing, nested routes, loaders, actions,
and more.
</p>
<h2>Features</h2>
<p>
Explore the demo to see how React Router handles:
</p>
<ul>
<li>
Data loading and mutations with loaders and
actions
</li>
<li>
Nested routing with parent/child relationships
</li>
<li>URL-based routing with dynamic segments</li>
<li>Pending and optimistic UI</li>
</ul>
<h2>Learn More</h2>
<p>
Check out the official documentation at{" "}
<a href="https://reactrouter.com">
reactrouter.com
</a>{" "}
to learn more about building great web
applications with React Router.
</p>
</div>
</div>
);
}

View File

@@ -1,10 +1,7 @@
import React from "react";
import type { Metadata } from "next";
import React, { Suspense } from "react";
import "./globals.css";
import Form from "next/form";
import ContactList from "@/app/sidebar-contacts";
import { getContacts } from "@/app/data";
export const metadata: Metadata = {
title: "Next.js Address Book",
@@ -16,42 +13,11 @@ export default function RootLayout({
}: Readonly<{
children: React.ReactNode;
}>) {
const contacts = getContacts();
return (
<html lang="en">
<body>
<div id="sidebar">
<h1>React Router Contacts</h1>
<div>
<Form id="search-form" role="search" action="." formMethod="get">
<input
aria-label="Search contacts"
id="q"
name="q"
placeholder="Search"
type="search"
/>
<div
aria-hidden
hidden={true}
id="search-spinner"
/>
</Form>
<Form action="." formMethod="post">
<button type="submit">New</button>
</Form>
</div>
<nav>
<Suspense fallback={<div>Loading...</div>}>
<ContactList contacts={contacts}/>
</Suspense>
</nav>
</div>
<div id={'detail'}>
{children}
</div>
{children}
</body>
</html>
);
}
}

View File

@@ -1,8 +0,0 @@
import Form from "next/form";
import React from "react";
export default function Home() {
return (
<div></div>
);
}