1+ import { useState } from "react" ;
2+ import Popup from "./PopUp" ;
3+ import { TaskDifficulty } from "../../../objects/BoardTask" ;
4+ import "../styles/CreateTaskPopUp.css"
5+
6+ type TaskFormData = {
7+ title : string ;
8+ description : string ;
9+ difficulty : string ;
10+ tags : string [ ] ;
11+ requirements : string [ ] ;
12+ resources : File [ ] ; // files for upload
13+ token : {
14+ name : string ;
15+ description : string ;
16+ image : File | null ; // image upload
17+ } ;
18+ } ;
19+
20+ type CreateTaskPopUpProps = {
21+ onSubmit : ( data : TaskFormData ) => void ;
22+ isOpen : boolean ;
23+ onClose : ( ) => void ;
24+ }
25+
26+ function CreateTaskPopUp ( { onSubmit, isOpen, onClose } : CreateTaskPopUpProps ) {
27+ const [ form , setForm ] = useState < TaskFormData > ( {
28+ title : "" ,
29+ description : "" ,
30+ difficulty : "Beginner" ,
31+ tags : [ ] ,
32+ requirements : [ ] ,
33+ resources : [ ] ,
34+ token : { name : "" , description : "" , image : null } ,
35+ } ) ;
36+
37+ const handleChange = ( field : keyof TaskFormData , value : any ) => {
38+ setForm ( ( prev ) => ( { ...prev , [ field ] : value } ) ) ;
39+ } ;
40+
41+ const handleTokenChange = ( field : keyof TaskFormData [ "token" ] , value : any ) => {
42+ setForm ( ( prev ) => ( {
43+ ...prev ,
44+ token : { ...prev . token , [ field ] : value } ,
45+ } ) ) ;
46+ } ;
47+
48+ const handleSubmit = ( e : React . FormEvent ) => {
49+ e . preventDefault ( ) ;
50+ onSubmit ( form ) ;
51+ } ;
52+
53+ return (
54+ < Popup isOpen = { isOpen } onClose = { onClose } title = "Create a New Task" >
55+ < form className = "task-form" onSubmit = { handleSubmit } >
56+ < label >
57+ Title
58+ < input type = "text" value = { form . title } onChange = { ( e ) => handleChange ( "title" , e . target . value ) } required />
59+ </ label >
60+
61+ < label >
62+ Description
63+ < textarea value = { form . description } onChange = { ( e ) => handleChange ( "description" , e . target . value ) } />
64+ </ label >
65+
66+ < label >
67+ Difficulty
68+ < select value = { form . difficulty } onChange = { ( e ) => handleChange ( "difficulty" , e . target . value ) } >
69+ { Object . values ( TaskDifficulty ) . map ( ( diff ) => (
70+ < option key = { diff } value = { diff } >
71+ { diff }
72+ </ option >
73+ ) ) }
74+ </ select >
75+ </ label >
76+
77+ < label >
78+ Tags (comma separated)
79+ < input type = "text" value = { form . tags } onChange = { ( e ) => handleChange ( "tags" , e . target . value . split ( "," ) . map ( ( tag ) => tag . trim ( ) ) ) } />
80+ </ label >
81+
82+ < label >
83+ Requirements (comma separated)
84+ < input
85+ type = "text"
86+ value = { form . requirements . join ( ", " ) }
87+ onChange = { ( e ) =>
88+ handleChange (
89+ "requirements" ,
90+ e . target . value . split ( "," ) . map ( ( req ) => req . trim ( ) )
91+ )
92+ }
93+ />
94+ </ label >
95+
96+ < label >
97+ Resources (one per line, e.g. IPFS links)
98+ < input
99+ type = "file"
100+ multiple
101+ onChange = { ( e ) =>
102+ handleChange ( "resources" , e . target . files ? Array . from ( e . target . files ) : [ ] )
103+ }
104+ />
105+ </ label >
106+
107+ < h3 > Token Metadata</ h3 >
108+
109+ < label >
110+ Token Name:
111+ < input
112+ type = "text"
113+ value = { form . token . name }
114+ onChange = { ( e ) => handleTokenChange ( "name" , e . target . value ) }
115+ required
116+ />
117+ </ label >
118+
119+ < label >
120+ Token Description:
121+ < textarea
122+ value = { form . token . description }
123+ onChange = { ( e ) => handleTokenChange ( "description" , e . target . value ) }
124+ />
125+ </ label >
126+
127+ < label >
128+ Token Image:
129+ < input
130+ type = "file"
131+ accept = "image/*"
132+ onChange = { ( e ) =>
133+ handleTokenChange ( "image" , e . target . files ? e . target . files [ 0 ] : null )
134+ }
135+ required
136+ />
137+ </ label >
138+
139+ < button type = "submit" >
140+ Create Task
141+ </ button >
142+ </ form >
143+ </ Popup >
144+ ) ;
145+ }
146+
147+ export default CreateTaskPopUp ;
0 commit comments