4
4
type ActionFunctionArgs ,
5
5
unstable_parseMultipartFormData ,
6
6
LoaderFunctionArgs ,
7
+ type UploadHandler ,
7
8
} from "@remix-run/node" ;
8
9
import { Form , useFetcher } from "@remix-run/react" ;
9
10
import {
@@ -31,23 +32,26 @@ const ACCEPTED_IMAGE_TYPES = [
31
32
"image/png" ,
32
33
"image/webp" ,
33
34
] ;
35
+ export const fileUploadHandler =
36
+ ( ) : UploadHandler =>
37
+ async ( { data, filename } ) => {
38
+ const chunks = [ ] ;
39
+ console . log ( "udje?" , filename ) ;
40
+ for await ( const chunk of data ) {
41
+ chunks . push ( chunk ) ;
42
+ }
43
+ const buffer = Buffer . concat ( chunks ) ;
44
+ // If there's no filename, it's a text field and we can return the value directly
45
+ if ( ! filename ) {
46
+ const textDecoder = new TextDecoder ( ) ;
47
+ return textDecoder . decode ( buffer ) ;
48
+ }
49
+
50
+ return new File ( [ buffer ] , filename , { type : "image/jpeg" } ) ;
51
+ } ;
52
+
34
53
export const patientBaseSchema = generateObjectSchema ( {
35
- id : stringOptional ( ) ,
36
- firstName : stringRequired ( ) ,
37
- lastName : stringRequired ( ) ,
38
- primaryCareProvider : stringOptional ( ) ,
39
- dateOfBirth : dateOfBirthRequired ( ) ,
40
- email : emailOptional ( ) ,
41
- hasThirdPartyCoverage : booleanOptional ( ) ,
42
- isForeignCitizen : booleanOptional ( ) ,
43
- allergies : z . array ( stringRequired ( ) ) . optional ( ) ,
44
- healthCardNumber : stringOptional ( ) ,
45
- hasHealthCardNumber : booleanRequired ( ) ,
46
- city : stringRequired ( ) ,
47
- province : stringRequired ( ) ,
48
- street : stringRequired ( ) ,
49
- postalCode : stringRequired ( ) ,
50
- healthCardProvince : stringRequired ( ) ,
54
+ file : z . any ( ) . optional ( ) ,
51
55
} ) ;
52
56
const FormDataZodSchema = z . object ( {
53
57
email : z . string ( ) . trim ( ) . nonempty ( "validation.required" ) ,
@@ -61,15 +65,15 @@ type FormData = z.infer<typeof patientBaseSchema>;
61
65
const resolver = zodResolver ( patientBaseSchema ) ;
62
66
export const loader = ( { request } : LoaderFunctionArgs ) => {
63
67
const data = getFormDataFromSearchParams ( request ) ;
64
- console . log ( "loader" , data ) ;
65
68
return json ( { result : "success" } ) ;
66
69
} ;
67
70
export const action = async ( { request } : ActionFunctionArgs ) => {
68
- const { data , errors , receivedValues } = await getValidatedFormData (
71
+ const formData = await unstable_parseMultipartFormData (
69
72
request ,
70
- resolver ,
73
+ fileUploadHandler ( ) ,
71
74
) ;
72
- console . log ( "action" , data , errors , receivedValues ) ;
75
+ console . log ( formData . get ( "file" ) ) ;
76
+ const { errors, data } = await validateFormData ( formData , resolver ) ;
73
77
if ( errors ) {
74
78
return json ( errors , {
75
79
status : 422 ,
@@ -84,39 +88,24 @@ export default function Index() {
84
88
resolver,
85
89
fetcher,
86
90
defaultValues : {
87
- firstName : "a" ,
88
- lastName : "t" ,
89
- primaryCareProvider : "" ,
90
- dateOfBirth : new Date ( "1997-09-05T00:00:00.000Z" ) ,
91
-
92
- email : "" ,
93
-
94
- hasThirdPartyCoverage : false ,
95
- isForeignCitizen : false ,
96
- allergies : [ ] ,
97
- city : "Sarajevo" ,
98
- street : "Radenka Abazovića" ,
99
- province : "ON" ,
100
- postalCode : "a5t 5a5" ,
101
- hasHealthCardNumber : true ,
102
- healthCardNumber : "5555555555" ,
103
- healthCardProvince : "ON" ,
91
+ file : undefined ,
92
+ } ,
93
+ submitData : {
94
+ test : "test" ,
104
95
} ,
105
96
submitConfig : {
106
97
method : "POST" ,
98
+ encType : "multipart/form-data" ,
107
99
} ,
108
100
} ) ;
109
101
const { register, handleSubmit, formState, watch, reset } = methods ;
110
- console . log ( formState ) ;
111
102
112
103
return (
113
104
< RemixFormProvider { ...methods } >
114
105
< p > Add a thing...</ p >
115
106
116
- < Form method = "post" onSubmit = { handleSubmit } >
117
- < div className = "flex flex-col gap-2" >
118
- < input type = "text" { ...register ( "email" ) } />
119
- </ div >
107
+ < Form method = "post" encType = "multipart/form-data" onSubmit = { handleSubmit } >
108
+ < input type = "file" { ...register ( "file" ) } />
120
109
< div >
121
110
< button type = "submit" className = "button" >
122
111
Add
0 commit comments