Skip to content

Commit d51fb91

Browse files
committed
✨ Init react app
1 parent a1338dc commit d51fb91

5 files changed

Lines changed: 159 additions & 0 deletions

File tree

index.html

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>React Router - Auth Example</title>
7+
</head>
8+
<body>
9+
<div id="root"></div>
10+
<script type="module" src="/src/main.tsx"></script>
11+
</body>
12+
</html>

src/App.tsx

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
import * as React from "react"
2+
import {
3+
Routes,
4+
Route,
5+
Link,
6+
useNavigate,
7+
Outlet,
8+
} from "react-router-dom"
9+
import { CLIENT_ID, REDIRECT_URI } from "./constants"
10+
import { usePasswordless } from "./usePasswordless"
11+
import { useQuery } from "./useQuery"
12+
13+
export default function App() {
14+
return (
15+
<Routes>
16+
<Route element={<Layout />}>
17+
<Route path="/" element={<PasswordlessLoginRequestCodePage />} />
18+
<Route path="/claim" element={<PasswordlessLoginClaimCodePage />} />
19+
</Route>
20+
</Routes>
21+
)
22+
}
23+
24+
function Layout() {
25+
return (
26+
<div>
27+
<ul>
28+
<li>
29+
<Link to="/">Public Page</Link>
30+
</li>
31+
<li>
32+
<Link to="/claim">Claim code</Link>
33+
</li>
34+
</ul>
35+
36+
<Outlet />
37+
</div>
38+
)
39+
}
40+
41+
function PasswordlessLoginRequestCodePage() {
42+
let navigate = useNavigate();
43+
const { requestLoginCode, loading } = usePasswordless(REDIRECT_URI, CLIENT_ID)
44+
45+
async function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
46+
event.preventDefault();
47+
48+
let formData = new FormData(event.currentTarget)
49+
let email = formData.get("email") as string
50+
51+
await requestLoginCode(email)
52+
53+
navigate('/claim')
54+
}
55+
56+
if (loading) return <p>Loading...</p>
57+
58+
return (
59+
<div>
60+
<form onSubmit={handleSubmit}>
61+
<label>
62+
Email: <input name="email" type="email" />
63+
</label>
64+
<button type="submit">Send code</button>
65+
</form>
66+
</div>
67+
);
68+
}
69+
70+
function PasswordlessLoginClaimCodePage() {
71+
const { code } = useQuery()
72+
const [tokens, setTokens] = React.useState()
73+
const { claimLoginCode, loading } = usePasswordless(REDIRECT_URI, CLIENT_ID)
74+
75+
async function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
76+
event.preventDefault();
77+
78+
let formData = new FormData(event.currentTarget);
79+
let code = formData.get("code") as string;
80+
81+
const res = await claimLoginCode(code)
82+
83+
setTokens(res)
84+
}
85+
86+
const tokenEffectFn = async () => {
87+
if (!code) return
88+
89+
const res = await claimLoginCode(code)
90+
91+
setTokens(res)
92+
}
93+
94+
// @ts-expect-error 2345
95+
React.useEffect(tokenEffectFn, [code])
96+
97+
if (loading) return <p>Loading...</p>
98+
99+
return (
100+
<div>
101+
{code && !tokens && (
102+
<p>Your code is: {code}</p>
103+
)}
104+
{!code && !tokens && (
105+
<form>
106+
<label>
107+
Code: <input name="code" type="text" />
108+
</label>
109+
<button type="submit">Claim code</button>
110+
</form>
111+
)}
112+
{tokens && (
113+
<pre>{JSON.stringify(tokens, null, 2)}</pre>
114+
)}
115+
</div>
116+
)
117+
}

src/constants.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export const BASE_ENDPOINT = ''
2+
export const CLIENT_ID = ''
3+
export const REDIRECT_URI = ''

src/index.css

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
body {
2+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
3+
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
4+
sans-serif;
5+
-webkit-font-smoothing: antialiased;
6+
-moz-osx-font-smoothing: grayscale;
7+
}
8+
9+
code {
10+
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
11+
monospace;
12+
}

src/main.tsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import React from "react"
2+
import ReactDOM from "react-dom"
3+
import { BrowserRouter } from "react-router-dom"
4+
5+
import "./index.css"
6+
import App from "./App"
7+
8+
ReactDOM.render(
9+
<React.StrictMode>
10+
<BrowserRouter>
11+
<App />
12+
</BrowserRouter>
13+
</React.StrictMode>,
14+
document.getElementById("root")
15+
)

0 commit comments

Comments
 (0)