From 2c7d1d97e9235cfef5e067a961bf65f46ebed808 Mon Sep 17 00:00:00 2001 From: Anthony Frehner Date: Tue, 11 Apr 2023 10:57:34 -0600 Subject: [PATCH] First update for the skeleton routes following the new guidelines (#760) * First update for the skeleton routes following the new guidelines * v1 and v2 ErrorBoundaries Also fix commenting style, and add a doc to guidelines. * remove comments --- templates/skeleton/TEMPLATE_GUIDELINES.md | 26 ++++++++++ .../skeleton/app/routes/account/login.tsx | 51 +++++++++++++++---- .../skeleton/app/routes/account/register.tsx | 51 +++++++++++++++---- 3 files changed, 106 insertions(+), 22 deletions(-) diff --git a/templates/skeleton/TEMPLATE_GUIDELINES.md b/templates/skeleton/TEMPLATE_GUIDELINES.md index 74de1ef83b..8d6c4a12d6 100644 --- a/templates/skeleton/TEMPLATE_GUIDELINES.md +++ b/templates/skeleton/TEMPLATE_GUIDELINES.md @@ -10,6 +10,7 @@ Topics covered: - [TypeScript](#typescript) - [Remix Loader Return Values](#remix-loader-return-values) - [GraphQL Query Definitions](#graphql-query-definitions) +- [Comment Styles](#comment-styles) ## Error Handling @@ -248,3 +249,28 @@ const MUTATION_ADD_TO_CART = `#graphql } `; ``` + +## Comment Styles + +Use `//` for single-line comments, and `/** */` for multi-line comments. Consider adding a header section for additional context or extremely long comment blocks. + +### Example + +```tsx +// this is fine for single lines +function test() {} + +/** + * If you're providing substantial context, links, example code and other stuff, + * then you should switch to something that really visually differentiates. + */ +function thing() {} + +/** + * myStuff + * ----------------- + * Renders a login page for customer accounts. + * And does other really cool stuff + */ +function myStuff() {} +``` diff --git a/templates/skeleton/app/routes/account/login.tsx b/templates/skeleton/app/routes/account/login.tsx index e5f255e623..7a1a1753a4 100644 --- a/templates/skeleton/app/routes/account/login.tsx +++ b/templates/skeleton/app/routes/account/login.tsx @@ -1,10 +1,15 @@ import { type ActionFunction, type LoaderArgs, + type ErrorBoundaryComponent, redirect, - json, } from '@shopify/remix-oxygen'; -import {Form} from '@remix-run/react'; +import { + Form, + useCatch, + useRouteError, + isRouteErrorResponse, +} from '@remix-run/react'; export async function loader({context, params}: LoaderArgs) { const customerAccessToken = await context.session.get('customerAccessToken'); @@ -16,13 +21,7 @@ export async function loader({context, params}: LoaderArgs) { return new Response(null); } -type ActionData = { - formError?: string; -}; - -const badRequest = (data: ActionData) => json(data, {status: 400}); - -export const action: ActionFunction = async ({request, context, params}) => { +export const action: ActionFunction = async ({request}) => { const formData = await request.formData(); const email = formData.get('email'); @@ -34,8 +33,8 @@ export const action: ActionFunction = async ({request, context, params}) => { typeof email !== 'string' || typeof password !== 'string' ) { - return badRequest({ - formError: 'Please provide both an email and a password.', + throw new Response('Please provide both an email and a password.', { + status: 400, }); } @@ -72,3 +71,33 @@ export default function Login() { ); } + +export const ErrorBoundaryV1: ErrorBoundaryComponent = ({error}) => { + console.error(error); + + return
There was an error.
; +}; + +export function CatchBoundary() { + const caught = useCatch(); + console.error(caught); + + return ( +
+ There was an error. Status: {caught.status}. Message:{' '} + {caught.data?.message} +
+ ); +} + +export function ErrorBoundary() { + const error = useRouteError(); + + if (isRouteErrorResponse(error)) { + console.error(error.status, error.statusText, error.data); + return
Route Error
; + } else { + console.error((error as Error).message); + return
Thrown Error
; + } +} diff --git a/templates/skeleton/app/routes/account/register.tsx b/templates/skeleton/app/routes/account/register.tsx index eb5e85a6dd..a8387fb56b 100644 --- a/templates/skeleton/app/routes/account/register.tsx +++ b/templates/skeleton/app/routes/account/register.tsx @@ -1,10 +1,15 @@ import { type ActionFunction, type LoaderArgs, + type ErrorBoundaryComponent, redirect, - json, } from '@shopify/remix-oxygen'; -import {Form} from '@remix-run/react'; +import { + Form, + useCatch, + useRouteError, + isRouteErrorResponse, +} from '@remix-run/react'; export async function loader({context, params}: LoaderArgs) { const customerAccessToken = await context.session.get('customerAccessToken'); @@ -16,13 +21,7 @@ export async function loader({context, params}: LoaderArgs) { return new Response(null); } -type ActionData = { - formError?: string; -}; - -const badRequest = (data: ActionData) => json(data, {status: 400}); - -export const action: ActionFunction = async ({request, context, params}) => { +export const action: ActionFunction = async ({request}) => { const formData = await request.formData(); const email = formData.get('email'); @@ -34,8 +33,8 @@ export const action: ActionFunction = async ({request, context, params}) => { typeof email !== 'string' || typeof password !== 'string' ) { - return badRequest({ - formError: 'Please provide both an email and a password.', + throw new Response('Please provide both an email and a password.', { + status: 404, }); } @@ -72,3 +71,33 @@ export default function Register() { ); } + +export const ErrorBoundaryV1: ErrorBoundaryComponent = ({error}) => { + console.error(error); + + return
There was an error.
; +}; + +export function CatchBoundary() { + const caught = useCatch(); + console.error(caught); + + return ( +
+ There was an error. Status: {caught.status}. Message:{' '} + {caught.data?.message} +
+ ); +} + +export function ErrorBoundary() { + const error = useRouteError(); + + if (isRouteErrorResponse(error)) { + console.error(error.status, error.statusText, error.data); + return
Route Error
; + } else { + console.error((error as Error).message); + return
Thrown Error
; + } +}