Skip to content

Commit c33b520

Browse files
Refactor: use RR7 type generation (#904)
Co-authored-by: Kent C. Dodds <[email protected]>
1 parent c5ae4da commit c33b520

Some content is hidden

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

42 files changed

+250
-360
lines changed

app/root.tsx

+5-8
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
import { useRef } from 'react'
22
import {
33
data,
4-
type LoaderFunctionArgs,
5-
type HeadersFunction,
6-
type LinksFunction,
7-
type MetaFunction,
84
Form,
95
Link,
106
Links,
@@ -17,6 +13,7 @@ import {
1713
useSubmit,
1814
} from 'react-router'
1915
import { HoneypotProvider } from 'remix-utils/honeypot/react'
16+
import { type Route } from './+types/root.ts'
2017
import appleTouchIconAssetUrl from './assets/favicons/apple-touch-icon.png'
2118
import faviconAssetUrl from './assets/favicons/favicon.svg'
2219
import { GeneralErrorBoundary } from './components/error-boundary.tsx'
@@ -51,7 +48,7 @@ import { makeTimings, time } from './utils/timing.server.ts'
5148
import { getToast } from './utils/toast.server.ts'
5249
import { useOptionalUser, useUser } from './utils/user.ts'
5350

54-
export const links: LinksFunction = () => {
51+
export const links: Route.LinksFunction = () => {
5552
return [
5653
// Preload svg sprite as a resource to avoid render blocking
5754
{ rel: 'preload', href: iconsHref, as: 'image' },
@@ -71,14 +68,14 @@ export const links: LinksFunction = () => {
7168
].filter(Boolean)
7269
}
7370

74-
export const meta: MetaFunction<typeof loader> = ({ data }) => {
71+
export const meta: Route.MetaFunction = ({ data }) => {
7572
return [
7673
{ title: data ? 'Epic Notes' : 'Error | Epic Notes' },
7774
{ name: 'description', content: `Your own captain's log` },
7875
]
7976
}
8077

81-
export async function loader({ request }: LoaderFunctionArgs) {
78+
export async function loader({ request }: Route.LoaderArgs) {
8279
const timings = makeTimings('root loader')
8380
const userId = await time(() => getUserId(request), {
8481
timings,
@@ -142,7 +139,7 @@ export async function loader({ request }: LoaderFunctionArgs) {
142139
)
143140
}
144141

145-
export const headers: HeadersFunction = ({ loaderHeaders }) => {
142+
export const headers: Route.HeadersFunction = ({ loaderHeaders }) => {
146143
const headers = {
147144
'Server-Timing': loaderHeaders.get('Server-Timing') ?? '',
148145
}

app/routes/_auth+/auth.$provider.callback.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { redirect, type LoaderFunctionArgs } from 'react-router'
1+
import { redirect } from 'react-router'
22
import {
33
authenticator,
44
getSessionExpirationDate,
@@ -21,13 +21,14 @@ import {
2121
redirectWithToast,
2222
} from '#app/utils/toast.server.ts'
2323
import { verifySessionStorage } from '#app/utils/verification.server.ts'
24+
import { type Route } from './+types/auth.$provider.callback.ts'
2425
import { handleNewSession } from './login.server.ts'
2526
import { onboardingEmailSessionKey } from './onboarding.tsx'
2627
import { prefilledProfileKey, providerIdKey } from './onboarding_.$provider.tsx'
2728

2829
const destroyRedirectTo = { 'set-cookie': destroyRedirectToHeader }
2930

30-
export async function loader({ request, params }: LoaderFunctionArgs) {
31+
export async function loader({ request, params }: Route.LoaderArgs) {
3132
// this loader performs mutations, so we need to make sure we're on the
3233
// primary instance to avoid writing to a read-only replica
3334
await ensurePrimary()

app/routes/_auth+/auth_.$provider.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1-
import { redirect, type ActionFunctionArgs } from 'react-router'
1+
import { redirect } from 'react-router'
22
import { authenticator } from '#app/utils/auth.server.ts'
33
import { handleMockAction } from '#app/utils/connections.server.ts'
44
import { ProviderNameSchema } from '#app/utils/connections.tsx'
55
import { getReferrerRoute } from '#app/utils/misc.tsx'
66
import { getRedirectCookieHeader } from '#app/utils/redirect-cookie.server.ts'
7+
import { type Route } from './+types/auth_.$provider.ts'
78

89
export async function loader() {
910
return redirect('/login')
1011
}
1112

12-
export async function action({ request, params }: ActionFunctionArgs) {
13+
export async function action({ request, params }: Route.ActionArgs) {
1314
const providerName = ProviderNameSchema.parse(params.provider)
1415

1516
try {

app/routes/_auth+/forgot-password.tsx

+4-10
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,7 @@ import { getFormProps, getInputProps, useForm } from '@conform-to/react'
22
import { getZodConstraint, parseWithZod } from '@conform-to/zod'
33
import { type SEOHandle } from '@nasa-gcn/remix-seo'
44
import * as E from '@react-email/components'
5-
import {
6-
data,
7-
redirect,
8-
type ActionFunctionArgs,
9-
type MetaFunction,
10-
Link,
11-
useFetcher,
12-
} from 'react-router'
5+
import { data, redirect, Link, useFetcher } from 'react-router'
136
import { HoneypotInputs } from 'remix-utils/honeypot/react'
147
import { z } from 'zod'
158
import { GeneralErrorBoundary } from '#app/components/error-boundary.tsx'
@@ -19,6 +12,7 @@ import { prisma } from '#app/utils/db.server.ts'
1912
import { sendEmail } from '#app/utils/email.server.ts'
2013
import { checkHoneypot } from '#app/utils/honeypot.server.ts'
2114
import { EmailSchema, UsernameSchema } from '#app/utils/user-validation.ts'
15+
import { type Route } from './+types/forgot-password.ts'
2216
import { prepareVerification } from './verify.server.ts'
2317

2418
export const handle: SEOHandle = {
@@ -29,7 +23,7 @@ const ForgotPasswordSchema = z.object({
2923
usernameOrEmail: z.union([EmailSchema, UsernameSchema]),
3024
})
3125

32-
export async function action({ request }: ActionFunctionArgs) {
26+
export async function action({ request }: Route.ActionArgs) {
3327
const formData = await request.formData()
3428
checkHoneypot(formData)
3529
const submission = await parseWithZod(formData, {
@@ -119,7 +113,7 @@ function ForgotPasswordEmail({
119113
)
120114
}
121115

122-
export const meta: MetaFunction = () => {
116+
export const meta: Route.MetaFunction = () => {
123117
return [{ title: 'Password Recovery for Epic Notes' }]
124118
}
125119

app/routes/_auth+/login.tsx

+6-15
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,7 @@
11
import { getFormProps, getInputProps, useForm } from '@conform-to/react'
22
import { getZodConstraint, parseWithZod } from '@conform-to/zod'
33
import { type SEOHandle } from '@nasa-gcn/remix-seo'
4-
import {
5-
data,
6-
type ActionFunctionArgs,
7-
type LoaderFunctionArgs,
8-
type MetaFunction,
9-
Form,
10-
Link,
11-
useActionData,
12-
useSearchParams,
13-
} from 'react-router'
4+
import { data, Form, Link, useSearchParams } from 'react-router'
145
import { HoneypotInputs } from 'remix-utils/honeypot/react'
156
import { z } from 'zod'
167
import { GeneralErrorBoundary } from '#app/components/error-boundary.tsx'
@@ -25,6 +16,7 @@ import {
2516
import { checkHoneypot } from '#app/utils/honeypot.server.ts'
2617
import { useIsPending } from '#app/utils/misc.tsx'
2718
import { PasswordSchema, UsernameSchema } from '#app/utils/user-validation.ts'
19+
import { type Route } from './+types/login.ts'
2820
import { handleNewSession } from './login.server.ts'
2921

3022
export const handle: SEOHandle = {
@@ -38,12 +30,12 @@ const LoginFormSchema = z.object({
3830
remember: z.boolean().optional(),
3931
})
4032

41-
export async function loader({ request }: LoaderFunctionArgs) {
33+
export async function loader({ request }: Route.LoaderArgs) {
4234
await requireAnonymous(request)
4335
return {}
4436
}
4537

46-
export async function action({ request }: ActionFunctionArgs) {
38+
export async function action({ request }: Route.ActionArgs) {
4739
await requireAnonymous(request)
4840
const formData = await request.formData()
4941
checkHoneypot(formData)
@@ -83,8 +75,7 @@ export async function action({ request }: ActionFunctionArgs) {
8375
})
8476
}
8577

86-
export default function LoginPage() {
87-
const actionData = useActionData<typeof action>()
78+
export default function LoginPage({ actionData }: Route.ComponentProps) {
8879
const isPending = useIsPending()
8980
const [searchParams] = useSearchParams()
9081
const redirectTo = searchParams.get('redirectTo')
@@ -204,7 +195,7 @@ export default function LoginPage() {
204195
)
205196
}
206197

207-
export const meta: MetaFunction = () => {
198+
export const meta: Route.MetaFunction = () => {
208199
return [{ title: 'Login to Epic Notes' }]
209200
}
210201

app/routes/_auth+/logout.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
import { redirect, type ActionFunctionArgs } from 'react-router'
1+
import { redirect } from 'react-router'
22
import { logout } from '#app/utils/auth.server.ts'
3+
import { type Route } from './+types/logout.ts'
34

45
export async function loader() {
56
return redirect('/')
67
}
78

8-
export async function action({ request }: ActionFunctionArgs) {
9+
export async function action({ request }: Route.ActionArgs) {
910
return logout({ request })
1011
}

app/routes/_auth+/onboarding.tsx

+10-18
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,6 @@
11
import { getFormProps, getInputProps, useForm } from '@conform-to/react'
22
import { getZodConstraint, parseWithZod } from '@conform-to/zod'
3-
import {
4-
data,
5-
redirect,
6-
type LoaderFunctionArgs,
7-
type ActionFunctionArgs,
8-
type MetaFunction,
9-
Form,
10-
useActionData,
11-
useLoaderData,
12-
useSearchParams,
13-
} from 'react-router'
3+
import { data, redirect, Form, useSearchParams } from 'react-router'
144
import { HoneypotInputs } from 'remix-utils/honeypot/react'
155
import { safeRedirect } from 'remix-utils/safe-redirect'
166
import { z } from 'zod'
@@ -29,6 +19,7 @@ import {
2919
UsernameSchema,
3020
} from '#app/utils/user-validation.ts'
3121
import { verifySessionStorage } from '#app/utils/verification.server.ts'
22+
import { type Route } from './+types/onboarding.ts'
3223

3324
export const onboardingEmailSessionKey = 'onboardingEmail'
3425

@@ -57,12 +48,12 @@ async function requireOnboardingEmail(request: Request) {
5748
return email
5849
}
5950

60-
export async function loader({ request }: LoaderFunctionArgs) {
51+
export async function loader({ request }: Route.LoaderArgs) {
6152
const email = await requireOnboardingEmail(request)
6253
return { email }
6354
}
6455

65-
export async function action({ request }: ActionFunctionArgs) {
56+
export async function action({ request }: Route.ActionArgs) {
6657
const email = await requireOnboardingEmail(request)
6758
const formData = await request.formData()
6859
checkHoneypot(formData)
@@ -123,13 +114,14 @@ export async function action({ request }: ActionFunctionArgs) {
123114
)
124115
}
125116

126-
export const meta: MetaFunction = () => {
117+
export const meta: Route.MetaFunction = () => {
127118
return [{ title: 'Setup Epic Notes Account' }]
128119
}
129120

130-
export default function OnboardingRoute() {
131-
const data = useLoaderData<typeof loader>()
132-
const actionData = useActionData<typeof action>()
121+
export default function OnboardingRoute({
122+
loaderData,
123+
actionData,
124+
}: Route.ComponentProps) {
133125
const isPending = useIsPending()
134126
const [searchParams] = useSearchParams()
135127
const redirectTo = searchParams.get('redirectTo')
@@ -149,7 +141,7 @@ export default function OnboardingRoute() {
149141
<div className="container flex min-h-full flex-col justify-center pb-32 pt-20">
150142
<div className="mx-auto w-full max-w-lg">
151143
<div className="flex flex-col gap-3 text-center">
152-
<h1 className="text-h1">Welcome aboard {data.email}!</h1>
144+
<h1 className="text-h1">Welcome aboard {loaderData.email}!</h1>
153145
<p className="text-body-md text-muted-foreground">
154146
Please enter your details.
155147
</p>

app/routes/_auth+/onboarding_.$provider.tsx

+10-13
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,8 @@ import { getZodConstraint, parseWithZod } from '@conform-to/zod'
88
import {
99
redirect,
1010
data,
11-
type ActionFunctionArgs,
12-
type LoaderFunctionArgs,
13-
type MetaFunction,
1411
type Params,
1512
Form,
16-
useActionData,
17-
useLoaderData,
1813
useSearchParams,
1914
} from 'react-router'
2015
import { safeRedirect } from 'remix-utils/safe-redirect'
@@ -36,6 +31,7 @@ import { authSessionStorage } from '#app/utils/session.server.ts'
3631
import { redirectWithToast } from '#app/utils/toast.server.ts'
3732
import { NameSchema, UsernameSchema } from '#app/utils/user-validation.ts'
3833
import { verifySessionStorage } from '#app/utils/verification.server.ts'
34+
import { type Route } from './+types/onboarding_.$provider.ts'
3935
import { onboardingEmailSessionKey } from './onboarding'
4036

4137
export const providerIdKey = 'providerId'
@@ -80,7 +76,7 @@ async function requireData({
8076
}
8177
}
8278

83-
export async function loader({ request, params }: LoaderFunctionArgs) {
79+
export async function loader({ request, params }: Route.LoaderArgs) {
8480
const { email } = await requireData({ request, params })
8581
const connectionSession = await connectionSessionStorage.getSession(
8682
request.headers.get('cookie'),
@@ -104,7 +100,7 @@ export async function loader({ request, params }: LoaderFunctionArgs) {
104100
}
105101
}
106102

107-
export async function action({ request, params }: ActionFunctionArgs) {
103+
export async function action({ request, params }: Route.ActionArgs) {
108104
const { email, providerId, providerName } = await requireData({
109105
request,
110106
params,
@@ -172,21 +168,22 @@ export async function action({ request, params }: ActionFunctionArgs) {
172168
)
173169
}
174170

175-
export const meta: MetaFunction = () => {
171+
export const meta: Route.MetaFunction = () => {
176172
return [{ title: 'Setup Epic Notes Account' }]
177173
}
178174

179-
export default function OnboardingProviderRoute() {
180-
const data = useLoaderData<typeof loader>()
181-
const actionData = useActionData<typeof action>()
175+
export default function OnboardingProviderRoute({
176+
loaderData,
177+
actionData,
178+
}: Route.ComponentProps) {
182179
const isPending = useIsPending()
183180
const [searchParams] = useSearchParams()
184181
const redirectTo = searchParams.get('redirectTo')
185182

186183
const [form, fields] = useForm({
187184
id: 'onboarding-provider-form',
188185
constraint: getZodConstraint(SignupFormSchema),
189-
lastResult: actionData?.result ?? data.submission,
186+
lastResult: actionData?.result ?? loaderData.submission,
190187
onValidate({ formData }) {
191188
return parseWithZod(formData, { schema: SignupFormSchema })
192189
},
@@ -197,7 +194,7 @@ export default function OnboardingProviderRoute() {
197194
<div className="container flex min-h-full flex-col justify-center pb-32 pt-20">
198195
<div className="mx-auto w-full max-w-lg">
199196
<div className="flex flex-col gap-3 text-center">
200-
<h1 className="text-h1">Welcome aboard {data.email}!</h1>
197+
<h1 className="text-h1">Welcome aboard {loaderData.email}!</h1>
201198
<p className="text-body-md text-muted-foreground">
202199
Please enter your details.
203200
</p>

0 commit comments

Comments
 (0)