1
+ 'use client' ;
2
+ import { useState , ChangeEvent , MouseEvent , FormEvent } from 'react' ;
3
+ import { QuestionBody , Difficulty , QuestionFullBody } from '@/api/structs' ;
4
+ import { addQuestion } from '@/api/gateway' ;
5
+
6
+ type Props = { }
7
+
8
+ interface Mapping {
9
+ key : string ,
10
+ value : string
11
+ }
12
+
13
+ function NewQuestion ( { } : Props ) {
14
+ const [ testCases , setTestCases ] = useState < Mapping [ ] > ( [ {
15
+ key : "" , value : ""
16
+ } ] ) ;
17
+ const [ formData , setFormData ] = useState < QuestionBody > ( {
18
+ title : "" ,
19
+ difficulty : Difficulty . Easy ,
20
+ description : "" ,
21
+ } ) ;
22
+
23
+ const handleTextInput = ( e : ChangeEvent < HTMLInputElement | HTMLTextAreaElement > ) => setFormData ( {
24
+ ...formData ,
25
+ [ e . target . name ] : e . target . value
26
+ } ) ;
27
+
28
+ const handleTestCaseInput = ( e : ChangeEvent < HTMLInputElement > , idx : number ) => {
29
+ const values = [ ...testCases ] ;
30
+ values [ idx ] = {
31
+ ...values [ idx ] ,
32
+ [ e . target . name ] : e . target . value
33
+ } ;
34
+ setTestCases ( values ) ;
35
+ }
36
+
37
+ const handleAddField = ( e : MouseEvent < HTMLElement > ) =>
38
+ setTestCases ( [ ...testCases , { key : "" , value : "" } ] ) ;
39
+
40
+ const handleDeleteField = ( e : MouseEvent < HTMLElement > , idx : number ) => {
41
+ const values = [ ...testCases ] ;
42
+ values . splice ( idx , 1 ) ;
43
+ setTestCases ( values ) ;
44
+ }
45
+
46
+ const handleSubmission = async ( e : FormEvent < HTMLFormElement > ) => {
47
+ e . preventDefault ( ) ;
48
+ const question : QuestionFullBody = {
49
+ ...formData ,
50
+ test_cases : testCases . map ( ( elem : Mapping ) => ( {
51
+ [ elem . key ] : elem . value
52
+ } ) ) . reduce ( ( res , item ) => ( { ...res , ...item } ) , { } )
53
+ }
54
+ const status = await addQuestion ( question ) ;
55
+ if ( status . error ) {
56
+ console . log ( "Failed to add question." ) ;
57
+ console . log ( `Code ${ status . status } : ${ status . error } ` ) ;
58
+ return ;
59
+ }
60
+ console . log ( `Successfully added the question.` ) ;
61
+ }
62
+
63
+ return (
64
+ < div >
65
+ < form style = { { color : "black" , padding : "5px" } } onSubmit = { handleSubmission } >
66
+ < input type = "text" name = "title" value = { formData . title } onChange = { handleTextInput } /> < br />
67
+ < input type = "radio" id = "easy" name = "difficulty" value = { 1 } onChange = { handleTextInput } />
68
+ < label htmlFor = "easy" > Easy</ label > < br />
69
+ < input type = "radio" id = "med" name = "difficulty" value = { 2 } onChange = { handleTextInput } />
70
+ < label htmlFor = "med" > Medium</ label > < br />
71
+ < input type = "radio" id = "hard" name = "difficulty" value = { 3 } onChange = { handleTextInput } />
72
+ < label htmlFor = "hard" > Hard</ label > < br />
73
+ < textarea name = "description" value = { formData . description } onChange = { handleTextInput } /> < br />
74
+ { testCases . map ( ( elem , idx ) => (
75
+ < >
76
+ < input
77
+ name = "key"
78
+ type = "text"
79
+ id = { `key_${ idx . toLocaleString ( ) } ` }
80
+ value = { elem . key }
81
+ onChange = { e => handleTestCaseInput ( e , idx ) } />
82
+ < input
83
+ name = "value"
84
+ type = "text"
85
+ id = { `val_${ idx . toLocaleString ( ) } ` }
86
+ value = { elem . value }
87
+ onChange = { e => handleTestCaseInput ( e , idx ) } />
88
+ < input
89
+ type = "button"
90
+ name = "del_entry"
91
+ value = "Delete..."
92
+ onClick = { e => handleDeleteField ( e , idx ) }
93
+ style = { { backgroundColor : "white" } } />
94
+ < br />
95
+ </ >
96
+ ) ) }
97
+ < input
98
+ type = "button"
99
+ name = "add_entry"
100
+ value = "Add..."
101
+ onClick = { handleAddField }
102
+ style = { { backgroundColor : "white" } } />
103
+ < button
104
+ type = "submit"
105
+ name = "submit"
106
+ style = { { backgroundColor : "white" } } > Submit</ button >
107
+ </ form >
108
+ </ div >
109
+ )
110
+ }
111
+
112
+ export default NewQuestion ;
0 commit comments