Skip to content

Commit 87aa10b

Browse files
committed
wip
1 parent 6c840d9 commit 87aa10b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

85 files changed

+69676
-2871
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,5 @@ data.db
1313
# file as well, but since this is for a workshop
1414
# we're going to keep them around.
1515
# .env
16+
dist
17+
.wrangler

epicshop/epic-me/.gitignore

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
.DS_Store
2+
/node_modules/
3+
*.tsbuildinfo
4+
5+
# React Router
6+
/.react-router/
7+
/build/
8+
9+
# Cloudflare
10+
.mf
11+
.wrangler
12+
.dev.vars*
13+
14+
15+
!.dev.vars.example
16+
.env*
17+
!.env.example

epicshop/epic-me/.npmrc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
legacy-peer-deps=true
2+
registry=https://registry.npmjs.org/

epicshop/epic-me/.prettierignore

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
node_modules
2+
dist
3+
build
4+
.next
5+
.vercel
6+
.netlify
7+
coverage
8+
*.log
9+
.env*
10+
!.env.example
11+
package-lock.json
12+
yarn.lock
13+
pnpm-lock.yaml
14+
**/worker-configuration.d.ts

epicshop/epic-me/README.md

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# Welcome to React Router!
2+
3+
A modern, production-ready template for building full-stack React applications
4+
using React Router.
5+
6+
## Features
7+
8+
- 🚀 Server-side rendering
9+
- ⚡️ Hot Module Replacement (HMR)
10+
- 📦 Asset bundling and optimization
11+
- 🔄 Data loading and mutations
12+
- 🔒 TypeScript by default
13+
- 🎉 TailwindCSS for styling
14+
- 📖 [React Router docs](https://reactrouter.com/)
15+
16+
## Getting Started
17+
18+
### Installation
19+
20+
Install the dependencies:
21+
22+
```bash
23+
npm install
24+
```
25+
26+
### Development
27+
28+
Start the development server with HMR:
29+
30+
```bash
31+
npm run dev
32+
```
33+
34+
Your application will be available at `http://localhost:5173`.
35+
36+
> Note: Wrangler and the Cloudflare Vite plugin now support dotenv files for local development.
37+
> Create a `.env` in this app's root (alongside `wrangler.jsonc`) to define local `vars`.
38+
> For example:
39+
>
40+
> ```dotenv
41+
> TITLE="My Worker"
42+
> API_TOKEN="dev-token"
43+
> ```
44+
>
45+
> These will be available on `context.cloudflare.env.TITLE` / `env.API_TOKEN` in worker code during `wrangler dev`.
46+
> You can also add `.env.<environment>` files (e.g. `.env.staging`) and run `wrangler dev --env staging`.
47+
48+
## Previewing the Production Build
49+
50+
Preview the production build locally:
51+
52+
```bash
53+
npm run preview
54+
```
55+
56+
## Building for Production
57+
58+
Create a production build:
59+
60+
```bash
61+
npm run build
62+
```
63+
64+
## Deployment
65+
66+
Deployment is done using the Wrangler CLI.
67+
68+
To build and deploy directly to production:
69+
70+
```sh
71+
npm run deploy
72+
```
73+
74+
To deploy a preview URL:
75+
76+
```sh
77+
npx wrangler versions upload
78+
```
79+
80+
You can then promote a version to production after verification or roll it out
81+
progressively.
82+
83+
```sh
84+
npx wrangler versions deploy
85+
```
86+
87+
## Styling
88+
89+
This template comes with [Tailwind CSS](https://tailwindcss.com/) already
90+
configured for a simple default starting experience. You can use whatever CSS
91+
framework you prefer.
92+
93+
---
94+
95+
Built with ❤️ using React Router.

epicshop/epic-me/app/app.css

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
@import 'tailwindcss' source('.');
2+
3+
@theme {
4+
--font-sans:
5+
'Inter', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji',
6+
'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
7+
}
8+
9+
html,
10+
body {
11+
@apply bg-white dark:bg-gray-950;
12+
13+
@media (prefers-color-scheme: dark) {
14+
color-scheme: dark;
15+
}
16+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { isbot } from 'isbot'
2+
import { renderToReadableStream } from 'react-dom/server'
3+
import {
4+
type AppLoadContext,
5+
type EntryContext,
6+
ServerRouter,
7+
} from 'react-router'
8+
9+
export default async function handleRequest(
10+
request: Request,
11+
responseStatusCode: number,
12+
responseHeaders: Headers,
13+
routerContext: EntryContext,
14+
_loadContext: AppLoadContext,
15+
) {
16+
let shellRendered = false
17+
const userAgent = request.headers.get('user-agent')
18+
19+
const body = await renderToReadableStream(
20+
<ServerRouter context={routerContext} url={request.url} />,
21+
{
22+
onError(error: unknown) {
23+
responseStatusCode = 500
24+
// Log streaming rendering errors from inside the shell. Don't log
25+
// errors encountered during initial shell rendering since they'll
26+
// reject and get logged in handleDocumentRequest.
27+
if (shellRendered) {
28+
console.error(error)
29+
}
30+
},
31+
},
32+
)
33+
shellRendered = true
34+
35+
// Ensure requests from bots and SPA Mode renders wait for all content to load before responding
36+
// https://react.dev/reference/react-dom/server/renderToPipeableStream#waiting-for-all-content-to-load-for-crawlers-and-static-generation
37+
if ((userAgent && isbot(userAgent)) || routerContext.isSpaMode) {
38+
await body.allReady
39+
}
40+
41+
responseHeaders.set('Content-Type', 'text/html')
42+
return new Response(body, {
43+
headers: responseHeaders,
44+
status: responseStatusCode,
45+
})
46+
}

epicshop/epic-me/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="container mx-auto p-4 pt-16">
66+
<h1>{message}</h1>
67+
<p>{details}</p>
68+
{stack && (
69+
<pre className="w-full overflow-x-auto p-4">
70+
<code>{stack}</code>
71+
</pre>
72+
)}
73+
</main>
74+
)
75+
}

epicshop/epic-me/app/routes.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { type RouteConfig, index, route } from '@react-router/dev/routes'
2+
3+
export default [
4+
index('routes/index.tsx'),
5+
route('/authorize', 'routes/authorize.tsx'),
6+
route('/healthcheck', 'routes/healthcheck.tsx'),
7+
route('/db-api', 'routes/db-api.tsx'),
8+
route('/introspect', 'routes/introspect.tsx'),
9+
route('/test-auth', 'routes/test-auth.tsx'),
10+
] satisfies RouteConfig

0 commit comments

Comments
 (0)