Skip to content

Commit d926ab9

Browse files
committed
Adding react router demo app
1 parent b9a37c5 commit d926ab9

File tree

13 files changed

+3857
-80
lines changed

13 files changed

+3857
-80
lines changed

apps/demo-react-router/.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.DS_Store
2+
/node_modules/
3+
4+
# React Router
5+
/.react-router/
6+
/build/

apps/demo-react-router/README.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# Welcome to React Router!
2+
3+
A modern, production-ready template for building full-stack React applications using React Router.
4+
5+
[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/remix-run/react-router-templates/tree/main/default)
6+
7+
## Features
8+
9+
- 🚀 Server-side rendering
10+
- ⚡️ Hot Module Replacement (HMR)
11+
- 📦 Asset bundling and optimization
12+
- 🔄 Data loading and mutations
13+
- 🔒 TypeScript by default
14+
- 🎉 TailwindCSS for styling
15+
- 📖 [React Router docs](https://reactrouter.com/)
16+
17+
## Getting Started
18+
19+
### Installation
20+
21+
Install the dependencies:
22+
23+
```bash
24+
npm install
25+
```
26+
27+
### Development
28+
29+
Start the development server with HMR:
30+
31+
```bash
32+
npm run dev
33+
```
34+
35+
Your application will be available at `http://localhost:5173`.
36+
37+
## Building for Production
38+
39+
Create a production build:
40+
41+
```bash
42+
npm run build
43+
```
44+
45+
## Deployment
46+
47+
### Docker Deployment
48+
49+
To build and run using Docker:
50+
51+
```bash
52+
docker build -t my-app .
53+
54+
# Run the container
55+
docker run -p 3000:3000 my-app
56+
```
57+
58+
The containerized application can be deployed to any platform that supports Docker, including:
59+
60+
- AWS ECS
61+
- Google Cloud Run
62+
- Azure Container Apps
63+
- Digital Ocean App Platform
64+
- Fly.io
65+
- Railway
66+
67+
### DIY Deployment
68+
69+
If you're familiar with deploying Node applications, the built-in app server is production-ready.
70+
71+
Make sure to deploy the output of `npm run build`
72+
73+
```
74+
├── package.json
75+
├── package-lock.json (or pnpm-lock.yaml, or bun.lockb)
76+
├── build/
77+
│ ├── client/ # Static assets
78+
│ └── server/ # Server-side code
79+
```
80+
81+
## Styling
82+
83+
This template comes with [Tailwind CSS](https://tailwindcss.com/) already configured for a simple default starting experience. You can use whatever CSS framework you prefer.
84+
85+
---
86+
87+
Built with ❤️ using React Router.

apps/demo-react-router/app/app.css

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
@import "tailwindcss";
2+
3+
@theme {
4+
--font-sans: "Inter", ui-sans-serif, system-ui, sans-serif,
5+
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
6+
}
7+
8+
html,
9+
body {
10+
@apply bg-white dark:bg-gray-950;
11+
12+
@media (prefers-color-scheme: dark) {
13+
color-scheme: dark;
14+
}
15+
}

apps/demo-react-router/app/root.tsx

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import {
2+
isRouteErrorResponse,
3+
Links,
4+
Meta,
5+
Outlet,
6+
Scripts,
7+
ScrollRestoration,
8+
} from "react-router";
9+
10+
import type { Route } from "./+types/root";
11+
import "./app.css";
12+
13+
export const links: Route.LinksFunction = () => [
14+
{ rel: "preconnect", href: "https://fonts.googleapis.com" },
15+
{
16+
rel: "preconnect",
17+
href: "https://fonts.gstatic.com",
18+
crossOrigin: "anonymous",
19+
},
20+
{
21+
rel: "stylesheet",
22+
href: "https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap",
23+
},
24+
];
25+
26+
export function Layout({ children }: { children: React.ReactNode }) {
27+
return (
28+
<html lang="en">
29+
<head>
30+
<meta charSet="utf-8" />
31+
<meta name="viewport" content="width=device-width, initial-scale=1" />
32+
<Meta />
33+
<Links />
34+
</head>
35+
<body>
36+
{children}
37+
<ScrollRestoration />
38+
<Scripts />
39+
</body>
40+
</html>
41+
);
42+
}
43+
44+
export default function App() {
45+
return <Outlet />;
46+
}
47+
48+
export function ErrorBoundary({ error }: Route.ErrorBoundaryProps) {
49+
let message = "Oops!";
50+
let details = "An unexpected error occurred.";
51+
let stack: string | undefined;
52+
53+
if (isRouteErrorResponse(error)) {
54+
message = error.status === 404 ? "404" : "Error";
55+
details =
56+
error.status === 404
57+
? "The requested page could not be found."
58+
: error.statusText || details;
59+
} else if (import.meta.env.DEV && error && error instanceof Error) {
60+
details = error.message;
61+
stack = error.stack;
62+
}
63+
64+
return (
65+
<main className="pt-16 p-4 container mx-auto">
66+
<h1>{message}</h1>
67+
<p>{details}</p>
68+
{stack && (
69+
<pre className="w-full p-4 overflow-x-auto">
70+
<code>{stack}</code>
71+
</pre>
72+
)}
73+
</main>
74+
);
75+
}

apps/demo-react-router/app/routes.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { type RouteConfig, index } from "@react-router/dev/routes";
2+
3+
export default [index("routes/home.tsx")] satisfies RouteConfig;
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
import type { Route } from "./+types/home";
2+
import { useRef, useState } from 'react';
3+
import { usePdf } from '@mikecousins/react-pdf';
4+
import clsx from 'clsx';
5+
import { ArrowLeftCircleIcon, ArrowRightCircleIcon } from '@heroicons/react/24/solid';
6+
7+
export function meta({}: Route.MetaArgs) {
8+
return [
9+
{ title: "New React Router App" },
10+
{ name: "description", content: "Welcome to React Router!" },
11+
];
12+
}
13+
14+
export default function Home() {
15+
const [page, setPage] = useState(1);
16+
const canvasRef = useRef(null);
17+
18+
const { pdfDocument } = usePdf({
19+
file: 'udm_se_ds.pdf',
20+
page,
21+
canvasRef,
22+
scale: 0.4,
23+
});
24+
25+
const previousDisabled = page === 1;
26+
const nextDisabled = Boolean(page === pdfDocument?.numPages);
27+
28+
return (
29+
<div className="w-full flex flex-col">
30+
<div className="bg-gradient-to-r from-sky-800 to-indigo-800">
31+
<div className="container text-center py-12 mx-auto">
32+
<div className="text-4xl font-bold text-white">
33+
@mikecousins/react-pdf
34+
</div>
35+
<div className="text-xl text-gray-200 mt-4">
36+
The easiest way to render PDFs in React.{' '}
37+
<a
38+
href="https://bundlephobia.com/package/@mikecousins/react-pdf"
39+
className="text-blue-400"
40+
>
41+
Under 1kB in size.
42+
</a>{' '}
43+
Modern React hook architecture.
44+
</div>
45+
</div>
46+
</div>
47+
<div className="bg-gray-100">
48+
<div className="container text-center py-12 mx-auto flex">
49+
<div className="flex-1 flex flex-col justify-center">
50+
<div className="text-center">
51+
<button
52+
disabled={previousDisabled}
53+
onClick={() => setPage(page - 1)}
54+
className={clsx(previousDisabled && 'text-gray-300')}
55+
>
56+
<ArrowLeftCircleIcon className="h-12 w-12" />
57+
</button>
58+
</div>
59+
</div>
60+
<div>
61+
{!pdfDocument && <span>Loading...</span>}
62+
<canvas ref={canvasRef} />
63+
</div>
64+
<div className="flex-1 flex flex-col justify-center">
65+
<div className="text-center">
66+
<button
67+
disabled={nextDisabled}
68+
onClick={() => setPage(page + 1)}
69+
className={clsx(nextDisabled && 'text-gray-300')}
70+
>
71+
<ArrowRightCircleIcon className="h-12 w-12" />
72+
</button>
73+
</div>
74+
</div>
75+
</div>
76+
</div>
77+
<div className="bg-gray-200">
78+
<div className="container text-center py-12 mx-auto">
79+
<div className="flex flex-row gap-4 px-4 justify-center">
80+
<a
81+
href="https://www.npmjs.com/package/@mikecousins/react-pdf"
82+
className="text-blue-400 underline"
83+
>
84+
NPM
85+
</a>
86+
<a
87+
href="https://github.com/mikecousins/react-pdf-js"
88+
className="text-blue-400 underline"
89+
>
90+
Github
91+
</a>
92+
<a
93+
href="https://bundlephobia.com/package/@mikecousins/react-pdf"
94+
className="text-blue-400 underline"
95+
>
96+
Bundlephobia
97+
</a>
98+
<a
99+
href="https://opencollective.com/react-pdf-js"
100+
className="text-blue-400 underline"
101+
>
102+
Open Collective
103+
</a>
104+
</div>
105+
</div>
106+
</div>
107+
</div>
108+
);
109+
}

apps/demo-react-router/package.json

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
"name": "demo-react-router",
3+
"private": true,
4+
"type": "module",
5+
"scripts": {
6+
"build": "react-router build",
7+
"dev": "react-router dev",
8+
"start": "react-router-serve ./build/server/index.js",
9+
"typecheck": "react-router typegen && tsc"
10+
},
11+
"dependencies": {
12+
"@heroicons/react": "^2.2.0",
13+
"@mikecousins/react-pdf": "workspace:*",
14+
"@react-router/node": "^7.4.0",
15+
"@react-router/serve": "^7.4.0",
16+
"clsx": "^2.1.1",
17+
"isbot": "^5.1.17",
18+
"pdfjs-dist": "^5.0.375",
19+
"react": "^19.0.0",
20+
"react-dom": "^19.0.0",
21+
"react-router": "^7.4.0"
22+
},
23+
"devDependencies": {
24+
"@react-router/dev": "^7.4.0",
25+
"@tailwindcss/vite": "^4.0.0",
26+
"@types/node": "^20",
27+
"@types/react": "^19.0.1",
28+
"@types/react-dom": "^19.0.1",
29+
"react-router-devtools": "^1.1.0",
30+
"tailwindcss": "^4.0.0",
31+
"typescript": "^5.7.2",
32+
"vite": "^5.4.11",
33+
"vite-tsconfig-paths": "^5.1.4"
34+
}
35+
}
14.7 KB
Binary file not shown.
4.75 MB
Binary file not shown.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import type { Config } from "@react-router/dev/config";
2+
3+
export default {
4+
// Config options...
5+
// Server-side render by default, to enable SPA mode set this to `false`
6+
ssr: true,
7+
} satisfies Config;

0 commit comments

Comments
 (0)