Skip to content

1: Intro, Routes and Layouts #6

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: 00-base
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions app/awesome/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export default function Layout({ children }: { children: React.ReactNode }) {
return (
<div>
<div className="p-4 -m-4 bg-sky-900 text-white sm:flex sm:items-center sm:justify-between mb-8">
<h2 className="text-base font-semibold leading-6">
Awesome things happening!
</h2>
<div className="mt-3 flex sm:ml-4 sm:mt-0">
<span className="text-sm text-gray-200 italic">Booya!</span>
</div>
</div>
{children}
</div>
);
}
19 changes: 19 additions & 0 deletions app/awesome/mix/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
export const metadata = {
title: 'Awesome Mixes!',
};

export default function Page() {
return (
<>
<div className="border-b border-gray-200 pb-5 sm:flex sm:items-center sm:justify-between">
<h2 className="text-base font-semibold leading-6 text-gray-900">
Awesome Mixes!
</h2>
<div className="mt-3 flex sm:ml-4 sm:mt-0">
<span className="text-sm text-gray-500 italic">Awesome Sauce!</span>
</div>
</div>
<div className="h-8 rounded-lg shadow bg-lime-600" />
</>
);
}
19 changes: 19 additions & 0 deletions app/awesome/mix/vol-1/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
export const metadata = {
title: 'Awesome Mix Vol. 2',
};

export default function Page() {
return (
<>
<div className="border-b border-gray-200 pb-5 sm:flex sm:items-center sm:justify-between">
<h2 className="text-base font-semibold leading-6 text-gray-900">
Awesome Mix Vol. 2
</h2>
<div className="mt-3 flex sm:ml-4 sm:mt-0">
<span className="text-sm text-gray-500 italic">Awe yeah!</span>
</div>
</div>
<div className="h-8 rounded-lg shadow bg-rose-400" />
</>
);
}
19 changes: 19 additions & 0 deletions app/awesome/mix/vol-2/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
export const metadata = {
title: 'Awesome Mix Vol. 1',
};

export default function Page() {
return (
<>
<div className="border-b border-gray-200 pb-5 sm:flex sm:items-center sm:justify-between">
<h2 className="text-base font-semibold leading-6 text-gray-900">
Awesome Mix Vol. 1
</h2>
<div className="mt-3 flex sm:ml-4 sm:mt-0">
<span className="text-sm text-gray-500 italic">Woo</span>
</div>
</div>
<div className="h-8 rounded-lg shadow bg-fuchsia-500" />
</>
);
}
19 changes: 19 additions & 0 deletions app/awesome/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
export const metadata = {
title: 'I am awesome!',
};

export default function Home() {
return (
<>
<div className="border-b border-gray-200 pb-5 sm:flex sm:items-center sm:justify-between">
<h2 className="text-base font-semibold leading-6 text-gray-900">
I am awesome!
</h2>
<div className="mt-3 flex sm:ml-4 sm:mt-0">
<span className="text-sm text-gray-500 italic">Booya!</span>
</div>
</div>
<div className="h-8 rounded-lg shadow bg-orange-400" />
</>
);
}
19 changes: 19 additions & 0 deletions app/awesome/sauce/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
export const metadata = {
title: 'I am awesome sauce!',
};

export default function Page() {
return (
<>
<div className="border-b border-gray-200 pb-5 sm:flex sm:items-center sm:justify-between">
<h2 className="text-base font-semibold leading-6 text-gray-900">
I am awesome sauce!
</h2>
<div className="mt-3 flex sm:ml-4 sm:mt-0">
<span className="text-sm text-gray-500 italic">Awesome Sauce!</span>
</div>
</div>
<div className="h-8 rounded-lg shadow bg-purple-500" />
</>
);
}
19 changes: 19 additions & 0 deletions app/awesome/totally/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
export const metadata = {
title: `You're Totally Awesome!`,
};

export default function Page() {
return (
<>
<div className="border-b border-gray-200 pb-5 sm:flex sm:items-center sm:justify-between">
<h2 className="text-base font-semibold leading-6 text-gray-900">
{`You're Totally Awesome!`}
</h2>
<div className="mt-3 flex sm:ml-4 sm:mt-0">
<span className="text-sm text-gray-500 italic">Awesome Sauce!</span>
</div>
</div>
<div className="h-8 rounded-lg shadow bg-sky-600" />
</>
);
}
70 changes: 70 additions & 0 deletions app/breadcrumbs.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
'use client';

import Link from 'next/link';
import { useSelectedLayoutSegments } from 'next/navigation';
import { useMemo } from 'react';

export default function BreadCrumbs() {
const segments = useSelectedLayoutSegments();

const crumbs = useMemo(() => {
let curPath = '/';

return [
{
name: 'Home',
href: curPath,
current: segments.length === 0,
},
...segments
.filter(
(segment) => !segment.startsWith('(') && !segment.startsWith('[')
)
.map((segment, index) => {
curPath += segment;

return {
name: segment,
href: curPath,
current: index === segments.length - 1,
};
}),
];
}, [segments]);

console.log(segments);

return (
<nav className="flex mb-8 justify-end" aria-label="Breadcrumb">
<ol role="list" className="flex items-center space-x-4">
{crumbs.map((page, index) => (
<li key={page.name}>
<div className="flex items-center">
{index !== 0 && (
<svg
className="h-5 w-5 flex-shrink-0 text-gray-300"
fill="currentColor"
viewBox="0 0 20 20"
aria-hidden="true"
>
<path d="M5.555 17.776l8-16 .894.448-8 16-.894-.448z" />
</svg>
)}
<Link
href={page.href}
className={`ml-4 text-sm font-medium ${
page.current
? 'text-sky-700 hover:text-sky-800 drop-shadow-sm'
: 'text-gray-500 hover:text-gray-700'
}`}
aria-current={page.current ? 'page' : undefined}
>
{page.name}
</Link>
</div>
</li>
))}
</ol>
</nav>
);
}
22 changes: 22 additions & 0 deletions app/interactive/button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
'use client';

import { useState } from 'react';

export default function Button() {
const [isSpun, setIsSpun] = useState(false);

return (
<button
onClick={() => {
setIsSpun((spun) => !spun);
}}
className={`
${isSpun ? 'rotate-180' : ''}
transition-transform
rounded-md bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600
`}
>
Spin me!
</button>
);
}
25 changes: 25 additions & 0 deletions app/interactive/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// transition-transform

import Button from './button';

export const metadata = {
title: 'I am awesome!',
};

export default function Home() {
return (
<>
<div className="border-b border-gray-200 pb-5 sm:flex sm:items-center sm:justify-between">
<h2 className="text-base font-semibold leading-6 text-gray-900">
Interactivity
</h2>
<div className="mt-3 flex sm:ml-4 sm:mt-0">
<span className="text-sm text-gray-500 italic">Woo!</span>
</div>
</div>
<div className="p-8 flex justify-center">
<Button />
</div>
</>
);
}
30 changes: 30 additions & 0 deletions app/interactive/x-page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// This won't work!

export const metadata = {
title: 'I am awesome!',
};

export default function Home() {
return (
<>
<div className="border-b border-gray-200 pb-5 sm:flex sm:items-center sm:justify-between">
<h2 className="text-base font-semibold leading-6 text-gray-900">
Interactivity
</h2>
<div className="mt-3 flex sm:ml-4 sm:mt-0">
<span className="text-sm text-gray-500 italic">Woo!</span>
</div>
</div>
<div className="p-y-4 flex justify-end">
<button
onClick={() => {
// do something
}}
className="rounded-md bg-indigo-600 px-2.5 py-1.5 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
>
Spin me!
</button>
</div>
</>
);
}
52 changes: 48 additions & 4 deletions app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import Link from 'next/link';
import './globals.css';
import { Inter } from 'next/font/google';
import BreadCrumbs from './breadcrumbs';

const inter = Inter({ subsets: ['latin'] });

export const metadata = {
title: 'Create Next App',
description: 'Generated by create next app',
title: {
template: '%s | Next.js App Router Example',
default: 'Home Page',
},
description: `We're doing things!`,
};

export default function RootLayout({
Expand All @@ -17,15 +22,54 @@ export default function RootLayout({
<html lang="en">
<body className={inter.className}>
<div className="container p-4 mx-auto">
<header className="md:flex md:items-center md:justify-between mb-8">
<header className="md:flex md:items-center md:justify-between mb-2">
<div className="min-w-0 flex-1">
<h1 className="text-2xl font-bold leading-7 text-gray-900 sm:truncate sm:text-3xl sm:tracking-tight">
Next.js App Router Example
</h1>
</div>
<div className="mt-4 flex md:ml-4 md:mt-0">Hello!</div>
<div className="mt-4 flex md:ml-4 md:mt-0">
{new Date().toLocaleTimeString()}
</div>
</header>
<BreadCrumbs />
{children}
<footer className="mt-8 border-t border-t-sky-500 pt-8">
<nav className="prose">
<h3>Links!</h3>
<ul>
<li>
<Link href="/">Home</Link>
</li>
<li>
<Link href="/interactive">Interactive</Link>
</li>
<li>
<Link href="/awesome">Awesome</Link>
<ul>
<li>
<Link href="/awesome/sauce">Sauce</Link>
</li>
<li>
<Link href="/awesome/totally">Totally</Link>
</li>

<li>
<Link href="/awesome/mix">Mix</Link>
<ul>
<li>
<Link href="/awesome/mix/vol-1">Volume 1</Link>
</li>
<li>
<Link href="/awesome/mix/vol-2">Volume 2</Link>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</footer>
</div>
</body>
</html>
Expand Down
11 changes: 7 additions & 4 deletions app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
export default function Home() {
export default function Page() {
return (
<main>
<>
<div className="border-b border-gray-200 pb-5 sm:flex sm:items-center sm:justify-between">
<h2 className="text-base font-semibold leading-6 text-gray-900">
I am the home page!
</h2>
<div className="mt-3 flex sm:ml-4 sm:mt-0">We&apos;re home!</div>
<div className="mt-3 flex sm:ml-4 sm:mt-0">
<span className="text-sm text-gray-500 italic">We&apos;re home!</span>
</div>
</div>
</main>
<div className="h-8 rounded-lg shadow bg-red-400" />
</>
);
}
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
"lint": "next lint"
},
"dependencies": {
"@faker-js/faker": "^8.0.2",
"@tailwindcss/typography": "^0.5.9",
"@types/node": "20.2.5",
"@types/react": "18.2.7",
"@types/react-dom": "18.2.4",
Expand Down
Loading