1- import type {
2- ActionFunction ,
3- LinksFunction ,
4- MetaFunction ,
5- } from "@remix-run/node" ;
6- import { json } from "@remix-run/node" ;
7- import { Form , Link , useActionData , useSearchParams } from "@remix-run/react" ;
1+ import type { ActionArgs , LinksFunction , MetaFunction } from "@remix-run/node" ;
2+ import { Link , useActionData , useSearchParams } from "@remix-run/react" ;
83
9- import { login , createUserSession , register } from "~/utils/session.server " ;
4+ import stylesUrl from "~/styles/login.css " ;
105import { db } from "~/utils/db.server" ;
6+ import { badRequest } from "~/utils/request.server" ;
7+ import { createUserSession , login , register } from "~/utils/session.server" ;
118
12- import stylesUrl from "../styles/login.css" ;
9+ export const meta : MetaFunction = ( ) => ( {
10+ description : "Login to submit your own jokes to Remix Jokes!" ,
11+ title : "Remix Jokes | Login" ,
12+ } ) ;
1313
14- export const meta : MetaFunction = ( ) => {
15- return {
16- title : "Remix Jokes | Login" ,
17- description : "Login to submit your own jokes to Remix Jokes!" ,
18- } ;
19- } ;
20-
21- export const links : LinksFunction = ( ) => {
22- return [ { rel : "stylesheet" , href : stylesUrl } ] ;
23- } ;
14+ export const links : LinksFunction = ( ) => [
15+ { rel : "stylesheet" , href : stylesUrl } ,
16+ ] ;
2417
2518function validateUsername ( username : unknown ) {
2619 if ( typeof username !== "string" || username . length < 3 ) {
@@ -34,28 +27,15 @@ function validatePassword(password: unknown) {
3427 }
3528}
3629
37- function validateUrl ( url : any ) {
30+ function validateUrl ( url : string ) {
3831 const urls = [ "/jokes" , "/" , "https://remix.run" ] ;
3932 if ( urls . includes ( url ) ) {
4033 return url ;
4134 }
4235 return "/jokes" ;
4336}
4437
45- type ActionData = {
46- formError ?: string ;
47- fieldErrors ?: { username : string | undefined ; password : string | undefined } ;
48- fields ?: { loginType : string ; username : string ; password : string } ;
49- } ;
50-
51- /**
52- * This helper function gives us typechecking for our ActionData return
53- * statements, while still returning the accurate HTTP status, 400 Bad Request,
54- * to the client.
55- */
56- const badRequest = ( data : ActionData ) => json ( data , { status : 400 } ) ;
57-
58- export const action : ActionFunction = async ( { request } ) => {
38+ export const action = async ( { request } : ActionArgs ) => {
5939 const form = await request . formData ( ) ;
6040 const loginType = form . get ( "loginType" ) ;
6141 const username = form . get ( "username" ) ;
@@ -67,7 +47,11 @@ export const action: ActionFunction = async ({ request }) => {
6747 typeof password !== "string" ||
6848 typeof redirectTo !== "string"
6949 ) {
70- return badRequest ( { formError : `Form not submitted correctly.` } ) ;
50+ return badRequest ( {
51+ fieldErrors : null ,
52+ fields : null ,
53+ formError : `Form not submitted correctly.` ,
54+ } ) ;
7155 }
7256
7357 const fields = { loginType, username, password } ;
@@ -76,14 +60,15 @@ export const action: ActionFunction = async ({ request }) => {
7660 password : validatePassword ( password ) ,
7761 } ;
7862 if ( Object . values ( fieldErrors ) . some ( Boolean ) ) {
79- return badRequest ( { fieldErrors, fields } ) ;
63+ return badRequest ( { fieldErrors, fields, formError : null } ) ;
8064 }
8165
8266 switch ( loginType ) {
8367 case "login" : {
8468 const user = await login ( { username, password } ) ;
8569 if ( ! user ) {
8670 return badRequest ( {
71+ fieldErrors : null ,
8772 fields,
8873 formError : `Username/Password combination is incorrect` ,
8974 } ) ;
@@ -94,33 +79,39 @@ export const action: ActionFunction = async ({ request }) => {
9479 const userExists = await db . user . findFirst ( { where : { username } } ) ;
9580 if ( userExists ) {
9681 return badRequest ( {
82+ fieldErrors : null ,
9783 fields,
9884 formError : `User with username ${ username } already exists` ,
9985 } ) ;
10086 }
10187 const user = await register ( { username, password } ) ;
10288 if ( ! user ) {
10389 return badRequest ( {
90+ fieldErrors : null ,
10491 fields,
10592 formError : `Something went wrong trying to create a new user.` ,
10693 } ) ;
10794 }
10895 return createUserSession ( user . id , redirectTo ) ;
10996 }
11097 default : {
111- return badRequest ( { fields, formError : `Login type invalid` } ) ;
98+ return badRequest ( {
99+ fieldErrors : null ,
100+ fields,
101+ formError : `Login type invalid` ,
102+ } ) ;
112103 }
113104 }
114105} ;
115106
116107export default function Login ( ) {
117- const actionData = useActionData < ActionData > ( ) ;
108+ const actionData = useActionData < typeof action > ( ) ;
118109 const [ searchParams ] = useSearchParams ( ) ;
119110 return (
120111 < div className = "container" >
121112 < div className = "content" data-light = "" >
122113 < h1 > Login</ h1 >
123- < Form method = "post" >
114+ < form method = "post" >
124115 < input
125116 type = "hidden"
126117 name = "redirectTo"
@@ -204,7 +195,7 @@ export default function Login() {
204195 < button type = "submit" className = "button" >
205196 Submit
206197 </ button >
207- </ Form >
198+ </ form >
208199 </ div >
209200 < div className = "links" >
210201 < ul >
0 commit comments