diff --git a/basic/app/routes/demos/actions.tsx b/basic/app/routes/demos/actions.tsx index bc5117e6..b0d216bd 100644 --- a/basic/app/routes/demos/actions.tsx +++ b/basic/app/routes/demos/actions.tsx @@ -1,4 +1,4 @@ -import type { ActionFunction, MetaFunction } from "@remix-run/node"; +import type { ActionArgs, MetaFunction } from "@remix-run/node"; import { json, redirect } from "@remix-run/node"; import { Form, useActionData } from "@remix-run/react"; import { useEffect, useRef } from "react"; @@ -10,7 +10,7 @@ export const meta: MetaFunction = () => ({ // When your form sends a POST, the action is called on the server. // - https://remix.run/api/conventions#action // - https://remix.run/guides/data-updates -export const action: ActionFunction = async ({ request }) => { +export const action = async ({ request }: ActionArgs) => { const formData = await request.formData(); const answer = formData.get("answer"); @@ -35,7 +35,7 @@ export const action: ActionFunction = async ({ request }) => { export default function ActionsDemo() { // https://remix.run/api/remix#useactiondata - const actionMessage = useActionData(); + const actionMessage = useActionData(); const answerRef = useRef(null); // This form works without JavaScript, but when we have JavaScript we can make diff --git a/basic/app/routes/demos/params/$id.tsx b/basic/app/routes/demos/params/$id.tsx index 10b09e44..86ca8d70 100644 --- a/basic/app/routes/demos/params/$id.tsx +++ b/basic/app/routes/demos/params/$id.tsx @@ -1,11 +1,11 @@ -import type { LoaderFunction, MetaFunction } from "@remix-run/node"; +import type { LoaderArgs, MetaFunction } from "@remix-run/node"; import { json } from "@remix-run/node"; import { useCatch, useLoaderData } from "@remix-run/react"; // The `$` in route filenames becomes a pattern that's parsed from the URL and // passed to your loaders so you can look up data. // - https://remix.run/api/conventions#loader-params -export const loader: LoaderFunction = async ({ params }) => { +export const loader = async ({ params }: LoaderArgs) => { // pretend like we're using params.id to look something up in the db if (params.id === "this-record-does-not-exist") { @@ -39,7 +39,7 @@ export const loader: LoaderFunction = async ({ params }) => { }; export default function ParamDemo() { - const data = useLoaderData(); + const data = useLoaderData(); return (

The param is {data.param} diff --git a/basic/app/routes/index.tsx b/basic/app/routes/index.tsx index 7f7043af..8b4c64f6 100644 --- a/basic/app/routes/index.tsx +++ b/basic/app/routes/index.tsx @@ -1,4 +1,4 @@ -import type { LoaderFunction, MetaFunction } from "@remix-run/node"; +import type { MetaFunction } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Link, useLoaderData } from "@remix-run/react"; @@ -11,7 +11,7 @@ type IndexData = { // you can connect to a database or run any server side code you want right next // to the component that renders it. // https://remix.run/api/conventions#loader -export const loader: LoaderFunction = async () => { +export const loader = async () => { const data: IndexData = { resources: [ { @@ -48,16 +48,14 @@ export const loader: LoaderFunction = async () => { }; // https://remix.run/api/conventions#meta -export const meta: MetaFunction = () => { - return { - title: "Remix Starter", - description: "Welcome to remix!", - }; -}; +export const meta: MetaFunction = () => ({ + title: "Remix Starter", + description: "Welcome to remix!", +}); // https://remix.run/guides/routing#index-routes export default function Index() { - const data = useLoaderData(); + const data = useLoaderData(); return (
diff --git a/bullmq-task-queue/app/routes/index.tsx b/bullmq-task-queue/app/routes/index.tsx index 1e75201f..0ceeb2ea 100644 --- a/bullmq-task-queue/app/routes/index.tsx +++ b/bullmq-task-queue/app/routes/index.tsx @@ -1,10 +1,10 @@ -import type { ActionFunction } from "@remix-run/node"; +import type { ActionArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Form, useActionData, useTransition } from "@remix-run/react"; import { queue } from "~/queues/notifier.server"; -export const action: ActionFunction = async ({ request }) => { +export const action = async ({ request }: ActionArgs) => { const formData = await request.formData(); const email = formData.get("email"); @@ -23,7 +23,7 @@ export const action: ActionFunction = async ({ request }) => { }; export default function Index() { - const actionMessage = useActionData(); + const actionMessage = useActionData(); const transition = useTransition(); return ( diff --git a/catch-boundary/app/routes/index.tsx b/catch-boundary/app/routes/index.tsx index 6adeb529..5a5443af 100644 --- a/catch-boundary/app/routes/index.tsx +++ b/catch-boundary/app/routes/index.tsx @@ -1,4 +1,3 @@ -import type { LoaderFunction } from "@remix-run/node"; import { redirect } from "@remix-run/node"; -export const loader: LoaderFunction = async () => redirect("/users"); +export const loader = async () => redirect("/users"); diff --git a/catch-boundary/app/routes/users.tsx b/catch-boundary/app/routes/users.tsx index daee444a..b6f0cf22 100644 --- a/catch-boundary/app/routes/users.tsx +++ b/catch-boundary/app/routes/users.tsx @@ -1,25 +1,20 @@ -import type { LoaderFunction, MetaFunction } from "@remix-run/node"; +import type { MetaFunction } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Link, Outlet, useLoaderData } from "@remix-run/react"; -import type { User } from "~/data.server"; import { getUsers } from "~/data.server"; -type LoaderData = { - users: Array; -}; - export const meta: MetaFunction = () => { return { title: "Users" }; }; -export const loader: LoaderFunction = async () => { +export const loader = async () => { const users = getUsers(); - return json({ users }); + return json({ users }); }; export default function Users() { - const { users } = useLoaderData(); + const { users } = useLoaderData(); return (
diff --git a/catch-boundary/app/routes/users/$userId.tsx b/catch-boundary/app/routes/users/$userId.tsx index c876f309..b043de80 100644 --- a/catch-boundary/app/routes/users/$userId.tsx +++ b/catch-boundary/app/routes/users/$userId.tsx @@ -1,15 +1,10 @@ -import type { LoaderFunction, MetaFunction } from "@remix-run/node"; +import type { LoaderArgs, MetaFunction } from "@remix-run/node"; import { json } from "@remix-run/node"; import { useCatch, useLoaderData, useParams } from "@remix-run/react"; -import type { User as UserType } from "~/data.server"; import { getUsers } from "~/data.server"; -interface LoaderData { - user: UserType; -} - -export const meta: MetaFunction = ({ data }: { data: LoaderData | null }) => { +export const meta: MetaFunction = ({ data }) => { // When the response is thrown for a missing user, the data will be the // thrown response. if (!data || !data.user) { @@ -18,7 +13,7 @@ export const meta: MetaFunction = ({ data }: { data: LoaderData | null }) => { return { title: data.user.name }; }; -export const loader: LoaderFunction = async ({ params }) => { +export const loader = async ({ params }: LoaderArgs) => { const userId = params.userId; const users = getUsers(); @@ -29,11 +24,11 @@ export const loader: LoaderFunction = async ({ params }) => { throw new Response("Not Found", { status: 404 }); } - return json({ user }); + return json({ user }); }; export default function User() { - const { user } = useLoaderData(); + const { user } = useLoaderData(); return
Hi there {user.name}!
; } diff --git a/client-side-validation/app/root.tsx b/client-side-validation/app/root.tsx index 5296fe06..0175cb8f 100644 --- a/client-side-validation/app/root.tsx +++ b/client-side-validation/app/root.tsx @@ -1,9 +1,4 @@ -import type { - ActionFunction, - LinksFunction, - LoaderFunction, - MetaFunction, -} from "@remix-run/node"; +import type { ActionArgs, LinksFunction, MetaFunction } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Links, @@ -27,7 +22,7 @@ export const meta: MetaFunction = () => ({ viewport: "width=device-width,initial-scale=1", }); -export const action: ActionFunction = async ({ request }) => { +export const action = async ({ request }: ActionArgs) => { const form = await request.formData(); const message = `Successfully submitted data: - Required text: ${form.get("required-text")} @@ -42,12 +37,7 @@ export const action: ActionFunction = async ({ request }) => { return json({ message }, { status: 200 }); }; -type LoaderData = { - todayString: string; - tomorrowString: string; -}; - -export const loader: LoaderFunction = async () => { +export const loader = async () => { const date = new Date(); // today string in "YYYY-MM-DD" format @@ -66,8 +56,8 @@ export const loader: LoaderFunction = async () => { }; export default function App() { - const actionData = useActionData(); - const data = useLoaderData(); + const actionData = useActionData(); + const data = useLoaderData(); return ( diff --git a/collected-notes/app/routes/$slug.tsx b/collected-notes/app/routes/$slug.tsx index 8e5f7068..67189438 100644 --- a/collected-notes/app/routes/$slug.tsx +++ b/collected-notes/app/routes/$slug.tsx @@ -1,23 +1,18 @@ -import type { LoaderFunction } from "@remix-run/node"; +import type { LoaderArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { useLoaderData } from "@remix-run/react"; -import type { HTML } from "collected-notes"; import { cn, sitePath } from "~/cn.server"; -type LoaderData = { - body: HTML; -}; - -export const loader: LoaderFunction = async ({ params }) => { +export const loader = async ({ params }: LoaderArgs) => { const slug = params.slug; if (typeof slug !== "string") throw new Error("Missing slug"); const { body } = await cn.body(sitePath, slug); - return json({ body }); + return json({ body }); }; export default function Screen() { - const { body } = useLoaderData(); + const { body } = useLoaderData(); return (
diff --git a/collected-notes/app/routes/index.tsx b/collected-notes/app/routes/index.tsx index 087871e1..fdd593e1 100644 --- a/collected-notes/app/routes/index.tsx +++ b/collected-notes/app/routes/index.tsx @@ -1,16 +1,10 @@ -import type { LoaderFunction } from "@remix-run/node"; +import type { LoaderArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Form, Link, useLoaderData, useSearchParams } from "@remix-run/react"; -import type { Note, Site } from "collected-notes"; import { cn, sitePath } from "~/cn.server"; -type LoaderData = { - site: Site; - notes: Note[]; -}; - -export const loader: LoaderFunction = async ({ request }) => { +export const loader = async ({ request }: LoaderArgs) => { const url = new URL(request.url); const term = url.searchParams.get("term") || ""; const page = Number(url.searchParams.get("page") || "1"); @@ -24,11 +18,11 @@ export const loader: LoaderFunction = async ({ request }) => { cn.site(sitePath), ]); - return json({ notes, site }); + return json({ notes, site }); }; export default function Screen() { - const { site, notes } = useLoaderData(); + const { site, notes } = useLoaderData(); const [params] = useSearchParams(); const term = params.get("term") || ""; const page = Number(params.get("page") || "1"); diff --git a/combobox-resource-route/app/routes/lang-search.tsx b/combobox-resource-route/app/routes/lang-search.tsx index 3d1932a6..50d3a203 100644 --- a/combobox-resource-route/app/routes/lang-search.tsx +++ b/combobox-resource-route/app/routes/lang-search.tsx @@ -1,4 +1,4 @@ -import type { LoaderFunction } from "@remix-run/node"; +import type { LoaderArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { searchLangs } from "~/models/langs"; @@ -8,7 +8,7 @@ import { searchLangs } from "~/models/langs"; * set of languages as the user types. It's called a Resource Route because it * doesn't export a component. You might think of it as an "API Route". */ -export const loader: LoaderFunction = async ({ request }) => { +export const loader = async ({ request }: LoaderArgs) => { // First get what the user is searching for by creating a URL: // https://developer.mozilla.org/en-US/docs/Web/API/URL // https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams diff --git a/dark-mode/app/root.tsx b/dark-mode/app/root.tsx index b2785130..6bad5ff4 100644 --- a/dark-mode/app/root.tsx +++ b/dark-mode/app/root.tsx @@ -1,4 +1,5 @@ -import type { LoaderFunction, MetaFunction } from "@remix-run/node"; +import type { LoaderArgs, MetaFunction } from "@remix-run/node"; +import { json } from "@remix-run/node"; import { Links, LiveReload, @@ -15,21 +16,14 @@ import { ThemeProvider, useTheme, } from "~/utils/theme-provider"; -import type { Theme } from "~/utils/theme-provider"; import { getThemeSession } from "~/utils/theme.server"; -export type LoaderData = { - theme: Theme | null; -}; - -export const loader: LoaderFunction = async ({ request }) => { +export const loader = async ({ request }: LoaderArgs) => { const themeSession = await getThemeSession(request); - const data: LoaderData = { + return json({ theme: themeSession.getTheme(), - }; - - return data; + }); }; export const meta: MetaFunction = () => ({ @@ -39,7 +33,7 @@ export const meta: MetaFunction = () => ({ }); function App() { - const data = useLoaderData(); + const data = useLoaderData(); const [theme] = useTheme(); return ( @@ -61,7 +55,7 @@ function App() { } export default function AppWithProviders() { - const data = useLoaderData(); + const data = useLoaderData(); return ( diff --git a/dark-mode/app/routes/action/set-theme.tsx b/dark-mode/app/routes/action/set-theme.tsx index bd747fff..207d7996 100644 --- a/dark-mode/app/routes/action/set-theme.tsx +++ b/dark-mode/app/routes/action/set-theme.tsx @@ -1,10 +1,10 @@ -import type { ActionFunction, LoaderFunction } from "@remix-run/node"; +import type { ActionArgs } from "@remix-run/node"; import { json, redirect } from "@remix-run/node"; import { getThemeSession } from "~/utils/theme.server"; import { isTheme } from "~/utils/theme-provider"; -export const action: ActionFunction = async ({ request }) => { +export const action = async ({ request }: ActionArgs) => { const themeSession = await getThemeSession(request); const requestText = await request.text(); const form = new URLSearchParams(requestText); @@ -24,4 +24,4 @@ export const action: ActionFunction = async ({ request }) => { ); }; -export const loader: LoaderFunction = () => redirect("/", { status: 404 }); +export const loader = async () => redirect("/", { status: 404 }); diff --git a/dataloader/app/data.server.ts b/dataloader/app/data.server.ts index e0849b9d..7b0efdbe 100644 --- a/dataloader/app/data.server.ts +++ b/dataloader/app/data.server.ts @@ -1,10 +1,10 @@ -export interface User { +interface User { id: string; email: string; name: string; } -export const users: User[] = [ +const users: User[] = [ { id: "ef3fcb93-0623-4d10-adbf-4dd865d6688c", email: "Melisa_Treutel38@gmail.com", diff --git a/dataloader/app/routes/index.tsx b/dataloader/app/routes/index.tsx index 6adeb529..5a5443af 100644 --- a/dataloader/app/routes/index.tsx +++ b/dataloader/app/routes/index.tsx @@ -1,4 +1,3 @@ -import type { LoaderFunction } from "@remix-run/node"; import { redirect } from "@remix-run/node"; -export const loader: LoaderFunction = async () => redirect("/users"); +export const loader = async () => redirect("/users"); diff --git a/dataloader/app/routes/users.tsx b/dataloader/app/routes/users.tsx index 7d9fc4b7..62e644ab 100644 --- a/dataloader/app/routes/users.tsx +++ b/dataloader/app/routes/users.tsx @@ -1,14 +1,8 @@ -import type { LoaderFunction } from "@remix-run/node"; +import type { LoaderArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Outlet, useLoaderData } from "@remix-run/react"; -import type { User } from "~/data.server"; - -interface LoaderData { - users: User[]; -} - -export const loader: LoaderFunction = async ({ context }) => { +export const loader = async ({ context }: LoaderArgs) => { const users = await context.loaders.usersById.loadMany([ "ef3fcb93-0623-4d10-adbf-4dd865d6688c", "2cbad877-2da6-422d-baa6-c6a96a9e085f", @@ -17,7 +11,7 @@ export const loader: LoaderFunction = async ({ context }) => { }; export default function UserNames() { - const { users } = useLoaderData(); + const { users } = useLoaderData(); return (
diff --git a/dataloader/app/routes/users/index.tsx b/dataloader/app/routes/users/index.tsx index 55e6a15c..bdd504e1 100644 --- a/dataloader/app/routes/users/index.tsx +++ b/dataloader/app/routes/users/index.tsx @@ -1,14 +1,8 @@ -import type { LoaderFunction } from "@remix-run/node"; +import type { LoaderArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { useLoaderData } from "@remix-run/react"; -import type { User } from "~/data.server"; - -interface LoaderData { - users: User[]; -} - -export const loader: LoaderFunction = async ({ context }) => { +export const loader = async ({ context }: LoaderArgs) => { /* * For demo purposes: * Batching & caching also works with multiple calls to `DataLoader#load` @@ -33,7 +27,7 @@ export const loader: LoaderFunction = async ({ context }) => { }; export default function UserEmails() { - const { users } = useLoaderData(); + const { users } = useLoaderData(); return (
diff --git a/file-and-cloudinary-upload/app/routes/cloudinary-upload.tsx b/file-and-cloudinary-upload/app/routes/cloudinary-upload.tsx index 8934642c..8fef5a8c 100644 --- a/file-and-cloudinary-upload/app/routes/cloudinary-upload.tsx +++ b/file-and-cloudinary-upload/app/routes/cloudinary-upload.tsx @@ -1,4 +1,4 @@ -import type { ActionFunction, UploadHandler } from "@remix-run/node"; +import type { ActionArgs, UploadHandler } from "@remix-run/node"; import { json, unstable_composeUploadHandlers as composeUploadHandlers, @@ -9,18 +9,13 @@ import { Form, useActionData } from "@remix-run/react"; import { uploadImage } from "~/utils/utils.server"; -type ActionData = { - errorMsg?: string; - imgSrc?: string; - imgDesc?: string; -}; - -export const action: ActionFunction = async ({ request }) => { +export const action = async ({ request }: ActionArgs) => { const uploadHandler: UploadHandler = composeUploadHandlers( - async ({ name, contentType, data, filename }) => { + async ({ name, data }) => { if (name !== "img") { return undefined; } + const uploadedImage = await uploadImage(data); return uploadedImage.secure_url; }, @@ -31,18 +26,15 @@ export const action: ActionFunction = async ({ request }) => { const imgSrc = formData.get("img"); const imgDesc = formData.get("desc"); if (!imgSrc) { - return json({ - error: "something wrong", - }); + return json({ error: "something wrong" }); } - return json({ - imgSrc, - imgDesc, - }); + + return json({ imgDesc, imgSrc }); }; export default function Index() { - const data = useActionData(); + const data = useActionData(); + return ( <>
@@ -52,13 +44,14 @@ export default function Index() {
- {data?.errorMsg &&

{data.errorMsg}

} - {data?.imgSrc && ( + {data?.error ?

{data.error}

: null} + + {data?.imgSrc ? ( <>

uploaded image

{data.imgDesc - )} + ) : null} ); } diff --git a/file-and-cloudinary-upload/app/routes/local-upload.tsx b/file-and-cloudinary-upload/app/routes/local-upload.tsx index 1775fd8b..46788914 100644 --- a/file-and-cloudinary-upload/app/routes/local-upload.tsx +++ b/file-and-cloudinary-upload/app/routes/local-upload.tsx @@ -1,4 +1,4 @@ -import type { ActionFunction } from "@remix-run/node"; +import type { ActionArgs } from "@remix-run/node"; import { json, unstable_composeUploadHandlers as composeUploadHandlers, @@ -8,12 +8,7 @@ import { } from "@remix-run/node"; import { Form, useActionData } from "@remix-run/react"; -type ActionData = { - errorMsg?: string; - imgSrc?: string; -}; - -export const action: ActionFunction = async ({ request }) => { +export const action = async ({ request }: ActionArgs) => { const uploadHandler = composeUploadHandlers( createFileUploadHandler({ directory: "public/uploads", @@ -24,30 +19,29 @@ export const action: ActionFunction = async ({ request }) => { const formData = await parseMultipartFormData(request, uploadHandler); const image = formData.get("img"); if (!image || typeof image === "string") { - return json({ - error: "something wrong", - }); + return json({ error: "something wrong" }); } - return json({ - imgSrc: image.name, - }); + + return json({ imgSrc: image.name }); }; export default function Index() { - const data = useActionData(); + const data = useActionData(); + return ( <>
- {data?.errorMsg &&

{data.errorMsg}

} - {data?.imgSrc && ( + {data?.error ?

{data.error}

: null} + + {data?.imgSrc ? ( <>

uploaded image

uploaded - )} + ) : null} ); } diff --git a/file-and-s3-upload/app/routes/s3-upload.tsx b/file-and-s3-upload/app/routes/s3-upload.tsx index 1ecc1c0c..b6fbce86 100644 --- a/file-and-s3-upload/app/routes/s3-upload.tsx +++ b/file-and-s3-upload/app/routes/s3-upload.tsx @@ -1,4 +1,4 @@ -import type { ActionFunction, UploadHandler } from "@remix-run/node"; +import type { ActionArgs, UploadHandler } from "@remix-run/node"; import { json, unstable_composeUploadHandlers as composeUploadHandlers, @@ -15,7 +15,7 @@ type ActionData = { imgDesc?: string; }; -export const action: ActionFunction = async ({ request }) => { +export const action = async ({ request }: ActionArgs) => { const uploadHandler: UploadHandler = composeUploadHandlers( s3UploadHandler, createMemoryUploadHandler() diff --git a/firebase/app/routes/index.tsx b/firebase/app/routes/index.tsx index fb16f874..0b69e6a8 100644 --- a/firebase/app/routes/index.tsx +++ b/firebase/app/routes/index.tsx @@ -1,4 +1,4 @@ -import type { ActionFunction, LoaderFunction } from "@remix-run/node"; +import type { ActionArgs, LoaderArgs } from "@remix-run/node"; import { json, redirect } from "@remix-run/node"; import { Form, @@ -7,38 +7,29 @@ import { useFetcher, useLoaderData, } from "@remix-run/react"; +import type { FunctionComponent } from "react"; import { useEffect, useRef } from "react"; import { requireAuth } from "~/server/auth.server"; -import type { Todo } from "~/server/db.server"; import { addTodo, getUserTodos, removeTodo } from "~/server/db.server"; -type LoaderData = { - message: string; - todos: Todo[]; -}; - -export const loader: LoaderFunction = async ({ request }) => { +export const loader = async ({ request }: LoaderArgs) => { const user = await requireAuth(request); const todos = await getUserTodos(user.uid); - return json({ + return json({ message: `Hello ${user.displayName || "unknown"}!`, todos, }); }; -export type ActionData = { - error: string; -}; - -export const action: ActionFunction = async ({ request }) => { +export const action = async ({ request }: ActionArgs) => { const { uid } = await requireAuth(request); const form = await request.formData(); const intent = form.get("intent"); if (intent === "create") { const title = form.get("title"); if (typeof title !== "string" || title.length === 0) { - return json({ error: "title is required" }, { status: 400 }); + return json({ error: "title is required" }, { status: 400 }); } await addTodo(uid, title); @@ -47,21 +38,24 @@ export const action: ActionFunction = async ({ request }) => { if (intent === "delete") { const id = form.get("id"); if (typeof id !== "string") { - return json({ error: "id is required" }, { status: 400 }); + return json({ error: "id is required" }, { status: 400 }); } await removeTodo(uid, id); return redirect("/"); } - return json({ error: "unknown method" }, { status: 400 }); + return json({ error: "unknown method" }, { status: 400 }); }; -const TodoComponent: React.FC<{ id: string; title: string }> = (props) => { +const TodoComponent: FunctionComponent<{ id: string; title: string }> = ({ + id, + title, +}) => { const fetcher = useFetcher(); return (
  • - - {props.title} + + {title} @@ -71,8 +65,8 @@ const TodoComponent: React.FC<{ id: string; title: string }> = (props) => { }; export default function Index() { - const action = useActionData(); - const data = useLoaderData(); + const actionData = useActionData(); + const data = useLoaderData(); const ref = useRef(null); useEffect(() => { ref.current?.focus(); @@ -83,7 +77,9 @@ export default function Index() {

    Want to log out?

    - {action?.error &&

    {action.error}

    } + {actionData?.error ? ( +

    {actionData.error}

    + ) : null}

    Create new Todo:

    diff --git a/firebase/app/routes/join.tsx b/firebase/app/routes/join.tsx index 3ff80d54..4734a589 100644 --- a/firebase/app/routes/join.tsx +++ b/firebase/app/routes/join.tsx @@ -1,11 +1,11 @@ -import type { ActionFunction, LoaderFunction } from "@remix-run/node"; +import type { ActionArgs, LoaderArgs } from "@remix-run/node"; import { json, redirect } from "@remix-run/node"; import { Form, Link, useActionData } from "@remix-run/react"; import { checkSessionCookie, signUp } from "~/server/auth.server"; import { commitSession, getSession } from "~/sessions"; -export const loader: LoaderFunction = async ({ request }) => { +export const loader = async ({ request }: LoaderArgs) => { const session = await getSession(request.headers.get("cookie")); const { uid } = await checkSessionCookie(session); const headers = { @@ -17,11 +17,7 @@ export const loader: LoaderFunction = async ({ request }) => { return json(null, { headers }); }; -type ActionData = { - error?: string; -}; - -export const action: ActionFunction = async ({ request }) => { +export const action = async ({ request }: ActionArgs) => { const form = await request.formData(); const name = form.get("name"); const email = form.get("email"); @@ -41,16 +37,16 @@ export const action: ActionFunction = async ({ request }) => { }); } catch (error) { console.error(error); - return json({ error: String(error) }, { status: 401 }); + return json({ error: String(error) }, { status: 401 }); } }; export default function Login() { - const action = useActionData(); + const actionData = useActionData(); return (

    Join

    - {action?.error &&

    {action.error}

    } + {actionData?.error &&

    {actionData.error}

    } { +export const loader = async ({ request }: LoaderArgs) => { const session = await getSession(request.headers.get("cookie")); const { uid } = await checkSessionCookie(session); const headers = { @@ -31,13 +27,13 @@ export const loader: LoaderFunction = async ({ request }) => { return redirect("/", { headers }); } const { apiKey, domain } = getRestConfig(); - return json({ apiKey, domain }, { headers }); + return json({ apiKey, domain }, { headers }); }; -interface ActionData { +type ActionData = { error?: string; -} -export const action: ActionFunction = async ({ request }) => { +}; +export const action = async ({ request }: ActionArgs) => { const form = await request.formData(); const idToken = form.get("idToken"); let sessionCookie; @@ -64,14 +60,14 @@ export const action: ActionFunction = async ({ request }) => { }); } catch (error) { console.error(error); - return json({ error: String(error) }, { status: 401 }); + return json({ error: String(error) }, { status: 401 }); } }; export default function Login() { const [clientAction, setClientAction] = useState(); - const action = useActionData(); - const restConfig = useLoaderData(); + const actionData = useActionData(); + const restConfig = useLoaderData(); const submit = useSubmit(); const handleSubmit = useCallback( @@ -97,8 +93,8 @@ export default function Login() { return (

    Login

    - {(clientAction?.error || action?.error) && ( -

    {clientAction?.error || action?.error}

    + {(clientAction?.error || actionData?.error) && ( +

    {clientAction?.error || actionData?.error}

    )} { +export const action = async ({ request }: ActionArgs) => { const session = await getSession(request.headers.get("Cookie")); return redirect("/", { headers: { "Set-Cookie": await destroySession(session) }, diff --git a/firebase/app/server/db.server.ts b/firebase/app/server/db.server.ts index 1a27e0ce..ba475e2f 100644 --- a/firebase/app/server/db.server.ts +++ b/firebase/app/server/db.server.ts @@ -12,7 +12,7 @@ const dataPoint = ( collectionPath: string ) => getFirestore().collection(collectionPath).withConverter(converter()); -export type Todo = { +type Todo = { id: string; title: string; }; diff --git a/form-to-notion-db/app/root.tsx b/form-to-notion-db/app/root.tsx index de8dcf62..d4757e16 100644 --- a/form-to-notion-db/app/root.tsx +++ b/form-to-notion-db/app/root.tsx @@ -1,4 +1,4 @@ -import type { ActionFunction, MetaFunction } from "@remix-run/node"; +import type { ActionArgs, MetaFunction } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Links, @@ -10,7 +10,7 @@ import { import notion from "./notion.server"; -export const action: ActionFunction = async ({ request }) => { +export const action = async ({ request }: ActionArgs) => { const form = await request.formData(); const firstname = form.get("firstname"); const lastname = form.get("lastname"); diff --git a/gdpr-cookie-consent/app/root.tsx b/gdpr-cookie-consent/app/root.tsx index 7fc39e20..54b62264 100644 --- a/gdpr-cookie-consent/app/root.tsx +++ b/gdpr-cookie-consent/app/root.tsx @@ -1,4 +1,4 @@ -import type { LoaderFunction, MetaFunction } from "@remix-run/node"; +import type { LoaderArgs, MetaFunction } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Links, @@ -14,7 +14,7 @@ import * as React from "react"; import { gdprConsent } from "./cookies"; -export const loader: LoaderFunction = async ({ request }) => { +export const loader = async ({ request }: LoaderArgs) => { const cookieHeader = request.headers.get("Cookie"); const cookie = (await gdprConsent.parse(cookieHeader)) || {}; return json({ track: cookie.gdprConsent }); @@ -27,7 +27,7 @@ export const meta: MetaFunction = () => ({ }); export default function App() { - const { track } = useLoaderData(); + const { track } = useLoaderData(); const analyticsFetcher = useFetcher(); React.useEffect(() => { if (track) { diff --git a/gdpr-cookie-consent/app/routes/enable-analytics.tsx b/gdpr-cookie-consent/app/routes/enable-analytics.tsx index b6943859..f55a0449 100644 --- a/gdpr-cookie-consent/app/routes/enable-analytics.tsx +++ b/gdpr-cookie-consent/app/routes/enable-analytics.tsx @@ -1,9 +1,9 @@ -import type { ActionFunction } from "@remix-run/node"; +import type { ActionArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { gdprConsent } from "~/cookies"; -export const action: ActionFunction = async ({ request }) => { +export const action = async ({ request }: ActionArgs) => { const formData = await request.formData(); const cookieHeader = request.headers.get("Cookie"); const cookie = (await gdprConsent.parse(cookieHeader)) || {}; diff --git a/google-analytics/app/root.tsx b/google-analytics/app/root.tsx index bcebceaf..7c1b4632 100644 --- a/google-analytics/app/root.tsx +++ b/google-analytics/app/root.tsx @@ -1,4 +1,4 @@ -import type { LoaderFunction, MetaFunction } from "@remix-run/node"; +import type { MetaFunction } from "@remix-run/node"; import { json } from "@remix-run/node"; // import { json } from "@remix-run/node"; import { @@ -30,13 +30,9 @@ import * as gtag from "~/utils/gtags.client"; // }); // } -type LoaderData = { - gaTrackingId: string | undefined; -}; - // Load the GA tracking id from the .env -export const loader: LoaderFunction = async () => { - return json({ gaTrackingId: process.env.GA_TRACKING_ID }); +export const loader = async () => { + return json({ gaTrackingId: process.env.GA_TRACKING_ID }); }; export const meta: MetaFunction = () => ({ @@ -47,7 +43,7 @@ export const meta: MetaFunction = () => ({ export default function App() { const location = useLocation(); - const { gaTrackingId } = useLoaderData(); + const { gaTrackingId } = useLoaderData(); useEffect(() => { if (gaTrackingId?.length) { diff --git a/google-analytics/app/routes/contact.tsx b/google-analytics/app/routes/contact.tsx index a096314d..00521c22 100644 --- a/google-analytics/app/routes/contact.tsx +++ b/google-analytics/app/routes/contact.tsx @@ -1,13 +1,10 @@ -import type { ActionFunction } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Form } from "@remix-run/react"; import type { SyntheticEvent } from "react"; import * as gtag from "~/utils/gtags.client"; -export const action: ActionFunction = () => { - return json({}); -}; +export const action = async () => json({}); export default function Contact() { const handleSubmit = (e: SyntheticEvent) => { diff --git a/graphql-api/app/routes/api/character.tsx b/graphql-api/app/routes/api/character.tsx index c9329ba3..01314133 100644 --- a/graphql-api/app/routes/api/character.tsx +++ b/graphql-api/app/routes/api/character.tsx @@ -1,18 +1,9 @@ -import type { LoaderFunction } from "@remix-run/node"; +import type { LoaderArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; -import type { ApolloError } from "apollo-server-errors"; import { fetchFromGraphQL, gql } from "~/utils"; -import type { Character } from "~/generated/types"; - -export type LoaderData = { - data: { character: Character }; - errors?: ApolloError[]; -}; - -export const loader: LoaderFunction = async (args): Promise => { - const { request } = args; +export const loader = async ({ request }: LoaderArgs) => { const url = new URL(request.url); const id = url.searchParams.get("id"); diff --git a/graphql-api/app/routes/api/characters.tsx b/graphql-api/app/routes/api/characters.tsx index 87e8d3d0..a0b6eaa1 100644 --- a/graphql-api/app/routes/api/characters.tsx +++ b/graphql-api/app/routes/api/characters.tsx @@ -1,17 +1,9 @@ -import type { LoaderFunction } from "@remix-run/node"; +import type { LoaderArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; -import type { ApolloError } from "apollo-server-errors"; import { fetchFromGraphQL, gql } from "~/utils"; -import type { Characters } from "~/generated/types"; -export type LoaderData = { - data: { characters: Characters }; - errors?: ApolloError[]; -}; - -export const loader: LoaderFunction = async (args): Promise => { - const { params } = args; +export const loader = async ({ params }: LoaderArgs) => { const { page = 1 } = params; const getCharactersQuery = gql` diff --git a/graphql-api/app/routes/character/$id.tsx b/graphql-api/app/routes/character/$id.tsx index e35be7ef..666b6f08 100644 --- a/graphql-api/app/routes/character/$id.tsx +++ b/graphql-api/app/routes/character/$id.tsx @@ -1,16 +1,13 @@ -import type { LoaderFunction } from "@remix-run/node"; +import type { LoaderArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Link, useLoaderData } from "@remix-run/react"; import { Code } from "~/components/Code"; -import type { LoaderData } from "~/routes/api/character"; /** * @description This loader fetches from the Resource route using fetch. */ -export const loader: LoaderFunction = async (args) => { - const { params } = args; - +export const loader = async ({ params }: LoaderArgs) => { const url = `http://localhost:3000/api/character?id=${params.id}`; const res = await fetch(url, { method: "GET", @@ -24,7 +21,7 @@ export const loader: LoaderFunction = async (args) => { * the Remix loader & route params. */ export default function Character() { - const loader = useLoaderData(); + const loader = useLoaderData(); const { data } = loader; const character = data.character; diff --git a/graphql-api/app/routes/character/error.tsx b/graphql-api/app/routes/character/error.tsx index 549177c6..0e2a88d1 100644 --- a/graphql-api/app/routes/character/error.tsx +++ b/graphql-api/app/routes/character/error.tsx @@ -1,21 +1,13 @@ -import type { LoaderFunction } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Link, useLoaderData } from "@remix-run/react"; -import type { ApolloError } from "apollo-server-errors"; import { Code } from "~/components/Code"; import { fetchFromGraphQL, gql } from "~/utils/index"; -import type { Character } from "~/generated/types"; - -type LoaderData = { - data: { character: Character }; - errors?: ApolloError[]; -}; /** * @description Here we query an external GraphQL API directly via "fetch". */ -export const loader: LoaderFunction = async (_args) => { +export const loader = async () => { const getCharacterQuery = gql` fragment CharacterFields on Character { gender @@ -51,7 +43,7 @@ export const loader: LoaderFunction = async (_args) => { * an array of errors coming back from the GraphQL API. */ export default function CharacterError() { - const loader = useLoaderData(); + const loader = useLoaderData(); return (
    diff --git a/graphql-api/app/routes/index.tsx b/graphql-api/app/routes/index.tsx index df36f110..eb6fbb27 100644 --- a/graphql-api/app/routes/index.tsx +++ b/graphql-api/app/routes/index.tsx @@ -1,7 +1,7 @@ import { Link, useLoaderData } from "@remix-run/react"; import { Code } from "~/components/Code"; -import type { LoaderData } from "~/routes/api/characters"; +import type { loader } from "~/routes/api/characters"; /** * @description Here we simply re-export the loader used in our resource route @@ -14,8 +14,7 @@ export { loader } from "~/routes/api/characters"; * a GraphQL API. */ export default function Index() { - const loader = useLoaderData(); - const { data } = loader; + const { data } = useLoaderData(); const characters = data.characters.results ?? []; diff --git a/image-resize/app/routes/assets/resize/$.ts b/image-resize/app/routes/assets/resize/$.ts index 621df25e..4187c27f 100644 --- a/image-resize/app/routes/assets/resize/$.ts +++ b/image-resize/app/routes/assets/resize/$.ts @@ -17,7 +17,7 @@ import { createReadStream, statSync } from "fs"; import path from "path"; import { PassThrough } from "stream"; -import type { LoaderFunction, Params } from "@remix-run/node"; +import type { LoaderArgs, Params } from "@remix-run/node"; import type { FitEnum } from "sharp"; import sharp from "sharp"; @@ -30,7 +30,7 @@ interface ResizeParams { fit: keyof FitEnum; } -export const loader: LoaderFunction = async ({ params, request }) => { +export const loader = async ({ params, request }: LoaderArgs) => { // extract all the parameters from the url const { src, width, height, fit } = extractParams(params, request); diff --git a/infinite-scrolling/app/routes/offset/advanced.tsx b/infinite-scrolling/app/routes/offset/advanced.tsx index 527791a7..e070040a 100644 --- a/infinite-scrolling/app/routes/offset/advanced.tsx +++ b/infinite-scrolling/app/routes/offset/advanced.tsx @@ -1,4 +1,4 @@ -import type { LinksFunction, LoaderFunction } from "@remix-run/node"; +import type { LinksFunction, LoaderArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { useBeforeUnload, @@ -30,22 +30,15 @@ const getStartLimit = (searchParams: URLSearchParams) => ({ limit: Number(searchParams.get("limit") || LIMIT.toString()), }); -type LoaderData = { - items: Array<{ id: string; value: string }>; - totalItems: number; -}; - -export const loader: LoaderFunction = async ({ request }) => { +export const loader = async ({ request }: LoaderArgs) => { const { start, limit } = getStartLimit(new URL(request.url).searchParams); - const data: LoaderData = { - items: await getItems({ start, limit }), - totalItems: await countItems(), - }; - return json(data, { - headers: { - "Cache-Control": "public, max-age=120", + return json( + { + items: await getItems({ start, limit }), + totalItems: await countItems(), }, - }); + { headers: { "Cache-Control": "public, max-age=120" } } + ); }; const isServerRender = typeof document === "undefined"; @@ -59,7 +52,7 @@ function useIsHydrating(queryString: string) { } export default function Index() { - const data = useLoaderData(); + const data = useLoaderData(); const transition = useTransition(); const hydrating = useIsHydrating("[data-hydrating-signal]"); diff --git a/infinite-scrolling/app/routes/offset/simple.tsx b/infinite-scrolling/app/routes/offset/simple.tsx index f60e4a3d..e10d0aca 100644 --- a/infinite-scrolling/app/routes/offset/simple.tsx +++ b/infinite-scrolling/app/routes/offset/simple.tsx @@ -1,4 +1,4 @@ -import type { LinksFunction, LoaderFunction } from "@remix-run/node"; +import type { LinksFunction, LoaderArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { useFetcher, useLoaderData, useTransition } from "@remix-run/react"; import { useCallback, useEffect, useRef, useState } from "react"; @@ -19,24 +19,16 @@ const getStartLimit = (searchParams: URLSearchParams) => ({ limit: Number(searchParams.get("limit") || LIMIT.toString()), }); -type LoaderData = { - items: Array<{ id: string; value: string }>; -}; - -export const loader: LoaderFunction = async ({ request }) => { +export const loader = async ({ request }: LoaderArgs) => { const { start, limit } = getStartLimit(new URL(request.url).searchParams); - const data: LoaderData = { - items: await getItems({ start, limit }), - }; - return json(data, { - headers: { - "Cache-Control": "public, max-age=120", - }, - }); + return json( + { items: await getItems({ start, limit }) }, + { headers: { "Cache-Control": "public, max-age=120" } } + ); }; export default function Index() { - const data = useLoaderData(); + const data = useLoaderData(); const [items, setItems] = useState(data.items); const transition = useTransition(); diff --git a/infinite-scrolling/app/routes/page/advanced.tsx b/infinite-scrolling/app/routes/page/advanced.tsx index 0f593360..27d9e446 100644 --- a/infinite-scrolling/app/routes/page/advanced.tsx +++ b/infinite-scrolling/app/routes/page/advanced.tsx @@ -1,4 +1,4 @@ -import type { LinksFunction, LoaderFunction } from "@remix-run/node"; +import type { LinksFunction, LoaderArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { useBeforeUnload, @@ -31,22 +31,15 @@ const getPageLimit = (searchParams: URLSearchParams) => ({ limit: Number(searchParams.get("limit") || LIMIT.toString()), }); -type LoaderData = { - items: Array<{ id: string; value: string }>; - totalItems: number; -}; - -export const loader: LoaderFunction = async ({ request }) => { +export const loader = async ({ request }: LoaderArgs) => { const { page, limit } = getPageLimit(new URL(request.url).searchParams); - const data: LoaderData = { - items: await getItemsPaginated({ page, limit }), - totalItems: await countItems(), - }; - return json(data, { - headers: { - "Cache-Control": "public, max-age=120", + return json( + { + items: await getItemsPaginated({ page, limit }), + totalItems: await countItems(), }, - }); + { headers: { "Cache-Control": "public, max-age=120" } } + ); }; const isServerRender = typeof document === "undefined"; @@ -60,7 +53,7 @@ function useIsHydrating(queryString: string) { } export default function Index() { - const data = useLoaderData(); + const data = useLoaderData(); const transition = useTransition(); const [searchParams, setSearchParams] = useSearchParams(); const hydrating = useIsHydrating("[data-hydrating-signal]"); diff --git a/infinite-scrolling/app/routes/page/alternative.tsx b/infinite-scrolling/app/routes/page/alternative.tsx index 6be5f1bb..f9fedb02 100644 --- a/infinite-scrolling/app/routes/page/alternative.tsx +++ b/infinite-scrolling/app/routes/page/alternative.tsx @@ -1,4 +1,4 @@ -import type { LinksFunction, LoaderFunction } from "@remix-run/node"; +import type { LinksFunction, LoaderArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { useFetcher, useLoaderData } from "@remix-run/react"; import { useCallback, useEffect, useRef, useState } from "react"; @@ -17,26 +17,19 @@ const getPage = (searchParams: URLSearchParams) => ({ page: Number(searchParams.get("page") || "0"), }); -type LoaderData = { - items: Array<{ id: string; value: string }>; - totalItems: number; -}; - -export const loader: LoaderFunction = async ({ request }) => { +export const loader = async ({ request }: LoaderArgs) => { const { page } = getPage(new URL(request.url).searchParams); - const data: LoaderData = { - items: await getItemsPaginated({ page, limit: LIMIT }), - totalItems: await countItems(), - }; - return json(data, { - headers: { - "Cache-Control": "public, max-age=120", + return json( + { + items: await getItemsPaginated({ page, limit: LIMIT }), + totalItems: await countItems(), }, - }); + { headers: { "Cache-Control": "public, max-age=120" } } + ); }; export default function Index() { - const data = useLoaderData(); + const data = useLoaderData(); const [items, setItems] = useState(data.items); const fetcher = useFetcher(); diff --git a/infinite-scrolling/app/routes/page/simple.tsx b/infinite-scrolling/app/routes/page/simple.tsx index e90ebf73..e3eb08fa 100644 --- a/infinite-scrolling/app/routes/page/simple.tsx +++ b/infinite-scrolling/app/routes/page/simple.tsx @@ -1,4 +1,4 @@ -import type { LinksFunction, LoaderFunction } from "@remix-run/node"; +import type { LinksFunction, LoaderArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { useFetcher, useLoaderData, useTransition } from "@remix-run/react"; import { useCallback, useEffect, useRef, useState } from "react"; @@ -18,26 +18,19 @@ const getPage = (searchParams: URLSearchParams) => ({ page: Number(searchParams.get("page") || "0"), }); -type LoaderData = { - items: Array<{ id: string; value: string }>; - totalItems: number; -}; - -export const loader: LoaderFunction = async ({ request }) => { +export const loader = async ({ request }: LoaderArgs) => { const { page } = getPage(new URL(request.url).searchParams); - const data: LoaderData = { - items: await getItemsPaginated({ page, limit: LIMIT }), - totalItems: await countItems(), - }; - return json(data, { - headers: { - "Cache-Control": "public, max-age=120", + return json( + { + items: await getItemsPaginated({ page, limit: LIMIT }), + totalItems: await countItems(), }, - }); + { headers: { "Cache-Control": "public, max-age=120" } } + ); }; export default function Index() { - const data = useLoaderData(); + const data = useLoaderData(); const [items, setItems] = useState(data.items); const transition = useTransition(); diff --git a/io-ts-formdata-decoding/app/routes/index.tsx b/io-ts-formdata-decoding/app/routes/index.tsx index 02f633f6..4167efad 100644 --- a/io-ts-formdata-decoding/app/routes/index.tsx +++ b/io-ts-formdata-decoding/app/routes/index.tsx @@ -1,4 +1,4 @@ -import type { ActionFunction } from "@remix-run/node"; +import type { ActionArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Form, useActionData, useCatch } from "@remix-run/react"; import * as t from "io-ts"; @@ -14,13 +14,7 @@ const User = t.type({ age: t.number, }); -type ActionData = { - // The actual `User`-type - // https://gcanti.github.io/io-ts/modules/index.ts.html#typeof-type-alias - user: t.TypeOf; -}; - -export const action: ActionFunction = async ({ request }) => { +export const action = async ({ request }: ActionArgs) => { // Using `FormData` with TypeScript can be a little inconvenient: // // const formData = await request.formData(); @@ -81,7 +75,7 @@ const NewUserForm = () => ( ); export default function App() { - const data = useActionData(); + const data = useActionData(); const user = data?.user; return ( diff --git a/ioredis/app/routes/index.tsx b/ioredis/app/routes/index.tsx index 12a9b002..713a9a24 100644 --- a/ioredis/app/routes/index.tsx +++ b/ioredis/app/routes/index.tsx @@ -1,15 +1,15 @@ -import type { ActionFunction, LoaderFunction } from "@remix-run/node"; +import type { ActionArgs } from "@remix-run/node"; import { json, redirect } from "@remix-run/node"; import { Form, useActionData, useLoaderData } from "@remix-run/react"; import { redis } from "~/utils/redis.server"; -export const loader: LoaderFunction = async () => { +export const loader = async () => { const message = await redis.get("message"); return json({ message }); }; -export const action: ActionFunction = async ({ request }) => { +export const action = async ({ request }: ActionArgs) => { const formData = await request.formData(); const message = formData.get("message"); @@ -23,8 +23,8 @@ export const action: ActionFunction = async ({ request }) => { }; export default function IndexRoute() { - const data = useLoaderData(); - const actionMessage = useActionData(); + const data = useLoaderData(); + const actionMessage = useActionData(); return (
    diff --git a/msw/app/root.tsx b/msw/app/root.tsx index dafed492..30b601ed 100644 --- a/msw/app/root.tsx +++ b/msw/app/root.tsx @@ -1,4 +1,4 @@ -import type { LoaderFunction, MetaFunction } from "@remix-run/node"; +import type { MetaFunction } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Links, @@ -9,9 +9,7 @@ import { useLoaderData, } from "@remix-run/react"; -type LoaderData = { message: string }; - -export const loader: LoaderFunction = async () => { +export const loader = async () => { const data = await fetch("https://my-mock-api.com").then((response) => response.json() ); @@ -20,7 +18,7 @@ export const loader: LoaderFunction = async () => { throw json({ message: "Server error" }, { status: 500 }); } - return json(data); + return json(data); }; export const meta: MetaFunction = () => ({ @@ -30,7 +28,7 @@ export const meta: MetaFunction = () => ({ }); export default function App() { - const loaderData = useLoaderData(); + const data = useLoaderData(); return ( @@ -39,7 +37,7 @@ export default function App() { -

    {loaderData.message}

    +

    {data.message}

    diff --git a/multiple-forms/app/routes/index.tsx b/multiple-forms/app/routes/index.tsx index c7687bbd..a9449ec8 100644 --- a/multiple-forms/app/routes/index.tsx +++ b/multiple-forms/app/routes/index.tsx @@ -1,4 +1,3 @@ -import type { LoaderFunction } from "@remix-run/node"; import { redirect } from "@remix-run/node"; -export const loader: LoaderFunction = async () => redirect("/invitations"); +export const loader = async () => redirect("/invitations"); diff --git a/multiple-forms/app/routes/invitations.tsx b/multiple-forms/app/routes/invitations.tsx index 90f34fd9..67f16adc 100644 --- a/multiple-forms/app/routes/invitations.tsx +++ b/multiple-forms/app/routes/invitations.tsx @@ -1,8 +1,7 @@ -import type { ActionFunction, LoaderFunction } from "@remix-run/node"; +import type { ActionArgs } from "@remix-run/node"; import { json, redirect } from "@remix-run/node"; import { Form, useLoaderData } from "@remix-run/react"; -import type { Invitation } from "~/data.server"; import { sendInvitation } from "~/data.server"; import { getInvitations, @@ -10,15 +9,11 @@ import { deleteInvitiation, } from "~/data.server"; -type LoaderData = { invitations: Array }; - -export const loader: LoaderFunction = async () => { - return json({ - invitations: await getInvitations(), - }); +export const loader = async () => { + return json({ invitations: await getInvitations() }); }; -export const action: ActionFunction = async ({ request }) => { +export const action = async ({ request }: ActionArgs) => { const formData = await request.formData(); if (formData.get("intent") === "send") { const email = formData.get("email"); @@ -54,7 +49,7 @@ export const action: ActionFunction = async ({ request }) => { }; export default function Index() { - const data = useLoaderData(); + const data = useLoaderData(); return (
    diff --git a/multiple-params/app/db.ts b/multiple-params/app/db.ts index 039c8372..0a6c79be 100644 --- a/multiple-params/app/db.ts +++ b/multiple-params/app/db.ts @@ -1,10 +1,10 @@ -export type Invoice = { +type Invoice = { id: string; title: string; amount: number; currency: "EUR" | "USD" | "GBP"; }; -export type Client = { +type Client = { id: string; name: string; email: string; diff --git a/multiple-params/app/routes/clients.tsx b/multiple-params/app/routes/clients.tsx index a94183e8..ad7a0bc6 100644 --- a/multiple-params/app/routes/clients.tsx +++ b/multiple-params/app/routes/clients.tsx @@ -1,24 +1,17 @@ -import type { LoaderFunction } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Link, Outlet, useLoaderData } from "@remix-run/react"; -import type { Client } from "~/db"; import { getClients } from "~/db"; -type LoaderData = { - clients: Array>; -}; - -export const loader: LoaderFunction = async () => { +export const loader = async () => { const clients = await getClients(); - const data: LoaderData = { + return json({ clients: clients.map((c) => ({ id: c.id, name: c.name })), - }; - return json(data); + }); }; export default function ClientsRoute() { - const data = useLoaderData(); + const data = useLoaderData(); return (

    Clients

    diff --git a/multiple-params/app/routes/clients/$clientId.tsx b/multiple-params/app/routes/clients/$clientId.tsx index cae2813b..829111e5 100644 --- a/multiple-params/app/routes/clients/$clientId.tsx +++ b/multiple-params/app/routes/clients/$clientId.tsx @@ -1,4 +1,4 @@ -import type { LoaderFunction } from "@remix-run/node"; +import type { LoaderArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Link, @@ -8,14 +8,9 @@ import { useParams, } from "@remix-run/react"; -import type { Client } from "~/db"; import { getClient } from "~/db"; -type LoaderData = { - client: Pick; -}; - -export const loader: LoaderFunction = async ({ params }) => { +export const loader = async ({ params }: LoaderArgs) => { if (!params.clientId) { throw new Response(`No client ID provided`, { status: 404, @@ -28,12 +23,11 @@ export const loader: LoaderFunction = async ({ params }) => { }); } - const data: LoaderData = { client: { name: client.name } }; - return json(data); + return json({ client: { name: client.name } }); }; export default function ClientRoute() { - const data = useLoaderData(); + const data = useLoaderData(); return (

    {data.client.name}

    diff --git a/multiple-params/app/routes/clients/$clientId/index.tsx b/multiple-params/app/routes/clients/$clientId/index.tsx index 012327dd..6f739a4f 100644 --- a/multiple-params/app/routes/clients/$clientId/index.tsx +++ b/multiple-params/app/routes/clients/$clientId/index.tsx @@ -1,15 +1,10 @@ -import type { LoaderFunction } from "@remix-run/node"; +import type { LoaderArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { useLoaderData } from "@remix-run/react"; -import type { Client } from "~/db"; import { getClient } from "~/db"; -type LoaderData = { - client: Pick; -}; - -export const loader: LoaderFunction = async ({ params }) => { +export const loader = async ({ params }: LoaderArgs) => { if (!params.clientId) { throw new Response(`No client ID provided`, { status: 404, @@ -22,18 +17,17 @@ export const loader: LoaderFunction = async ({ params }) => { }); } - const data: LoaderData = { + return json({ client: { id: client.id, email: client.email, name: client.name, }, - }; - return json(data); + }); }; export default function ClientIndexRoute() { - const data = useLoaderData(); + const data = useLoaderData(); return (
    {data.client.name} Information diff --git a/multiple-params/app/routes/clients/$clientId/invoices.tsx b/multiple-params/app/routes/clients/$clientId/invoices.tsx index 9964903e..d9a7b4ee 100644 --- a/multiple-params/app/routes/clients/$clientId/invoices.tsx +++ b/multiple-params/app/routes/clients/$clientId/invoices.tsx @@ -1,13 +1,10 @@ -import type { LoaderFunction } from "@remix-run/node"; +import type { LoaderArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Link, Outlet, useLoaderData } from "@remix-run/react"; -import type { Invoice } from "~/db"; import { getClient } from "~/db"; -type LoaderData = { invoices: Array> }; - -export const loader: LoaderFunction = async ({ params }) => { +export const loader = async ({ params }: LoaderArgs) => { if (!params.clientId) { throw new Response(`No client ID provided`, { status: 404, @@ -20,14 +17,13 @@ export const loader: LoaderFunction = async ({ params }) => { }); } - const data: LoaderData = { + return json({ invoices: client.invoices.map((i) => ({ id: i.id, title: i.title })), - }; - return json(data); + }); }; export default function ClientRoute() { - const data = useLoaderData(); + const data = useLoaderData(); return (

    Invoices

    diff --git a/multiple-params/app/routes/clients/$clientId/invoices/$invoiceId.tsx b/multiple-params/app/routes/clients/$clientId/invoices/$invoiceId.tsx index 06e71a05..3b09bbce 100644 --- a/multiple-params/app/routes/clients/$clientId/invoices/$invoiceId.tsx +++ b/multiple-params/app/routes/clients/$clientId/invoices/$invoiceId.tsx @@ -1,13 +1,10 @@ -import type { LoaderFunction } from "@remix-run/node"; +import type { LoaderArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { useCatch, useLoaderData, useParams } from "@remix-run/react"; -import type { Invoice } from "~/db"; import { getClient } from "~/db"; -type LoaderData = { invoice: Invoice }; - -export const loader: LoaderFunction = async ({ params }) => { +export const loader = async ({ params }: LoaderArgs) => { if (!params.clientId) { throw new Response(`No client ID provided`, { status: 404, @@ -31,12 +28,11 @@ export const loader: LoaderFunction = async ({ params }) => { }); } - const data: LoaderData = { invoice }; - return json(data); + return json({ invoice }); }; export default function ClientRoute() { - const data = useLoaderData(); + const data = useLoaderData(); return (

    Invoice

    diff --git a/newsletter-signup/app/routes/newsletter.tsx b/newsletter-signup/app/routes/newsletter.tsx index 6833bd83..1cd0beab 100644 --- a/newsletter-signup/app/routes/newsletter.tsx +++ b/newsletter-signup/app/routes/newsletter.tsx @@ -1,9 +1,9 @@ -import type { ActionFunction } from "@remix-run/node"; +import type { ActionArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Form, Link, useActionData, useTransition } from "@remix-run/react"; import { useEffect, useRef } from "react"; -export const action: ActionFunction = async ({ request }) => { +export const action = async ({ request }: ActionArgs) => { await new Promise((res) => setTimeout(res, 1000)); const formData = await request.formData(); const email = formData.get("email"); @@ -24,7 +24,7 @@ export const action: ActionFunction = async ({ request }) => { }; export default function Newsletter() { - const actionData = useActionData(); + const actionData = useActionData(); const transition = useTransition(); const state: "idle" | "success" | "error" | "submitting" = transition.submission diff --git a/nprogress/app/routes/slow-page.tsx b/nprogress/app/routes/slow-page.tsx index a7ffc41f..b5e8273b 100644 --- a/nprogress/app/routes/slow-page.tsx +++ b/nprogress/app/routes/slow-page.tsx @@ -1,8 +1,7 @@ -import type { LoaderFunction } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Link } from "@remix-run/react"; -export const loader: LoaderFunction = async () => { +export const loader = async () => { await new Promise((resolve) => setTimeout(resolve, 1000)); return json({}); }; diff --git a/on-demand-hydration/app/routes/on-demand-js.tsx b/on-demand-hydration/app/routes/on-demand-js.tsx index 01eebfee..c1e6cab1 100644 --- a/on-demand-hydration/app/routes/on-demand-js.tsx +++ b/on-demand-hydration/app/routes/on-demand-js.tsx @@ -1,23 +1,19 @@ -import type { LoaderFunction } from "@remix-run/node"; +import type { LoaderArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { useLoaderData } from "@remix-run/react"; -type LoaderData = { withJS: boolean }; - -export const loader: LoaderFunction = async ({ request }) => { +export const loader = async ({ request }: LoaderArgs) => { const url = new URL(request.url); const withJS = url.searchParams.has("js"); - return json({ withJS }); + return json({ withJS }); }; export const handle = { - hydrate(data: LoaderData) { - return data.withJS; - }, + hydrate: (data: { withJS: boolean }) => data.withJS, }; export default function Screen() { - const { withJS } = useLoaderData(); + const { withJS } = useLoaderData(); return ( <> diff --git a/outlet-form-rerender/app/routes/index.tsx b/outlet-form-rerender/app/routes/index.tsx index 6adeb529..5a5443af 100644 --- a/outlet-form-rerender/app/routes/index.tsx +++ b/outlet-form-rerender/app/routes/index.tsx @@ -1,4 +1,3 @@ -import type { LoaderFunction } from "@remix-run/node"; import { redirect } from "@remix-run/node"; -export const loader: LoaderFunction = async () => redirect("/users"); +export const loader = async () => redirect("/users"); diff --git a/outlet-form-rerender/app/routes/users.tsx b/outlet-form-rerender/app/routes/users.tsx index 77d378fa..62b82bc1 100644 --- a/outlet-form-rerender/app/routes/users.tsx +++ b/outlet-form-rerender/app/routes/users.tsx @@ -1,24 +1,19 @@ -import type { LoaderFunction, MetaFunction } from "@remix-run/node"; +import type { MetaFunction } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Link, Outlet, useLoaderData } from "@remix-run/react"; -import type { User } from "~/data.server"; import { users } from "~/data.server"; -interface LoaderData { - users: User[]; -} - export const meta: MetaFunction = () => { return { title: "Users" }; }; -export const loader: LoaderFunction = async () => { - return json({ users }); +export const loader = async () => { + return json({ users }); }; export default function Users() { - const { users } = useLoaderData(); + const { users } = useLoaderData(); return (
    diff --git a/outlet-form-rerender/app/routes/users/$userId.tsx b/outlet-form-rerender/app/routes/users/$userId.tsx index 384cf1a0..58efb698 100644 --- a/outlet-form-rerender/app/routes/users/$userId.tsx +++ b/outlet-form-rerender/app/routes/users/$userId.tsx @@ -1,22 +1,17 @@ -import type { LoaderFunction, MetaFunction } from "@remix-run/node"; +import type { LoaderArgs, MetaFunction } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Form, useCatch, useLoaderData, useLocation } from "@remix-run/react"; -import type { User as UserType } from "~/data.server"; import { users } from "~/data.server"; -interface LoaderData { - user: UserType; -} - -export const meta: MetaFunction = ({ data }: { data: LoaderData | null }) => { +export const meta: MetaFunction = ({ data }) => { if (!data) { return { title: "User not found!" }; } return { title: data.user.name }; }; -export const loader: LoaderFunction = async ({ params }) => { +export const loader = async ({ params }: LoaderArgs) => { const userId = params.userId; const user = users.find(({ id }) => id === userId); @@ -25,11 +20,11 @@ export const loader: LoaderFunction = async ({ params }) => { throw json(null, { status: 404 }); } - return json({ user }); + return json({ user }); }; export default function User() { - const { user } = useLoaderData(); + const { user } = useLoaderData(); const location = useLocation(); return ( diff --git a/pm-app/app/models.ts b/pm-app/app/models.ts index 565051cb..f2d7649f 100644 --- a/pm-app/app/models.ts +++ b/pm-app/app/models.ts @@ -17,7 +17,6 @@ export type TodoList = _TodoList & { }; export type UserSecure = Omit; -export type UserPublic = Omit; export type TodoData = Omit< Pick & Partial>, diff --git a/pm-app/app/root.tsx b/pm-app/app/root.tsx index 973c3e4c..1d4f8060 100644 --- a/pm-app/app/root.tsx +++ b/pm-app/app/root.tsx @@ -1,8 +1,4 @@ -import type { - LinksFunction, - LoaderFunction, - MetaFunction, -} from "@remix-run/node"; +import type { LinksFunction, MetaFunction } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Links, @@ -23,18 +19,12 @@ export const links: LinksFunction = () => { return [{ rel: "stylesheet", href: global }]; }; -interface LoaderData { - ENV: Exclude; -} - -export const loader: LoaderFunction = async () => { - const data: LoaderData = { +export const loader = async () => { + return json({ ENV: { SITE_URL: process.env.SITE_URL, }, - }; - - return json(data); + }); }; export const meta: MetaFunction = () => ({ diff --git a/pm-app/app/routes/dashboard.tsx b/pm-app/app/routes/dashboard.tsx index 185fb605..ba8454ef 100644 --- a/pm-app/app/routes/dashboard.tsx +++ b/pm-app/app/routes/dashboard.tsx @@ -1,8 +1,4 @@ -import type { - LinksFunction, - LoaderFunction, - MetaFunction, -} from "@remix-run/node"; +import type { LinksFunction, LoaderArgs, MetaFunction } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Outlet, useCatch } from "@remix-run/react"; import * as React from "react"; @@ -13,7 +9,7 @@ import { MaxContainer } from "~/ui/max-container"; import { Heading, Section } from "~/ui/section-heading"; import { requireUser } from "~/session.server"; -export const loader: LoaderFunction = async ({ request }) => { +export const loader = async ({ request }: LoaderArgs) => { const { passwordHash, ...secureUser } = await requireUser(request, { redirect: "/sign-in", }); @@ -22,11 +18,11 @@ export const loader: LoaderFunction = async ({ request }) => { }); }; -export const links: LinksFunction = () => { - return [{ rel: "stylesheet", href: stylesUrl }]; -}; +export const links: LinksFunction = () => [ + { rel: "stylesheet", href: stylesUrl }, +]; -export const meta: MetaFunction = ({ params, data, location, parentsData }) => { +export const meta: MetaFunction = ({ parentsData }) => { let userName: string | null = parentsData?.root?.user?.name ?? null; userName = "Chance"; return { @@ -88,7 +84,7 @@ function Layout({ } export default function DashboardLayout() { - // let { currentYear } = useLoaderData(); + // let { currentYear } = useLoaderData(); return ( diff --git a/pm-app/app/routes/dashboard/index.tsx b/pm-app/app/routes/dashboard/index.tsx index 9a5853bc..2d0f13bb 100644 --- a/pm-app/app/routes/dashboard/index.tsx +++ b/pm-app/app/routes/dashboard/index.tsx @@ -1,9 +1,9 @@ -import type { LinksFunction, LoaderFunction } from "@remix-run/node"; +import type { LinksFunction, LoaderArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { useCatch, useFetcher, useLoaderData } from "@remix-run/react"; import * as React from "react"; -import type { UserSecure, Project } from "~/models"; +import type { Project } from "~/models"; import { Heading, Section } from "~/ui/section-heading"; import { MaxContainer } from "~/ui/max-container"; import stylesUrl from "~/dist/styles/routes/dashboard/index.css"; @@ -24,24 +24,21 @@ export const links: LinksFunction = () => { return [{ rel: "stylesheet", href: stylesUrl }]; }; -export const loader: LoaderFunction = async ({ request }) => { +export const loader = async ({ request }: LoaderArgs) => { const { passwordHash, ...secureUser } = await requireUser(request, { redirect: "/sign-in", }); const projects = await getUserProjects(secureUser.id); - const data: LoaderData = { + return json({ user: secureUser, projects, - }; - - return json(data); + }); }; export default function DashboardIndex() { - const loaderData = useLoaderData(); - const { user, projects } = loaderData; + const { user, projects } = useLoaderData(); const { nameFirst } = user; const deleteFetcher = useFetcher(); const deleteFormRef = React.useRef(null); @@ -188,8 +185,3 @@ export function ErrorBoundary({ error }: { error: Error }) {
    ); } - -interface LoaderData { - user: UserSecure | null; - projects: Project[]; -} diff --git a/pm-app/app/routes/dashboard/projects/$projectId.tsx b/pm-app/app/routes/dashboard/projects/$projectId.tsx index f22e15e0..077cc4e9 100644 --- a/pm-app/app/routes/dashboard/projects/$projectId.tsx +++ b/pm-app/app/routes/dashboard/projects/$projectId.tsx @@ -1,13 +1,8 @@ -import type { - LinksFunction, - LoaderFunction, - MetaFunction, -} from "@remix-run/node"; +import type { LinksFunction, LoaderArgs, MetaFunction } from "@remix-run/node"; import { json, redirect } from "@remix-run/node"; import { Form, Outlet, - useActionData, useFetcher, useLoaderData, useTransition, @@ -20,7 +15,7 @@ import stylesUrl from "~/dist/styles/routes/dashboard/projects/$projectId/index. import { Link } from "~/ui/link"; import { requireUser } from "~/session.server"; import { getProject, getUsers } from "~/db.server"; -import type { Project, UserSecure } from "~/models"; +import type { UserSecure } from "~/models"; import { DropdownMenu, DropdownMenuOptionsButton, @@ -54,7 +49,7 @@ export const meta: MetaFunction = ({ data }) => { }; }; -export const loader: LoaderFunction = async ({ request, params }) => { +export const loader = async ({ params, request }: LoaderArgs) => { const { passwordHash, ...user } = await requireUser(request, { redirect: "/sign-in", }); @@ -69,12 +64,12 @@ export const loader: LoaderFunction = async ({ request, params }) => { throw redirect("/dashboard"); } - return json({ project, user, allUsers }); + return json({ project, user, allUsers }); }; export default function ProjectRoute() { - const { project, allUsers, user } = useLoaderData(); - const actionData = useActionData(); + const { project, allUsers, user } = useLoaderData(); + const actionData: ActionData = {}; const { fieldErrors } = actionData || {}; const [showTeamDialog, setShowTeamDialog] = React.useState(false); @@ -487,17 +482,11 @@ function Layout({ ); } -interface LoaderData { - project: Project; - user: UserSecure; - allUsers: UserSecure[]; -} - -interface ActionData { +type ActionData = { formError?: string; fieldErrors?: FieldErrors; fields?: Fields; -} +}; type FieldErrors = Record; diff --git a/pm-app/app/routes/dashboard/projects/$projectId/delete.tsx b/pm-app/app/routes/dashboard/projects/$projectId/delete.tsx index 1c5af7c5..9c7de332 100644 --- a/pm-app/app/routes/dashboard/projects/$projectId/delete.tsx +++ b/pm-app/app/routes/dashboard/projects/$projectId/delete.tsx @@ -1,10 +1,10 @@ -import type { ActionFunction } from "@remix-run/node"; +import type { ActionArgs } from "@remix-run/node"; import { redirect } from "@remix-run/node"; import { deleteProject } from "~/db.server"; import { requireUser } from "~/session.server"; -export const action: ActionFunction = async ({ request, params }) => { +export const action = async ({ params, request }: ActionArgs) => { await requireUser(request, { redirect: "/sign-in", }); diff --git a/pm-app/app/routes/dashboard/projects/$projectId/list/$listId.tsx b/pm-app/app/routes/dashboard/projects/$projectId/list/$listId.tsx index 043554f1..909d1528 100644 --- a/pm-app/app/routes/dashboard/projects/$projectId/list/$listId.tsx +++ b/pm-app/app/routes/dashboard/projects/$projectId/list/$listId.tsx @@ -1,7 +1,7 @@ import type { - ActionFunction, + ActionArgs, LinksFunction, - LoaderFunction, + LoaderArgs, MetaFunction, } from "@remix-run/node"; import { json, redirect } from "@remix-run/node"; @@ -19,7 +19,7 @@ import { updateTodo, updateTodoList, } from "~/db.server"; -import type { TodoList as TTodoList, Project, Todo } from "~/models"; +import type { TodoList as TTodoList, Todo } from "~/models"; import { Field, FieldProvider, Label } from "~/ui/form"; import { Button } from "~/ui/button"; import { TodoItem, TodoList } from "~/ui/todo-list"; @@ -37,7 +37,7 @@ export const meta: MetaFunction = ({ data }) => { }; }; -export const loader: LoaderFunction = async ({ request, params }) => { +export const loader = async ({ params, request }: LoaderArgs) => { const listId = params.listId as string; await requireUser(request, { redirect: "/sign-in", @@ -58,11 +58,10 @@ export const loader: LoaderFunction = async ({ request, params }) => { throw redirect("/dashboard"); } - const data: LoaderData = { todoList, projects, project }; - return json(data); + return json({ todoList, projects, project }); }; -export const action: ActionFunction = async ({ request, params }) => { +export const action = async ({ params, request }: ActionArgs) => { await requireUser(request, { redirect: "/sign-in", }); @@ -93,10 +92,9 @@ export const action: ActionFunction = async ({ request, params }) => { } const fieldErrors: FieldErrors = { project: null }; if (projectId != null && typeof projectId !== "string") { - const data: ActionData = { + return json({ formError: `Something went wrong. Please try again later.`, - }; - return json(data); + }); } const fields: Fields = { project: projectId }; if (Object.values(fieldErrors).some(Boolean)) { @@ -105,19 +103,17 @@ export const action: ActionFunction = async ({ request, params }) => { if (projectId) { await updateTodoList(listId, { projectId }); } - const data: ActionData = { + return json({ fieldErrors, fields, - }; - return json(data); + }); } - const data: ActionData = {}; - return json(data); + return json({}); }; function TodoListRoute() { - const { todoList, project } = useLoaderData(); + const { todoList, project } = useLoaderData(); const fetchers = useFetchers(); const taskFetcherMap = new Map(); @@ -275,18 +271,6 @@ function NewTodoForm({ listId }: { listId: TTodoList["id"] }) { export default TodoListRoute; -interface LoaderData { - todoList: TTodoList; - projects: Project[]; - project: Project; -} - -interface ActionData { - formError?: string; - fieldErrors?: FieldErrors; - fields?: Fields; -} - type Fields = Record; type FieldErrors = Record; diff --git a/pm-app/app/routes/dashboard/projects/new.tsx b/pm-app/app/routes/dashboard/projects/new.tsx index 0ebdb7a8..c8f39284 100644 --- a/pm-app/app/routes/dashboard/projects/new.tsx +++ b/pm-app/app/routes/dashboard/projects/new.tsx @@ -1,13 +1,8 @@ import * as React from "react"; -import type { - ActionFunction, - LinksFunction, - LoaderFunction, -} from "@remix-run/node"; +import type { ActionArgs, LinksFunction, LoaderArgs } from "@remix-run/node"; import { json, redirect } from "@remix-run/node"; import { Form, useActionData, useCatch, useLoaderData } from "@remix-run/react"; -import type { UserSecure } from "~/models"; import { Heading } from "~/ui/section-heading"; import { MaxContainer } from "~/ui/max-container"; import { requireUser } from "~/session.server"; @@ -26,22 +21,20 @@ export const links: LinksFunction = () => { return [{ rel: "stylesheet", href: stylesUrl }]; }; -export const loader: LoaderFunction = async ({ request }) => { +export const loader = async ({ request }: LoaderArgs) => { const { passwordHash, ...secureUser } = await requireUser(request, { redirect: "/sign-in", }); const allUsers = await getUsers(); - const loaderData: LoaderData = { + return json({ user: secureUser, allUsers: allUsers, - }; - - return json(loaderData); + }); }; -export const action: ActionFunction = async ({ request }) => { +export const action = async ({ request }: ActionArgs) => { const currentUser = await requireUser(request, { redirect: "/sign-in", }); @@ -69,11 +62,10 @@ export const action: ActionFunction = async ({ request }) => { ) { throw Error("blergh"); } - } catch (_) { - const data: ActionData = { + } catch { + return json({ formError: `Something went wrong. Please try again later.`, - }; - return json(data); + }); } const fields = { name, description, members }; @@ -97,19 +89,16 @@ export const action: ActionFunction = async ({ request }) => { members, }); return redirect(`dashboard/projects/${project.id}`); - } catch (_) { - const data: ActionData = { + } catch { + return json({ formError: `Something went wrong. Please try again later.`, - }; - return json(data); + }); } }; function NewProject() { - const loaderData = useLoaderData(); - const actionData = useActionData() || {}; - const { fieldErrors, fields, formError } = actionData; - const { allUsers, user } = loaderData; + const { allUsers, user } = useLoaderData(); + const { fieldErrors, fields, formError } = useActionData(); const selectableUsers = React.useMemo(() => { return allUsers.filter((u) => u.id !== user.id); @@ -246,17 +235,6 @@ export function ErrorBoundary({ error }: { error: Error }) { ); } -interface LoaderData { - user: UserSecure; - allUsers: UserSecure[]; -} - -interface ActionData { - formError?: string; - fieldErrors?: FieldErrors; - fields?: Record; -} - type FieldErrors = Record; type TextFields = "name" | "description" | "members"; diff --git a/pm-app/app/routes/dashboard/todo-lists/$listId/delete.tsx b/pm-app/app/routes/dashboard/todo-lists/$listId/delete.tsx index 0b4719f9..81569e33 100644 --- a/pm-app/app/routes/dashboard/todo-lists/$listId/delete.tsx +++ b/pm-app/app/routes/dashboard/todo-lists/$listId/delete.tsx @@ -1,10 +1,10 @@ -import type { ActionFunction, LoaderFunction } from "@remix-run/node"; +import type { ActionArgs, LoaderArgs } from "@remix-run/node"; import { redirect } from "@remix-run/node"; import { deleteTodoList } from "~/db.server"; import { requireUser } from "~/session.server"; -export const action: ActionFunction = async ({ request, params }) => { +export const action = async ({ params, request }: ActionArgs) => { await requireUser(request, { redirect: "/sign-in", }); @@ -15,7 +15,7 @@ export const action: ActionFunction = async ({ request, params }) => { return redirect("/dashboard"); }; -export const loader: LoaderFunction = async ({ request, params }) => { +export const loader = async ({ params, request }: LoaderArgs) => { await requireUser(request, { redirect: "/sign-in", }); diff --git a/pm-app/app/routes/dashboard/todo-lists/$listId/index.tsx b/pm-app/app/routes/dashboard/todo-lists/$listId/index.tsx index 2ae3c2fd..83bc6c21 100644 --- a/pm-app/app/routes/dashboard/todo-lists/$listId/index.tsx +++ b/pm-app/app/routes/dashboard/todo-lists/$listId/index.tsx @@ -1,7 +1,7 @@ import type { - ActionFunction, + ActionArgs, LinksFunction, - LoaderFunction, + LoaderArgs, MetaFunction, } from "@remix-run/node"; import { json, redirect } from "@remix-run/node"; @@ -20,7 +20,7 @@ import { updateTodo, updateTodoList, } from "~/db.server"; -import type { TodoList as TTodoList, Project, Todo } from "~/models"; +import type { TodoList as TTodoList, Todo } from "~/models"; import { Field, FieldProvider, Label } from "~/ui/form"; import { Button } from "~/ui/button"; import { TodoItem, TodoList } from "~/ui/todo-list"; @@ -40,7 +40,7 @@ export const meta: MetaFunction = ({ data }) => { }; }; -export const loader: LoaderFunction = async ({ request, params }) => { +export const loader = async ({ params, request }: LoaderArgs) => { const listId = params.listId as string; await requireUser(request, { redirect: "/sign-in", @@ -62,11 +62,10 @@ export const loader: LoaderFunction = async ({ request, params }) => { throw redirect("/dashboard"); } - const data: LoaderData = { todoList, projects, project }; - return json(data); + return json({ todoList, projects, project }); }; -export const action: ActionFunction = async ({ request, params }) => { +export const action = async ({ params, request }: ActionArgs) => { await requireUser(request, { redirect: "/sign-in", }); @@ -97,10 +96,9 @@ export const action: ActionFunction = async ({ request, params }) => { } const fieldErrors: FieldErrors = { project: null }; if (projectId != null && typeof projectId !== "string") { - const data: ActionData = { + return json({ formError: `Something went wrong. Please try again later.`, - }; - return json(data); + }); } const fields: Fields = { project: projectId }; if (Object.values(fieldErrors).some(Boolean)) { @@ -109,19 +107,17 @@ export const action: ActionFunction = async ({ request, params }) => { if (projectId) { await updateTodoList(listId, { projectId }); } - const data: ActionData = { + return json({ fieldErrors, fields, - }; - return json(data); + }); } - const data: ActionData = {}; - return json(data); + return json({}); }; function TodoListRoute() { - const { todoList, project } = useLoaderData(); + const { todoList, project } = useLoaderData(); const fetchers = useFetchers(); const taskFetcherMap = new Map(); @@ -279,18 +275,6 @@ function NewTodoForm({ listId }: { listId: TTodoList["id"] }) { export default TodoListRoute; -interface LoaderData { - todoList: TTodoList; - projects: Project[]; - project: Project; -} - -interface ActionData { - formError?: string; - fieldErrors?: FieldErrors; - fields?: Fields; -} - type Fields = Record; type FieldErrors = Record; diff --git a/pm-app/app/routes/dashboard/todo-lists/index.tsx b/pm-app/app/routes/dashboard/todo-lists/index.tsx index f746ef69..c48f1ecc 100644 --- a/pm-app/app/routes/dashboard/todo-lists/index.tsx +++ b/pm-app/app/routes/dashboard/todo-lists/index.tsx @@ -1,26 +1,22 @@ -import type { LoaderFunction } from "@remix-run/node"; +import type { LoaderArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Link, useLoaderData } from "@remix-run/react"; import * as React from "react"; import { getAllTodoLists } from "~/db.server"; -import type { TodoList } from "~/models"; import { requireUser } from "~/session.server"; -export const loader: LoaderFunction = async ({ request }) => { +export const loader = async ({ request }: LoaderArgs) => { await requireUser(request, { redirect: "/sign-in", }); const lists = await getAllTodoLists(); - return json({ - lists, - }); + return json({ lists }); }; export default function AllLists() { - const loaderData = useLoaderData(); - const lists: TodoList[] = loaderData.lists; + const { lists } = useLoaderData(); return (
    diff --git a/pm-app/app/routes/dashboard/todo-lists/new.tsx b/pm-app/app/routes/dashboard/todo-lists/new.tsx index 1fed399d..fa22b53f 100644 --- a/pm-app/app/routes/dashboard/todo-lists/new.tsx +++ b/pm-app/app/routes/dashboard/todo-lists/new.tsx @@ -1,8 +1,8 @@ import * as React from "react"; import type { - ActionFunction, + ActionArgs, LinksFunction, - LoaderFunction, + LoaderArgs, RouteComponent, } from "@remix-run/node"; import { json, redirect } from "@remix-run/node"; @@ -14,7 +14,7 @@ import { useSearchParams, } from "@remix-run/react"; -import type { UserSecure, TodoDataUnordered, Project } from "~/models"; +import type { TodoDataUnordered } from "~/models"; import { Heading } from "~/ui/section-heading"; import { MaxContainer } from "~/ui/max-container"; import { requireUser } from "~/session.server"; @@ -34,26 +34,24 @@ import { TokenDismissButton } from "../../../ui/token"; type TempTodo = TodoDataUnordered & { _tempId: number }; -export const links: LinksFunction = () => { - return [{ rel: "stylesheet", href: stylesUrl }]; -}; +export const links: LinksFunction = () => [ + { rel: "stylesheet", href: stylesUrl }, +]; -export const loader: LoaderFunction = async ({ request, params }) => { +export const loader = async ({ request }: LoaderArgs) => { const { passwordHash, ...secureUser } = await requireUser(request, { redirect: "/sign-in", }); const projects = await getUserProjects(secureUser.id); - const loaderData: LoaderData = { + return json({ user: secureUser, projects, - }; - - return json(loaderData); + }); }; -export const action: ActionFunction = async ({ request, context, params }) => { +export const action = async ({ request }: ActionArgs) => { await requireUser(request, { redirect: "/sign-in", }); @@ -90,11 +88,10 @@ export const action: ActionFunction = async ({ request, context, params }) => { ) { throw Error("blergh"); } - } catch (_) { - const data: ActionData = { + } catch { + return json({ formError: `Something went wrong. Please try again later.`, - }; - return json(data); + }); } const fields = { name, description, todos }; @@ -122,16 +119,15 @@ export const action: ActionFunction = async ({ request, context, params }) => { ? redirect(`dashboard/projects/${projectId}`) : redirect(`dashboard/todo-lists/${todoList.id}`); } catch (_) { - const data: ActionData = { + return json({ formError: `Something went wrong. Please try again later.`, - }; - return json(data); + }); } }; const NewTodoList: RouteComponent = () => { - const actionData = useActionData() || {}; - const { projects } = useLoaderData(); + const actionData = useActionData() || {}; + const { projects } = useLoaderData(); const [searchParams] = useSearchParams(); const { fieldErrors, fields, formError } = actionData; const [todos, setTodos] = React.useState([]); @@ -443,17 +439,6 @@ function handleTodoListKeyDown(event: React.KeyboardEvent) { } } -interface LoaderData { - user: UserSecure; - projects: Project[]; -} - -interface ActionData { - formError?: string; - fieldErrors?: FieldErrors; - fields?: Record; -} - type FieldErrors = Record; type TextFields = "name" | "description" | "todos"; diff --git a/pm-app/app/routes/dashboard/todos/$todoId/delete.tsx b/pm-app/app/routes/dashboard/todos/$todoId/delete.tsx index 2e531479..880ca870 100644 --- a/pm-app/app/routes/dashboard/todos/$todoId/delete.tsx +++ b/pm-app/app/routes/dashboard/todos/$todoId/delete.tsx @@ -1,35 +1,26 @@ -import type { ActionFunction } from "@remix-run/node"; +import type { ActionArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { requireUser } from "~/session.server"; import { deleteTodo } from "~/db.server"; -import type { Todo } from "~/models"; -export const action: ActionFunction = async ({ request, params }) => { +export const action = async ({ params, request }: ActionArgs) => { await requireUser(request, { redirect: "/sign-in", }); - let actionData: ActionData; if (request.method.toLowerCase() === "post") { const todoId = params.todoId as string; if (!todoId || typeof todoId !== "string") { - actionData = { todo: null }; - throw json(actionData, 400); + throw json({ todo: null }, 400); } try { - actionData = { todo: await deleteTodo(todoId) }; - return json(actionData); + return json({ todo: await deleteTodo(todoId) }); } catch { - actionData = { todo: null }; - return json(actionData, 400); + return json({ todo: null }, 400); } } return json({ todo: null }, 400); }; - -interface ActionData { - todo: Todo | null; -} diff --git a/pm-app/app/routes/dashboard/todos/$todoId/edit.tsx b/pm-app/app/routes/dashboard/todos/$todoId/edit.tsx index 3e8681f6..5be43543 100644 --- a/pm-app/app/routes/dashboard/todos/$todoId/edit.tsx +++ b/pm-app/app/routes/dashboard/todos/$todoId/edit.tsx @@ -1,23 +1,20 @@ -import type { ActionFunction } from "@remix-run/node"; +import type { ActionArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { requireUser } from "~/session.server"; import { updateTodo } from "~/db.server"; -import type { Todo } from "~/models"; import { Sanitizer } from "~/utils/sanitizer"; -export const action: ActionFunction = async ({ request, context, params }) => { +export const action = async ({ context, params, request }: ActionArgs) => { await requireUser(request, { redirect: "/sign-in", }); - let actionData: ActionData; if (request.method.toLowerCase() === "post") { const todoId = params.todoId as string; if (!todoId || typeof todoId !== "string") { - actionData = { todo: null }; - throw json(actionData, 400); + throw json({ todo: null }, 400); } try { @@ -48,16 +45,10 @@ export const action: ActionFunction = async ({ request, context, params }) => { } const todo = await updateTodo(todoId, todoUpdates); - actionData = { todo }; - return json(actionData, 200); + return json({ todo }, 200); } catch { - actionData = { todo: null }; - return json(actionData, 400); + return json({ todo: null }, 400); } } return json({ todo: null }, 400); }; - -interface ActionData { - todo: Todo | null; -} diff --git a/pm-app/app/routes/dashboard/todos/$todoId/index.tsx b/pm-app/app/routes/dashboard/todos/$todoId/index.tsx index b229a6b4..60c16cd3 100644 --- a/pm-app/app/routes/dashboard/todos/$todoId/index.tsx +++ b/pm-app/app/routes/dashboard/todos/$todoId/index.tsx @@ -1,11 +1,10 @@ -import type { ActionFunction, LoaderFunction } from "@remix-run/node"; +import type { ActionArgs, LoaderArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { requireUser } from "~/session.server"; import { getTodo, updateTodo } from "~/db.server"; -import type { Todo } from "~/models"; -export const loader: LoaderFunction = async ({ request, context, params }) => { +export const loader = async ({ params, request }: LoaderArgs) => { const todoId = params.todoId as string; await requireUser(request, { redirect: "/sign-in", @@ -14,28 +13,23 @@ export const loader: LoaderFunction = async ({ request, context, params }) => { const todo = await getTodo(todoId); if (!todo) { - const data: LoaderData = { todo: null }; - return json(data, 404); + return json({ todo: null }, 404); } - const data: LoaderData = { todo }; - return json(data); + return json({ todo }); }; -export const action: ActionFunction = async ({ request, context, params }) => { +export const action = async ({ params, request }: ActionArgs) => { await requireUser(request, { redirect: "/sign-in", }); - let actionData: ActionData; - // Toggle actions if (request.method.toLowerCase() === "post") { const todoId = params.todoId as string; if (!todoId || typeof todoId !== "string") { - actionData = { todo: null }; - throw json(actionData, 400); + throw json({ todo: null }, 400); } try { @@ -45,20 +39,10 @@ export const action: ActionFunction = async ({ request, context, params }) => { const todo = await updateTodo(todoId, { completed: status === "on", }); - actionData = { todo }; - return json(actionData, 200); + return json({ todo }, 200); } catch { - actionData = { todo: null }; - return json(actionData, 400); + return json({ todo: null }, 400); } } return json({ message: "Bad request", todo: null }, 400); }; - -interface LoaderData { - todo: Todo | null; -} - -interface ActionData { - todo: Todo | null; -} diff --git a/pm-app/app/routes/dashboard/todos/$todoId/set.tsx b/pm-app/app/routes/dashboard/todos/$todoId/set.tsx index 5916202d..58c6d665 100644 --- a/pm-app/app/routes/dashboard/todos/$todoId/set.tsx +++ b/pm-app/app/routes/dashboard/todos/$todoId/set.tsx @@ -1,22 +1,19 @@ -import type { ActionFunction } from "@remix-run/node"; +import type { ActionArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { requireUser } from "~/session.server"; import { updateTodo } from "~/db.server"; -import type { Todo } from "~/models"; -export const action: ActionFunction = async ({ request, params }) => { +export const action = async ({ params, request }: ActionArgs) => { await requireUser(request, { redirect: "/sign-in", }); - let actionData: ActionData; if (request.method.toLowerCase() === "post") { const todoId = params.todoId as string; if (!todoId || typeof todoId !== "string") { - actionData = { todo: null }; - throw json(actionData, 400); + throw json({ todo: null }, 400); } try { @@ -25,16 +22,10 @@ export const action: ActionFunction = async ({ request, params }) => { const todo = await updateTodo(todoId, { completed: status === "on", }); - actionData = { todo }; - return json(actionData, 200); + return json({ todo }, 200); } catch { - actionData = { todo: null }; - return json(actionData, 400); + return json({ todo: null }, 400); } } return json({ todo: null }, 400); }; - -interface ActionData { - todo: Todo | null; -} diff --git a/pm-app/app/routes/dashboard/todos/index.tsx b/pm-app/app/routes/dashboard/todos/index.tsx index f1c65e99..9d91f97d 100644 --- a/pm-app/app/routes/dashboard/todos/index.tsx +++ b/pm-app/app/routes/dashboard/todos/index.tsx @@ -1,4 +1,4 @@ -import type { ActionFunction, LoaderFunction } from "@remix-run/node"; +import type { ActionArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Form, @@ -9,16 +9,14 @@ import { import * as React from "react"; import { getAllTodos, getTodo, updateTodo } from "~/db.server"; -import type { Todo } from "~/models"; -export const loader: LoaderFunction = async () => { +export const loader = async () => { const todos = await getAllTodos(); - return json({ - todos, - }); + + return json({ todos }); }; -export const action: ActionFunction = async ({ request }) => { +export const action = async ({ request }: ActionArgs) => { const formData = await request.formData(); const todoId = formData.get("update") as string; const orderRaw = formData.get("order") || ""; @@ -32,12 +30,10 @@ export const action: ActionFunction = async ({ request }) => { return json({ todo }); }; -export default function Llllll() { - const loaderData = useLoaderData(); - const actionData = useActionData(); +export default function Index() { + const { todos } = useLoaderData(); + const { todo: nextTodo = null } = useActionData() || {}; const transtion = useTransition(); - const todos: Todo[] = loaderData.todos; - const nextTodo: Todo | null = actionData?.todo || null; const keyMapRef = React.useRef>(); if (!keyMapRef.current) { diff --git a/pm-app/app/routes/dashboard/todos/new.tsx b/pm-app/app/routes/dashboard/todos/new.tsx index b2acaa39..dbc14aae 100644 --- a/pm-app/app/routes/dashboard/todos/new.tsx +++ b/pm-app/app/routes/dashboard/todos/new.tsx @@ -1,24 +1,21 @@ -import type { ActionFunction } from "@remix-run/node"; +import type { ActionArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { requireUser } from "~/session.server"; import { createTodo, getTodosFromList } from "~/db.server"; -import type { Todo } from "~/models"; import { Sanitizer } from "~/utils/sanitizer"; -export const action: ActionFunction = async ({ request, params }) => { +export const action = async ({ params, request }: ActionArgs) => { await requireUser(request, { redirect: "/sign-in", }); - let actionData: ActionData; if (request.method.toLowerCase() === "post") { const formData = await request.formData(); const todoListId = params.listId || (formData.get("listId") as string); if (!todoListId || typeof todoListId !== "string") { - actionData = { todo: null }; - throw json(actionData, 400); + throw json({ todo: null }, 400); } const existingTodos = await getTodosFromList(todoListId); @@ -31,8 +28,7 @@ export const action: ActionFunction = async ({ request, params }) => { const order = existingTodos.length - 1; if (!name) { - actionData = { todo: null }; - throw json(actionData, 400); + throw json({ todo: null }, 400); } // TODO: Handle invalid inputs @@ -48,16 +44,10 @@ export const action: ActionFunction = async ({ request, params }) => { } const todo = await createTodo(todoData); - actionData = { todo }; - return json(actionData, 200); + return json({ todo }, 200); } catch { - actionData = { todo: null }; - return json(actionData, 400); + return json({ todo: null }, 400); } } return json({ todo: null }, 400); }; - -interface ActionData { - todo: Todo | null; -} diff --git a/pm-app/app/routes/dashboard/todos/toggle.tsx b/pm-app/app/routes/dashboard/todos/toggle.tsx index 65efca8c..bf308a68 100644 --- a/pm-app/app/routes/dashboard/todos/toggle.tsx +++ b/pm-app/app/routes/dashboard/todos/toggle.tsx @@ -1,10 +1,10 @@ -import type { ActionFunction } from "@remix-run/node"; +import type { ActionArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { getTodo, updateTodo } from "~/db.server"; import { requireUser } from "~/session.server"; -export const action: ActionFunction = async ({ request }) => { +export const action = async ({ request }: ActionArgs) => { await requireUser(request, { redirect: "/sign-in", }); diff --git a/pm-app/app/routes/index.tsx b/pm-app/app/routes/index.tsx index 71bb65e0..4e6f47f3 100644 --- a/pm-app/app/routes/index.tsx +++ b/pm-app/app/routes/index.tsx @@ -1,9 +1,9 @@ -import type { LoaderFunction } from "@remix-run/node"; +import type { LoaderArgs } from "@remix-run/node"; import { redirect } from "@remix-run/node"; import { getUser } from "~/session.server"; -export const loader: LoaderFunction = async ({ request }) => { +export const loader = async ({ request }: LoaderArgs) => { const user = await getUser(request); if (user) { return redirect("dashboard"); diff --git a/pm-app/app/routes/register.tsx b/pm-app/app/routes/register.tsx index b94960ed..f576239a 100644 --- a/pm-app/app/routes/register.tsx +++ b/pm-app/app/routes/register.tsx @@ -1,7 +1,7 @@ import type { - ActionFunction, + ActionArgs, LinksFunction, - LoaderFunction, + LoaderArgs, MetaFunction, } from "@remix-run/node"; import { json } from "@remix-run/node"; @@ -19,17 +19,15 @@ import { validateEmail, validatePassword } from "~/utils/validation"; import routeStyles from "../styles/routes/register.css"; -export const meta: MetaFunction = () => { - return { - title: "Register | PM Camp", - }; -}; +export const meta: MetaFunction = () => ({ + title: "Register | PM Camp", +}); export const links: LinksFunction = () => { return [{ href: routeStyles, rel: "stylesheet" }]; }; -export const loader: LoaderFunction = async ({ request }) => { +export const loader = async ({ request }: LoaderArgs) => { // let session = await sessionStorage.getSession(request.headers.get("Cookie")); // // If the user is already authenticated, just redirect to `/done` @@ -40,7 +38,7 @@ export const loader: LoaderFunction = async ({ request }) => { return json({}); }; -export const action: ActionFunction = async ({ request }) => { +export const action = async ({ request }: ActionArgs) => { // 1. Get/setup form data from the request const formData = await request.formData(); const fieldErrors = {} as FieldErrors; @@ -66,10 +64,9 @@ export const action: ActionFunction = async ({ request }) => { typeof fields.password !== "string" || typeof redirectTo !== "string" ) { - const data: ActionData = { + return json({ formError: `Something went wrong. Please try again later.`, - }; - return json(data); + }); } const { email, password, nameFirst, nameLast } = fields; @@ -128,7 +125,7 @@ export const action: ActionFunction = async ({ request }) => { }; export default function Register() { - const actionData = useActionData() || {}; + const actionData = useActionData() || {}; const { fieldErrors, fields, formError } = actionData; const [searchParams] = useSearchParams(); @@ -244,11 +241,6 @@ export default function Register() { ); } -interface ActionData { - formError?: string; - fieldErrors?: FieldErrors; - fields?: Record; -} type FieldErrors = Record; type TextFields = "email" | "password" | "nameFirst" | "nameLast"; diff --git a/pm-app/app/routes/sign-in.tsx b/pm-app/app/routes/sign-in.tsx index 6dfbbeab..7487989f 100644 --- a/pm-app/app/routes/sign-in.tsx +++ b/pm-app/app/routes/sign-in.tsx @@ -1,7 +1,7 @@ import type { - ActionFunction, + ActionArgs, LinksFunction, - LoaderFunction, + LoaderArgs, MetaFunction, } from "@remix-run/node"; import { json } from "@remix-run/node"; @@ -20,17 +20,15 @@ import { useFocusOnFormError } from "~/utils/react"; import routeStyles from "../styles/routes/sign-in.css"; -export const meta: MetaFunction = () => { - return { - title: "Sign In | PM Camp", - }; -}; +export const meta: MetaFunction = () => ({ + title: "Sign In | PM Camp", +}); -export const links: LinksFunction = () => { - return [{ href: routeStyles, rel: "stylesheet" }]; -}; +export const links: LinksFunction = () => [ + { href: routeStyles, rel: "stylesheet" }, +]; -export const action: ActionFunction = async ({ request }) => { +export const action = async ({ request }: ActionArgs) => { // 1. Get/setup form data from the request const formData = await request.formData(); const email = formData.get("email"); @@ -47,8 +45,11 @@ export const action: ActionFunction = async ({ request }) => { typeof password !== "string" || (redirectTo && typeof redirectTo !== "string") ) { - return json( - { formError: `Something went wrong. Please try again later.` }, + return json( + { + formError: `Something went wrong. Please try again later.`, + fieldErrors, + }, 400 ); } @@ -88,7 +89,7 @@ export const action: ActionFunction = async ({ request }) => { } if (Object.values(fieldErrors).some(Boolean)) { - return json({ fieldErrors, fields }, 400); + return json({ fieldErrors, fields }, 400); } // 3. Attempt login @@ -105,7 +106,7 @@ export const action: ActionFunction = async ({ request }) => { formError = "There was an error logging in. Please try again later."; } - return json({ fields, formError }, 401); + return json({ fields, formError }, 401); } // 4. Create a user session with the user's ID @@ -116,7 +117,7 @@ export const action: ActionFunction = async ({ request }) => { }); }; -export const loader: LoaderFunction = async ({ request }) => { +export const loader = async ({ request }: LoaderArgs) => { await redirectUser(request, { redirect: "/dashboard", }); @@ -124,8 +125,7 @@ export const loader: LoaderFunction = async ({ request }) => { }; export default function SignIn() { - const actionData = useActionData(); - const { fieldErrors, fields, formError } = actionData || {}; + const { fieldErrors, fields, formError } = useActionData(); const [searchParams] = useSearchParams(); const formRef = React.useRef(null); @@ -196,12 +196,6 @@ export default function SignIn() { ); } -interface ActionData { - formError?: string; - fieldErrors?: FieldErrors; - fields?: Record; -} - type FieldErrors = Record; type TextFields = "email" | "password"; diff --git a/pm-app/app/routes/sign-out.tsx b/pm-app/app/routes/sign-out.tsx index f1370e70..e411b55d 100644 --- a/pm-app/app/routes/sign-out.tsx +++ b/pm-app/app/routes/sign-out.tsx @@ -1,11 +1,11 @@ -import type { ActionFunction, LoaderFunction } from "@remix-run/node"; +import type { ActionArgs, LoaderArgs } from "@remix-run/node"; import { logout } from "~/session.server"; -export const action: ActionFunction = async ({ request }) => { +export const action = async ({ request }: ActionArgs) => { return logout(request, { redirect: "/sign-in" }); }; -export const loader: LoaderFunction = async ({ request }) => { +export const loader = async ({ request }: LoaderArgs) => { return logout(request, { redirect: "/sign-in" }); }; diff --git a/quirrel/app/routes/index.tsx b/quirrel/app/routes/index.tsx index ea6c02d7..9f4766f9 100644 --- a/quirrel/app/routes/index.tsx +++ b/quirrel/app/routes/index.tsx @@ -1,9 +1,8 @@ -import type { LoaderFunction } from "@remix-run/node"; import { json } from "@remix-run/node"; import greetingsQueue from "~/queues/greetings.server"; -export const loader: LoaderFunction = async () => { +export const loader = async () => { await greetingsQueue.enqueue("Groot"); return json({}); }; diff --git a/redis-upstash-session/app/routes/index.tsx b/redis-upstash-session/app/routes/index.tsx index f57ce21c..6231a125 100644 --- a/redis-upstash-session/app/routes/index.tsx +++ b/redis-upstash-session/app/routes/index.tsx @@ -1,10 +1,10 @@ -import type { LoaderFunction } from "@remix-run/node"; +import type { LoaderArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { useLoaderData } from "@remix-run/react"; import { commitSession, getSession } from "~/sessions.server"; -export const loader: LoaderFunction = async ({ request }) => { +export const loader = async ({ request }: LoaderArgs) => { // Get the session from the cookie const session = await getSession(request.headers.get("Cookie")); const myStoredData = session.get("myStoredData"); @@ -12,14 +12,8 @@ export const loader: LoaderFunction = async ({ request }) => { if (!myStoredData) { session.set("myStoredData", "Some data"); return json( - { - message: "Created new session", - }, - { - headers: { - "Set-Cookie": await commitSession(session), - }, - } + { message: "Created new session" }, + { headers: { "Set-Cookie": await commitSession(session) } } ); } // If session was found, present the session info. @@ -29,6 +23,6 @@ export const loader: LoaderFunction = async ({ request }) => { }; export default function IndexRoute() { - const data = useLoaderData(); + const data = useLoaderData(); return
    {data.message}
    ; } diff --git a/remix-auth-auth0/app/routes/auth0.tsx b/remix-auth-auth0/app/routes/auth0.tsx index b80ff884..5075bab2 100644 --- a/remix-auth-auth0/app/routes/auth0.tsx +++ b/remix-auth-auth0/app/routes/auth0.tsx @@ -1,10 +1,9 @@ -import type { ActionFunction, LoaderFunction } from "@remix-run/node"; +import type { ActionArgs } from "@remix-run/node"; import { redirect } from "@remix-run/node"; import { auth } from "~/utils/auth.server"; -export const loader: LoaderFunction = async () => redirect("/"); +export const loader = async () => redirect("/"); -export const action: ActionFunction = ({ request }) => { - return auth.authenticate("auth0", request); -}; +export const action = async ({ request }: ActionArgs) => + auth.authenticate("auth0", request); diff --git a/remix-auth-auth0/app/routes/callback.tsx b/remix-auth-auth0/app/routes/callback.tsx index e320e0f4..7df41991 100644 --- a/remix-auth-auth0/app/routes/callback.tsx +++ b/remix-auth-auth0/app/routes/callback.tsx @@ -1,8 +1,8 @@ -import type { LoaderFunction } from "@remix-run/node"; +import type { LoaderArgs } from "@remix-run/node"; import { auth } from "~/utils/auth.server"; -export const loader: LoaderFunction = async ({ request }) => { +export const loader = async ({ request }: LoaderArgs) => { return auth.authenticate("auth0", request, { successRedirect: "/private", failureRedirect: "/", diff --git a/remix-auth-auth0/app/routes/index.tsx b/remix-auth-auth0/app/routes/index.tsx index 307b4e07..0ef2a31f 100644 --- a/remix-auth-auth0/app/routes/index.tsx +++ b/remix-auth-auth0/app/routes/index.tsx @@ -1,22 +1,19 @@ -import type { LoaderFunction } from "@remix-run/node"; +import type { LoaderArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Form, useLoaderData } from "@remix-run/react"; import { auth, getSession } from "~/utils/auth.server"; -type LoaderData = { - error: { message: string } | null; -}; - -export const loader: LoaderFunction = async ({ request }) => { +type LoaderError = { message: string } | null; +export const loader = async ({ request }: LoaderArgs) => { await auth.isAuthenticated(request, { successRedirect: "/private" }); const session = await getSession(request.headers.get("Cookie")); - const error = session.get(auth.sessionErrorKey) as LoaderData["error"]; - return json({ error }); + const error = session.get(auth.sessionErrorKey) as LoaderError; + return json({ error }); }; export default function Screen() { - const { error } = useLoaderData(); + const { error } = useLoaderData(); return ( diff --git a/remix-auth-auth0/app/routes/logout.tsx b/remix-auth-auth0/app/routes/logout.tsx index 05f7230a..0e114d7a 100644 --- a/remix-auth-auth0/app/routes/logout.tsx +++ b/remix-auth-auth0/app/routes/logout.tsx @@ -1,4 +1,4 @@ -import type { ActionFunction } from "@remix-run/node"; +import type { ActionArgs } from "@remix-run/node"; import { redirect } from "@remix-run/node"; import { destroySession, getSession } from "~/utils/auth.server"; @@ -8,7 +8,7 @@ import { AUTH0_RETURN_TO_URL, } from "~/constants/index.server"; -export const action: ActionFunction = async ({ request }) => { +export const action = async ({ request }: ActionArgs) => { const session = await getSession(request.headers.get("Cookie")); const logoutURL = new URL(AUTH0_LOGOUT_URL); diff --git a/remix-auth-auth0/app/routes/private.tsx b/remix-auth-auth0/app/routes/private.tsx index 9a35115e..d767d1d3 100644 --- a/remix-auth-auth0/app/routes/private.tsx +++ b/remix-auth-auth0/app/routes/private.tsx @@ -1,22 +1,19 @@ -import type { LoaderFunction } from "@remix-run/node"; +import type { LoaderArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Form, useLoaderData } from "@remix-run/react"; -import type { Auth0Profile } from "remix-auth-auth0"; import { auth } from "~/utils/auth.server"; -type LoaderData = { profile: Auth0Profile }; - -export const loader: LoaderFunction = async ({ request }) => { +export const loader = async ({ request }: LoaderArgs) => { const profile = await auth.isAuthenticated(request, { failureRedirect: "/", }); - return json({ profile }); + return json({ profile }); }; export default function Screen() { - const { profile } = useLoaderData(); + const { profile } = useLoaderData(); return ( <> diff --git a/remix-auth-form/app/routes/login.tsx b/remix-auth-form/app/routes/login.tsx index 427d4406..f7e84bbe 100644 --- a/remix-auth-form/app/routes/login.tsx +++ b/remix-auth-form/app/routes/login.tsx @@ -1,31 +1,28 @@ -import type { ActionFunction, LoaderFunction } from "@remix-run/node"; +import type { ActionArgs, LoaderArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Form, useLoaderData } from "@remix-run/react"; import { auth, sessionStorage } from "~/auth.server"; -type LoaderData = { - error: { message: string } | null; -}; - -export const action: ActionFunction = async ({ request }) => { +export const action = async ({ request }: ActionArgs) => { await auth.authenticate("form", request, { successRedirect: "/private", failureRedirect: "/login", }); }; -export const loader: LoaderFunction = async ({ request }) => { +type LoaderError = { message: string } | null; +export const loader = async ({ request }: LoaderArgs) => { await auth.isAuthenticated(request, { successRedirect: "/private" }); const session = await sessionStorage.getSession( request.headers.get("Cookie") ); - const error = session.get(auth.sessionErrorKey) as LoaderData["error"]; - return json({ error }); + const error = session.get(auth.sessionErrorKey) as LoaderError; + return json({ error }); }; export default function Screen() { - const { error } = useLoaderData(); + const { error } = useLoaderData(); return ( diff --git a/remix-auth-form/app/routes/private.tsx b/remix-auth-form/app/routes/private.tsx index a46384e2..4dd5059f 100644 --- a/remix-auth-form/app/routes/private.tsx +++ b/remix-auth-form/app/routes/private.tsx @@ -1,25 +1,23 @@ -import type { ActionFunction, LoaderFunction } from "@remix-run/node"; +import type { ActionArgs, LoaderArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Form, useLoaderData } from "@remix-run/react"; import { auth } from "~/auth.server"; -type LoaderData = { email: string }; - -export const action: ActionFunction = async ({ request }) => { +export const action = async ({ request }: ActionArgs) => { await auth.logout(request, { redirectTo: "/login" }); }; -export const loader: LoaderFunction = async ({ request }) => { +export const loader = async ({ request }: LoaderArgs) => { const email = await auth.isAuthenticated(request, { failureRedirect: "/login", }); - return json({ email }); + return json({ email }); }; export default function Screen() { - const { email } = useLoaderData(); + const { email } = useLoaderData(); return ( <>

    Hello {email}

    diff --git a/remix-auth-github/app/routes/auth.github.callback.tsx b/remix-auth-github/app/routes/auth.github.callback.tsx index 1253420b..e0e96037 100644 --- a/remix-auth-github/app/routes/auth.github.callback.tsx +++ b/remix-auth-github/app/routes/auth.github.callback.tsx @@ -1,8 +1,8 @@ -import type { LoaderFunction } from "@remix-run/node"; +import type { LoaderArgs } from "@remix-run/node"; import { auth } from "~/auth.server"; -export const loader: LoaderFunction = async ({ request }) => { +export const loader = async ({ request }: LoaderArgs) => { return auth.authenticate("github", request, { successRedirect: "/private", failureRedirect: "/", diff --git a/remix-auth-github/app/routes/auth.github.tsx b/remix-auth-github/app/routes/auth.github.tsx index 4604be44..eb87311a 100644 --- a/remix-auth-github/app/routes/auth.github.tsx +++ b/remix-auth-github/app/routes/auth.github.tsx @@ -1,8 +1,8 @@ -import type { ActionFunction } from "@remix-run/node"; +import type { ActionArgs } from "@remix-run/node"; import { auth } from "~/auth.server"; -export const action: ActionFunction = async ({ request }) => { +export const action = async ({ request }: ActionArgs) => { return await auth.authenticate("github", request, { successRedirect: "/private", failureRedirect: "/", diff --git a/remix-auth-github/app/routes/index.tsx b/remix-auth-github/app/routes/index.tsx index cef9338c..69e07d43 100644 --- a/remix-auth-github/app/routes/index.tsx +++ b/remix-auth-github/app/routes/index.tsx @@ -1,24 +1,21 @@ -import type { LoaderFunction } from "@remix-run/node"; +import type { LoaderArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Form, useLoaderData } from "@remix-run/react"; import { auth, sessionStorage } from "~/auth.server"; -type LoaderData = { - error: { message: string } | null; -}; - -export const loader: LoaderFunction = async ({ request }) => { +type LoaderError = { message: string } | null; +export const loader = async ({ request }: LoaderArgs) => { await auth.isAuthenticated(request, { successRedirect: "/private" }); const session = await sessionStorage.getSession( request.headers.get("Cookie") ); - const error = session.get(auth.sessionErrorKey) as LoaderData["error"]; - return json({ error }); + const error = session.get(auth.sessionErrorKey) as LoaderError; + return json({ error }); }; export default function Screen() { - const { error } = useLoaderData(); + const { error } = useLoaderData(); return ( diff --git a/remix-auth-github/app/routes/private.tsx b/remix-auth-github/app/routes/private.tsx index 5ae061e0..8c74ac21 100644 --- a/remix-auth-github/app/routes/private.tsx +++ b/remix-auth-github/app/routes/private.tsx @@ -1,26 +1,23 @@ -import type { ActionFunction, LoaderFunction } from "@remix-run/node"; +import type { ActionArgs, LoaderArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Form, useLoaderData } from "@remix-run/react"; -import type { GitHubProfile } from "remix-auth-github"; import { auth } from "~/auth.server"; -type LoaderData = { profile: GitHubProfile }; - -export const action: ActionFunction = async ({ request }) => { +export const action = async ({ request }: ActionArgs) => { await auth.logout(request, { redirectTo: "/" }); }; -export const loader: LoaderFunction = async ({ request }) => { +export const loader = async ({ request }: LoaderArgs) => { const { profile } = await auth.isAuthenticated(request, { failureRedirect: "/", }); - return json({ profile }); + return json({ profile }); }; export default function Screen() { - const { profile } = useLoaderData(); + const { profile } = useLoaderData(); return ( <> diff --git a/remix-auth-supabase-github/app/root.tsx b/remix-auth-supabase-github/app/root.tsx index 5f1072e4..3a9402e5 100644 --- a/remix-auth-supabase-github/app/root.tsx +++ b/remix-auth-supabase-github/app/root.tsx @@ -1,4 +1,4 @@ -import type { LoaderFunction, MetaFunction } from "@remix-run/node"; +import type { MetaFunction } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Links, @@ -10,7 +10,7 @@ import { useLoaderData, } from "@remix-run/react"; -export const loader: LoaderFunction = () => { +export const loader = async () => { return json({ env: { SUPABASE_URL: process.env.SUPABASE_URL, @@ -26,7 +26,7 @@ export const meta: MetaFunction = () => ({ }); export default function App() { - const { env } = useLoaderData(); + const { env } = useLoaderData(); return ( diff --git a/remix-auth-supabase-github/app/routes/login.tsx b/remix-auth-supabase-github/app/routes/login.tsx index b988d998..3d9bb9f5 100644 --- a/remix-auth-supabase-github/app/routes/login.tsx +++ b/remix-auth-supabase-github/app/routes/login.tsx @@ -1,22 +1,19 @@ -import type { ActionFunction, LoaderFunction } from "@remix-run/node"; +import type { ActionArgs, LoaderArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Form, useLoaderData } from "@remix-run/react"; import { authenticator, sessionStorage, supabaseStrategy } from "~/auth.server"; import { signInWithGithub } from "~/supabase.client"; -type LoaderData = { - error: { message: string } | null; -}; - -export const action: ActionFunction = async ({ request }) => { +export const action = async ({ request }: ActionArgs) => { await authenticator.authenticate("sb", request, { successRedirect: "/private", failureRedirect: "/login", }); }; -export const loader: LoaderFunction = async ({ request }) => { +type LoaderError = { message: string } | null; +export const loader = async ({ request }: LoaderArgs) => { await supabaseStrategy.checkSession(request, { successRedirect: "/private", }); @@ -25,15 +22,13 @@ export const loader: LoaderFunction = async ({ request }) => { request.headers.get("Cookie") ); - const error = session.get( - authenticator.sessionErrorKey - ) as LoaderData["error"]; + const error = session.get(authenticator.sessionErrorKey) as LoaderError; - return json({ error }); + return json({ error }); }; export default function Screen() { - const { error } = useLoaderData(); + const { error } = useLoaderData(); return ( <> diff --git a/remix-auth-supabase-github/app/routes/oauth.callback.tsx b/remix-auth-supabase-github/app/routes/oauth.callback.tsx index a58302cd..82339ee9 100644 --- a/remix-auth-supabase-github/app/routes/oauth.callback.tsx +++ b/remix-auth-supabase-github/app/routes/oauth.callback.tsx @@ -1,11 +1,11 @@ -import type { ActionFunction } from "@remix-run/node"; +import type { ActionArgs } from "@remix-run/node"; import { useSubmit } from "@remix-run/react"; import { useEffect } from "react"; import { authenticator } from "~/auth.server"; import { supabaseClient } from "~/supabase.client"; -export const action: ActionFunction = async ({ request }) => { +export const action = async ({ request }: ActionArgs) => { await authenticator.authenticate("sb-oauth", request, { successRedirect: "/private", failureRedirect: "/login", diff --git a/remix-auth-supabase-github/app/routes/private.tsx b/remix-auth-supabase-github/app/routes/private.tsx index 7ea5e032..f5ca54d0 100644 --- a/remix-auth-supabase-github/app/routes/private.tsx +++ b/remix-auth-supabase-github/app/routes/private.tsx @@ -1,25 +1,23 @@ -import type { ActionFunction, LoaderFunction } from "@remix-run/node"; +import type { ActionArgs, LoaderArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Form, useLoaderData } from "@remix-run/react"; import { authenticator, supabaseStrategy } from "~/auth.server"; -type LoaderData = { email?: string }; - -export const action: ActionFunction = async ({ request }) => { +export const action = async ({ request }: ActionArgs) => { await authenticator.logout(request, { redirectTo: "/login" }); }; -export const loader: LoaderFunction = async ({ request }) => { +export const loader = async ({ request }: LoaderArgs) => { const session = await supabaseStrategy.checkSession(request, { failureRedirect: "/login", }); - return json({ email: session.user?.email }); + return json({ email: session.user?.email }); }; export default function Screen() { - const { email } = useLoaderData(); + const { email } = useLoaderData(); return ( <>

    Hello {email}

    diff --git a/remix-auth-supabase/app/routes/login.tsx b/remix-auth-supabase/app/routes/login.tsx index 3663de25..7d306deb 100644 --- a/remix-auth-supabase/app/routes/login.tsx +++ b/remix-auth-supabase/app/routes/login.tsx @@ -1,21 +1,18 @@ -import type { ActionFunction, LoaderFunction } from "@remix-run/node"; +import type { ActionArgs, LoaderArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Form, useLoaderData } from "@remix-run/react"; import { authenticator, sessionStorage, supabaseStrategy } from "~/auth.server"; -type LoaderData = { - error: { message: string } | null; -}; - -export const action: ActionFunction = async ({ request }) => { +export const action = async ({ request }: ActionArgs) => { await authenticator.authenticate("sb", request, { successRedirect: "/private", failureRedirect: "/login", }); }; -export const loader: LoaderFunction = async ({ request }) => { +type LoaderError = { message: string } | null; +export const loader = async ({ request }: LoaderArgs) => { await supabaseStrategy.checkSession(request, { successRedirect: "/private", }); @@ -24,15 +21,13 @@ export const loader: LoaderFunction = async ({ request }) => { request.headers.get("Cookie") ); - const error = session.get( - authenticator.sessionErrorKey - ) as LoaderData["error"]; + const error = session.get(authenticator.sessionErrorKey) as LoaderError; - return json({ error }); + return json({ error }); }; export default function Screen() { - const { error } = useLoaderData(); + const { error } = useLoaderData(); return ( diff --git a/remix-auth-supabase/app/routes/private.tsx b/remix-auth-supabase/app/routes/private.tsx index f0d5a21b..65a69c3d 100644 --- a/remix-auth-supabase/app/routes/private.tsx +++ b/remix-auth-supabase/app/routes/private.tsx @@ -1,25 +1,23 @@ -import type { ActionFunction, LoaderFunction } from "@remix-run/node"; +import type { ActionArgs, LoaderArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Form, useLoaderData } from "@remix-run/react"; import { authenticator, supabaseStrategy } from "~/auth.server"; -type LoaderData = { email?: string }; - -export const action: ActionFunction = async ({ request }) => { +export const action = async ({ request }: ActionArgs) => { await authenticator.logout(request, { redirectTo: "/" }); }; -export const loader: LoaderFunction = async ({ request }) => { +export const loader = async ({ request }: LoaderArgs) => { const session = await supabaseStrategy.checkSession(request, { failureRedirect: "/login", }); - return json({ email: session.user?.email }); + return json({ email: session.user?.email }); }; export default function Screen() { - const { email } = useLoaderData(); + const { email } = useLoaderData(); return ( <>

    Hello {email}

    diff --git a/route-modal/app/routes/invoices.tsx b/route-modal/app/routes/invoices.tsx index dfb90570..f942747a 100644 --- a/route-modal/app/routes/invoices.tsx +++ b/route-modal/app/routes/invoices.tsx @@ -1,8 +1,8 @@ -import type { LoaderFunction } from "@remix-run/node"; +import type { LoaderArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Link, Outlet, useLoaderData } from "@remix-run/react"; -export const loader: LoaderFunction = async ({ params }) => { +export const loader = async ({ params }: LoaderArgs) => { const invoices = [ { id: 1, @@ -23,7 +23,7 @@ export const loader: LoaderFunction = async ({ params }) => { }; export default function Invoices() { - const data = useLoaderData(); + const data = useLoaderData(); return ( <> diff --git a/route-modal/app/routes/invoices/$id/edit.tsx b/route-modal/app/routes/invoices/$id/edit.tsx index 77f2a1dc..146224c9 100644 --- a/route-modal/app/routes/invoices/$id/edit.tsx +++ b/route-modal/app/routes/invoices/$id/edit.tsx @@ -1,26 +1,17 @@ import Dialog from "@reach/dialog"; import styles from "@reach/dialog/styles.css"; -import type { - ActionFunction, - LinksFunction, - LoaderFunction, -} from "@remix-run/node"; +import type { ActionArgs, LinksFunction, LoaderArgs } from "@remix-run/node"; import { json, redirect } from "@remix-run/node"; import { Form, useLoaderData, useNavigate } from "@remix-run/react"; import * as React from "react"; -export const links: LinksFunction = () => { - return [ - { - rel: "stylesheet", - href: styles, - }, - ]; -}; +export const links: LinksFunction = () => [{ rel: "stylesheet", href: styles }]; -export const loader: LoaderFunction = async ({ params }) => { +export const loader = async ({ params }: LoaderArgs) => { const id = params.id; - if (!id) return null; + if (!id) { + return json({}); + } const invoices = [ { @@ -43,7 +34,7 @@ export const loader: LoaderFunction = async ({ params }) => { return json(invoice); }; -export const action: ActionFunction = async ({ request }) => { +export const action = async ({ request }: ActionArgs) => { // Here we can update our database with the updated invoice // Redirect back to invoice list @@ -52,7 +43,7 @@ export const action: ActionFunction = async ({ request }) => { export default function Edit() { const navigate = useNavigate(); - const data = useLoaderData(); + const data = useLoaderData(); const [formData, setFormData] = React.useState({ company: data.company, diff --git a/route-modal/app/routes/invoices/add.tsx b/route-modal/app/routes/invoices/add.tsx index 31d48049..2a24890c 100644 --- a/route-modal/app/routes/invoices/add.tsx +++ b/route-modal/app/routes/invoices/add.tsx @@ -1,6 +1,6 @@ import Dialog from "@reach/dialog"; import styles from "@reach/dialog/styles.css"; -import type { ActionFunction, LinksFunction } from "@remix-run/node"; +import type { ActionArgs, LinksFunction } from "@remix-run/node"; import { redirect } from "@remix-run/node"; import { Form, @@ -18,7 +18,7 @@ export const links: LinksFunction = () => { ]; }; -export const action: ActionFunction = async ({ request }) => { +export const action = async ({ request }: ActionArgs) => { // Here we can update our database with the new invoice // This is just so we can see the transition @@ -31,7 +31,7 @@ export const action: ActionFunction = async ({ request }) => { export default function Add() { const navigate = useNavigate(); - const actionData = useActionData(); + const actionData = useActionData(); const transition = useTransition(); function onDismiss() { diff --git a/routes-gen/app/routes/products/index.tsx b/routes-gen/app/routes/products/index.tsx index 1e93b5b9..ecf17315 100644 --- a/routes-gen/app/routes/products/index.tsx +++ b/routes-gen/app/routes/products/index.tsx @@ -1,4 +1,3 @@ -import type { LoaderFunction } from "@remix-run/node"; import { json } from "@remix-run/node"; import { useLoaderData } from "@remix-run/react"; import { Link } from "react-router-dom"; @@ -20,12 +19,12 @@ const posts: Post[] = [ }, ]; -export const loader: LoaderFunction = async () => { +export const loader = async () => { return json(posts); }; export default function Products() { - const data = useLoaderData(); + const data = useLoaderData(); return (
    diff --git a/rust/app/routes/index.tsx b/rust/app/routes/index.tsx index 76899c26..8df6ba7b 100644 --- a/rust/app/routes/index.tsx +++ b/rust/app/routes/index.tsx @@ -1,4 +1,4 @@ -import type { ActionFunction } from "@remix-run/node"; +import type { ActionArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Form, useActionData } from "@remix-run/react"; @@ -9,7 +9,7 @@ export function links() { return [{ rel: "stylesheet", href: indexStylesUrl }]; } -export const action: ActionFunction = async ({ request }) => { +export const action = async ({ request }: ActionArgs) => { const formData = await request.formData(); const { left_operand, operator, right_operand } = Object.fromEntries(formData); @@ -30,7 +30,7 @@ export const action: ActionFunction = async ({ request }) => { }; export default function Index() { - const data = useActionData(); + const data = useActionData(); return ( diff --git a/sanity/app/routes/$slug.tsx b/sanity/app/routes/$slug.tsx index 24cf44ea..9afb1cd6 100644 --- a/sanity/app/routes/$slug.tsx +++ b/sanity/app/routes/$slug.tsx @@ -1,4 +1,4 @@ -import type { LoaderFunction } from "@remix-run/node"; +import type { LoaderArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { useLoaderData } from "@remix-run/react"; import type { FunctionComponent } from "react"; @@ -12,14 +12,7 @@ import { urlFor, } from "~/lib/sanity"; -type LoaderData = { - initialData: unknown; - preview: boolean; - query: string; - queryParams: Record; -}; - -export const loader: LoaderFunction = async ({ params, request }) => { +export const loader = async ({ params, request }: LoaderArgs) => { const requestUrl = new URL(request?.url); const preview = requestUrl?.searchParams?.get("preview") === @@ -31,7 +24,7 @@ export const loader: LoaderFunction = async ({ params, request }) => { const queryParams = { slug: params.slug }; const initialData = await getClient(preview).fetch(query, queryParams); - return json({ + return json({ initialData, preview, // If `preview` mode is active, we'll need these for live updates @@ -42,7 +35,7 @@ export const loader: LoaderFunction = async ({ params, request }) => { const Movie: FunctionComponent = () => { const { initialData, preview, query, queryParams } = - useLoaderData(); + useLoaderData(); // If `preview` mode is active, its component update this state for us const [data, setData] = useState(initialData); diff --git a/sanity/app/routes/index.tsx b/sanity/app/routes/index.tsx index 7206c5b8..e6625dca 100644 --- a/sanity/app/routes/index.tsx +++ b/sanity/app/routes/index.tsx @@ -1,4 +1,4 @@ -import type { LoaderFunction, MetaFunction } from "@remix-run/node"; +import type { MetaFunction } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Link, useLoaderData } from "@remix-run/react"; import type { FunctionComponent } from "react"; @@ -10,7 +10,7 @@ type Movie = { slug: { current: string }; title: string; }; -export const loader: LoaderFunction = async () => { +export const loader = async () => { const movies = await getClient().fetch( `*[_type == "movie"]{ _id, title, slug }` ); diff --git a/search-input/app/routes/index.tsx b/search-input/app/routes/index.tsx index 9e8c9ea9..c4ed3f22 100644 --- a/search-input/app/routes/index.tsx +++ b/search-input/app/routes/index.tsx @@ -1,8 +1,4 @@ -import type { - LinksFunction, - LoaderFunction, - MetaFunction, -} from "@remix-run/node"; +import type { LinksFunction, LoaderArgs, MetaFunction } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Form, useLoaderData, useTransition } from "@remix-run/react"; @@ -24,29 +20,22 @@ type ShowResult = { show: { name: string; url: string; image?: { medium: string } }; }; -type LoaderData = { - status: "resultsFound" | "noResults" | "emptySearch"; - searchTerm: string; - items: Array<{ id: string; name: string; image: string; url: string }>; -}; - function typedBoolean( value: T ): value is Exclude { return Boolean(value); } -export const loader: LoaderFunction = async ({ request }) => { +export const loader = async ({ request }: LoaderArgs) => { const url = new URL(request.url); const searchTerm = url.searchParams.get("search"); if (!searchTerm) { - const data: LoaderData = { + return json({ status: "emptySearch", searchTerm: searchTerm || "", items: [], - }; - return json(data); + }); } const result = await fetch( @@ -55,15 +44,14 @@ export const loader: LoaderFunction = async ({ request }) => { const showResults = (await result.json()) as undefined | Array; if (!showResults || !showResults.length) { - const data: LoaderData = { + return json({ status: "noResults", searchTerm, items: [], - }; - return json(data); + }); } - const data: LoaderData = { + const data = { status: "resultsFound", searchTerm, items: showResults @@ -81,14 +69,12 @@ export const loader: LoaderFunction = async ({ request }) => { }; return json(data, { - headers: { - "Cache-Control": "max-age=60, stale-while-revalidate=60", - }, + headers: { "Cache-Control": "max-age=60, stale-while-revalidate=60" }, }); }; export default function Index() { - const data = useLoaderData(); + const data = useLoaderData(); const transition = useTransition(); return ( diff --git a/session-flash/app/routes/index.tsx b/session-flash/app/routes/index.tsx index 9efbfaf8..feeca199 100644 --- a/session-flash/app/routes/index.tsx +++ b/session-flash/app/routes/index.tsx @@ -1,4 +1,4 @@ -import type { ActionFunction, LoaderFunction } from "@remix-run/node"; +import type { ActionArgs, LoaderArgs } from "@remix-run/node"; import { json, redirect } from "@remix-run/node"; import { useLoaderData, Form, useActionData } from "@remix-run/react"; import { useEffect, useRef } from "react"; @@ -7,24 +7,16 @@ import type { FlashMessage as FlashMessageType } from "~/utils/session.server"; import { getSession, storage } from "~/utils/session.server"; import { getSessionFlash } from "~/utils/session.server"; -interface LoaderData { - message?: FlashMessageType; -} - -interface ActionData { - formError: string; -} - -export const loader: LoaderFunction = async ({ request }) => { +export const loader = async ({ request }: LoaderArgs) => { const flash = await getSessionFlash(request); if (flash && flash.message) { return json({ message: flash.message }, { headers: flash.headers }); } - return null; + return json({ message: null }); }; -export const action: ActionFunction = async ({ request }) => { +export const action = async ({ request }: ActionArgs) => { const form = await request.formData(); const text = form.get("messageText"); const color = form.get("messageColor"); @@ -44,8 +36,8 @@ export const action: ActionFunction = async ({ request }) => { }; export default function Index() { - const loaderData = useLoaderData(); - const actionData = useActionData(); + const loaderData = useLoaderData(); + const actionData = useActionData(); return ( <> {loaderData?.message ? ( diff --git a/sharing-loader-data/app/root.tsx b/sharing-loader-data/app/root.tsx index 026d8d06..248cb533 100644 --- a/sharing-loader-data/app/root.tsx +++ b/sharing-loader-data/app/root.tsx @@ -1,4 +1,4 @@ -import type { LoaderFunction, MetaFunction } from "@remix-run/node"; +import type { MetaFunction } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Links, @@ -9,13 +9,10 @@ import { ScrollRestoration, } from "@remix-run/react"; -import type { User } from "~/data.server"; import { getUser } from "~/data.server"; -type LoaderData = { user: User }; - -export const loader: LoaderFunction = async () => { - return json({ user: await getUser() }); +export const loader = async () => { + return json({ user: await getUser() }); }; export const meta: MetaFunction = () => ({ diff --git a/sharing-loader-data/app/routes/workshops.tsx b/sharing-loader-data/app/routes/workshops.tsx index 7392984c..a11aebdb 100644 --- a/sharing-loader-data/app/routes/workshops.tsx +++ b/sharing-loader-data/app/routes/workshops.tsx @@ -1,20 +1,14 @@ -import type { LoaderFunction } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Link, Outlet, useLoaderData } from "@remix-run/react"; -import type { Workshop } from "~/data.server"; import { getWorkshops } from "~/data.server"; -type LoaderData = { workshops: Array }; - -export const loader: LoaderFunction = async () => { - return json({ - workshops: await getWorkshops(), - }); +export const loader = async () => { + return json({ workshops: await getWorkshops() }); }; export default function Workshops() { - const data = useLoaderData(); + const data = useLoaderData(); return (
    diff --git a/sharing-loader-data/app/routes/workshops/$workshopId.tsx b/sharing-loader-data/app/routes/workshops/$workshopId.tsx index e92dd17d..309ff1d6 100644 --- a/sharing-loader-data/app/routes/workshops/$workshopId.tsx +++ b/sharing-loader-data/app/routes/workshops/$workshopId.tsx @@ -1,11 +1,11 @@ -import type { LoaderFunction } from "@remix-run/node"; +import type { LoaderArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { useCatch, useMatches, useParams } from "@remix-run/react"; import type { Workshop } from "~/data.server"; import { getWorkshops } from "~/data.server"; -export const loader: LoaderFunction = async ({ params }) => { +export const loader = async ({ params }: LoaderArgs) => { const { workshopId } = params; const workshops = await getWorkshops(); const workshop = workshops.find((w) => w.id === workshopId); diff --git a/strapi/app/routes/index.tsx b/strapi/app/routes/index.tsx index b9119d8f..bc5f4f02 100755 --- a/strapi/app/routes/index.tsx +++ b/strapi/app/routes/index.tsx @@ -1,4 +1,3 @@ -import type { LoaderFunction } from "@remix-run/node"; import { json } from "@remix-run/node"; import { useLoaderData } from "@remix-run/react"; import { marked } from "marked"; @@ -26,7 +25,7 @@ type PostResponse = { }; }; -export const loader: LoaderFunction = async () => { +export const loader = async () => { // This is where Remix integrates with Strapi const response = await fetch("http://localhost:1337/api/posts"); const postResponse = (await response.json()) as PostResponse; @@ -43,7 +42,7 @@ export const loader: LoaderFunction = async () => { }; const Posts: React.FC = () => { - const posts = useLoaderData(); + const posts = useLoaderData(); return ( <> diff --git a/stripe-integration/app/routes/api/stripe-web-hook.tsx b/stripe-integration/app/routes/api/stripe-web-hook.tsx index 2350dc9c..0c4571e8 100644 --- a/stripe-integration/app/routes/api/stripe-web-hook.tsx +++ b/stripe-integration/app/routes/api/stripe-web-hook.tsx @@ -1,9 +1,9 @@ -import type { ActionFunction } from "@remix-run/node"; +import type { ActionArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import stripe from "stripe"; -//[credit @kiliman to get this webhook working](https://github.com/remix-run/remix/discussions/1978) -export const action: ActionFunction = async ({ request }) => { +// [credit @kiliman to get this webhook working](https://github.com/remix-run/remix/discussions/1978) +export const action = async ({ request }: ActionArgs) => { const payload = await request.text(); const sig = request.headers.get("stripe-signature"); let event; diff --git a/stripe-integration/app/routes/buy.tsx b/stripe-integration/app/routes/buy.tsx index 527605f2..42ca48fc 100644 --- a/stripe-integration/app/routes/buy.tsx +++ b/stripe-integration/app/routes/buy.tsx @@ -1,10 +1,10 @@ -import type { ActionFunction } from "@remix-run/node"; +import type { ActionArgs } from "@remix-run/node"; import { redirect } from "@remix-run/node"; import { Form } from "@remix-run/react"; import { getStripeSession, getDomainUrl } from "~/utils/stripe.server"; -export const action: ActionFunction = async ({ request }) => { +export const action = async ({ request }: ActionArgs) => { const stripeRedirectUrl = await getStripeSession( process.env.PRICE_ID as string, getDomainUrl(request) diff --git a/supabase-subscription/app/root.tsx b/supabase-subscription/app/root.tsx index a2b68fb0..35b336c7 100644 --- a/supabase-subscription/app/root.tsx +++ b/supabase-subscription/app/root.tsx @@ -1,4 +1,4 @@ -import type { LoaderFunction, MetaFunction } from "@remix-run/node"; +import type { MetaFunction } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Links, @@ -12,14 +12,8 @@ import { import { createClient } from "@supabase/supabase-js"; import { Provider } from "react-supabase"; -type LoaderData = { - ENV: { - SUPABASE_URL: string; - SUPABASE_ANON_KEY: string; - }; -}; -export const loader: LoaderFunction = async () => { - return json({ +export const loader = async () => { + return json({ ENV: { SUPABASE_URL: process.env.SUPABASE_URL as string, SUPABASE_ANON_KEY: process.env.SUPABASE_ANON_KEY as string, @@ -34,7 +28,7 @@ export const meta: MetaFunction = () => ({ }); export default function App() { - const data = useLoaderData(); + const data = useLoaderData(); return ( diff --git a/supabase-subscription/app/routes/realtime.tsx b/supabase-subscription/app/routes/realtime.tsx index 76892033..e1e3020f 100644 --- a/supabase-subscription/app/routes/realtime.tsx +++ b/supabase-subscription/app/routes/realtime.tsx @@ -1,18 +1,18 @@ -import type { ActionFunction, LoaderFunction } from "@remix-run/node"; +import type { ActionArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Form, useFetcher, useLoaderData } from "@remix-run/react"; import { useSubscription } from "react-supabase"; import { client } from "~/utils/supabaseClient.server"; -export const loader: LoaderFunction = async () => { +export const loader = async () => { const { count } = await client .from("clicks") .select("id", { count: "exact", head: true }); return json(count); }; -export const action: ActionFunction = async ({ request }) => { +export const action = async ({ request }: ActionArgs) => { const formData = await request.formData(); if (formData.get("like")) { await client.from("clicks").insert([{}]); @@ -21,7 +21,7 @@ export const action: ActionFunction = async ({ request }) => { }; const Buttons = () => { - const count = useLoaderData(); + const count = useLoaderData(); const fetcher = useFetcher(); useSubscription( () => { diff --git a/toast-message/app/root.tsx b/toast-message/app/root.tsx index 7e8ef042..89127387 100644 --- a/toast-message/app/root.tsx +++ b/toast-message/app/root.tsx @@ -1,4 +1,4 @@ -import type { LoaderFunction, MetaFunction } from "@remix-run/node"; +import type { LoaderArgs, MetaFunction } from "@remix-run/node"; import { json } from "@remix-run/node"; import { Links, @@ -15,37 +15,33 @@ import { Toaster, toast } from "react-hot-toast"; import type { ToastMessage } from "./message.server"; import { commitSession, getSession } from "./message.server"; -type LoaderData = { - toastMessage: ToastMessage | null; -}; - export const meta: MetaFunction = () => ({ charset: "utf-8", title: "Remix + Toast notifications", viewport: "width=device-width,initial-scale=1", }); -export const loader: LoaderFunction = async ({ request }) => { +export const loader = async ({ request }: LoaderArgs) => { const session = await getSession(request.headers.get("cookie")); const toastMessage = session.get("toastMessage") as ToastMessage; if (!toastMessage) { - return json({ toastMessage: null }); + return json({ toastMessage: null }); } if (!toastMessage.type) { throw new Error("Message should have a type"); } - return json( + return json( { toastMessage }, { headers: { "Set-Cookie": await commitSession(session) } } ); }; export default function App() { - const { toastMessage } = useLoaderData(); + const { toastMessage } = useLoaderData(); React.useEffect(() => { if (!toastMessage) { diff --git a/toast-message/app/routes/index.tsx b/toast-message/app/routes/index.tsx index 426a6188..68363a45 100644 --- a/toast-message/app/routes/index.tsx +++ b/toast-message/app/routes/index.tsx @@ -1,4 +1,4 @@ -import type { ActionFunction } from "@remix-run/node"; +import type { ActionArgs } from "@remix-run/node"; import { redirect } from "@remix-run/node"; import { Form, useFetcher } from "@remix-run/react"; @@ -9,7 +9,7 @@ import { setSuccessMessage, } from "~/message.server"; -export const action: ActionFunction = async ({ request }) => { +export const action = async ({ request }: ActionArgs) => { const session = await getSession(request.headers.get("cookie")); const formData = await request.formData(); diff --git a/toast-message/app/routes/submit-secret.ts b/toast-message/app/routes/submit-secret.ts index ecf5a1cb..fcde2fd0 100644 --- a/toast-message/app/routes/submit-secret.ts +++ b/toast-message/app/routes/submit-secret.ts @@ -1,4 +1,4 @@ -import type { ActionFunction } from "@remix-run/node"; +import type { ActionArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { @@ -8,7 +8,7 @@ import { setSuccessMessage, } from "~/message.server"; -export const action: ActionFunction = async ({ request }) => { +export const action = async ({ request }: ActionArgs) => { const session = await getSession(request.headers.get("cookie")); const formData = await request.formData();