33import { UserInfo } from "@/components/UserInfo" ;
44import { BuyerItemsTable } from "@/components/tables/BuyerItemsTable" ;
55import { OrderResponse } from "@/lib/crud/purchase" ;
6+ import { AcademicYear } from "@docsoc/eactivities" ;
67import { Group , TextInput , Button , Alert , Container , Center , Stack } from "@mantine/core" ;
8+ import { useForm } from "@mantine/form" ;
79import { useRouter , useSearchParams } from "next/navigation" ;
810import React , { useCallback , useEffect , useMemo , useState , useTransition } from "react" ;
911import { FaSearch , FaTimesCircle } from "react-icons/fa" ;
1012
1113import { PageActions } from "./PageActions" ;
1214
13- export const UserSearch = ( ) => {
15+ interface UserSearchProps {
16+ currentAcademicYear : AcademicYear ;
17+ validAcaemicYears : string [ ] ;
18+ }
19+
20+ export const UserSearch : React . FC < UserSearchProps > = ( {
21+ currentAcademicYear,
22+ validAcaemicYears,
23+ } ) => {
1424 const [ error , setError ] = useState < string | null > ( null ) ;
1525 const [ purchases , setPurchases ] = useState < OrderResponse [ ] > ( [ ] ) ;
1626 const [ isPending , startTransition ] = useTransition ( ) ;
1727
18- // Need to allow clearing on route change to home
19- const [ shortcodeFormState , setSetshortcodeFormState ] = useState ( "" ) ;
20-
2128 const searchParams = useSearchParams ( ) ;
2229 const router = useRouter ( ) ;
23- const shortcode = useMemo ( ( ) => searchParams . get ( "shortcode" ) || "" , [ searchParams ] ) ;
30+ const shortcodeURLParam = useMemo ( ( ) => searchParams . get ( "shortcode" ) || "" , [ searchParams ] ) ;
2431
2532 const fetchPurchases = useCallback ( async ( shortcode : string ) => {
2633 const res = await fetch ( `/api/purchases/${ shortcode } ` , {
@@ -40,42 +47,45 @@ export const UserSearch = () => {
4047 }
4148 } , [ ] ) ;
4249
50+ // Form
51+ // 2 fields: shortcode & academic year purcahses.
52+ // Default value of shortcode is from the URL if possible
53+ const form = useForm ( {
54+ initialValues : { shortcode : shortcodeURLParam , academicYears : [ currentAcademicYear ] } ,
55+
56+ validate : {
57+ shortcode : ( value ) => {
58+ if ( typeof value !== "string" ) return "Please enter a shortcode" ;
59+ return ;
60+ } ,
61+ } ,
62+ } ) ;
4363 useEffect ( ( ) => {
44- if ( shortcode ) {
45- setSetshortcodeFormState ( shortcode ) ;
46- fetchPurchases ( shortcode ) ;
64+ if ( shortcodeURLParam ) {
65+ fetchPurchases ( shortcodeURLParam ) ;
4766 } else {
4867 setPurchases ( [ ] ) ;
49- setSetshortcodeFormState ( "" ) ;
68+ form . setFieldValue ( "shortcode" , "" ) ;
5069 }
51- } , [ shortcode , fetchPurchases ] ) ;
70+ // can't add form as would cause infinite loop
71+ // eslint-disable-next-line react-hooks/exhaustive-deps
72+ } , [ shortcodeURLParam , fetchPurchases ] ) ;
5273
5374 const submitAction = useCallback (
54- async ( formState : FormData ) => {
55- setError ( null ) ;
56- const shortcode = formState . get ( "shortcode" ) ?. toString ( ) . trim ( ) ;
75+ ( { shortcode } : { shortcode : string } ) => {
76+ startTransition ( ( ) => {
77+ setError ( null ) ;
5778
58- if ( typeof shortcode !== "string" ) {
59- setError ( "Please enter a shortcode" ) ;
60- return ;
61- }
62-
63- router . push ( "/?shortcode=" + shortcode ) ;
79+ router . push ( "/?shortcode=" + shortcode ) ;
80+ } ) ;
6481 } ,
6582 [ router ] ,
6683 ) ;
6784
68- const submitActionWithTransition = useCallback (
69- ( formState : FormData ) => {
70- startTransition ( async ( ) => await submitAction ( formState ) ) ;
71- } ,
72- [ submitAction ] ,
73- ) ;
74-
7585 return (
7686 < Container w = "70%" >
7787 < Stack gap = "lg" >
78- < PageActions />
88+ < PageActions academicYears = { validAcaemicYears } formHook = { form } />
7989 < Center >
8090 < Stack w = "90%" justify = "centre" align = "centre" >
8191 < form
@@ -85,7 +95,8 @@ export const UserSearch = () => {
8595 justifyContent : "center" ,
8696 alignItems : "center" ,
8797 } }
88- action = { submitActionWithTransition }
98+ onSubmit = { form . onSubmit ( submitAction ) }
99+ action = { ( ) => { } }
89100 >
90101 < Group w = "100%" >
91102 < TextInput
@@ -96,14 +107,19 @@ export const UserSearch = () => {
96107 required
97108 name = "shortcode"
98109 id = "shortcode"
99- onChange = { ( e ) =>
100- setSetshortcodeFormState ( e . currentTarget . value )
101- }
102- value = { shortcodeFormState }
110+ { ...form . getInputProps ( "shortcode" ) }
103111 />
104112 < Button loading = { isPending } type = "submit" >
105113 Submit
106114 </ Button >
115+ < Button
116+ color = "pink"
117+ onClick = { ( ) => {
118+ router . push ( "/" ) ;
119+ } }
120+ >
121+ Clear
122+ </ Button >
107123 </ Group >
108124 </ form >
109125 { error && (
@@ -114,14 +130,14 @@ export const UserSearch = () => {
114130 </ Stack >
115131 </ Center >
116132 < Center >
117- < UserInfo shortcode = { shortcode } />
133+ < UserInfo shortcode = { shortcodeURLParam } />
118134 </ Center >
119135
120136 { ! error ? (
121137 < BuyerItemsTable
122- shortcode = { shortcode }
138+ shortcode = { shortcodeURLParam }
123139 purchases = { purchases }
124- refresh = { ( ) => fetchPurchases ( shortcode ) }
140+ refresh = { ( ) => fetchPurchases ( shortcodeURLParam ) }
125141 />
126142 ) : (
127143 < > </ >
0 commit comments