1- import React , { useState } from "react" ;
1+ import React , { useEffect , useState } from "react" ;
22import {
33 Button ,
44 Typography ,
@@ -8,19 +8,66 @@ import {
88 Slider ,
99 FormControlLabel ,
1010 Switch ,
11+ Autocomplete ,
1112} from "@mui/material" ;
1213
1314import "../styles/Modal.css" ;
1415
16+ const skills = [ "Python" , "Java" , "SQL" , "JavaScript" , "C++" , "C#" , "C" ] ;
17+
1518function CreateJobModal ( props ) {
19+ const [ isEditing , setIsEditing ] = useState ( false ) ;
1620 const [ showSalary , setShowSalary ] = useState ( false ) ;
1721 const [ salary , setSalary ] = useState ( [ 0 , 0 ] ) ;
22+ const [ title , setTitle ] = useState ( "" ) ;
23+ const [ description , setDescription ] = useState ( "" ) ;
24+ const [ location , setLocation ] = useState ( "" ) ;
25+ const [ company_name , setCompanyName ] = useState ( "" ) ;
1826 const [ showGenericError , setShowGenericError ] = useState ( false ) ;
1927
28+ const [ selectedSkills , setSelectedSkills ] = useState ( [ ] ) ;
29+
30+ useEffect ( ( ) => {
31+ if ( props . job ) {
32+ setIsEditing ( true ) ;
33+ setTitle ( props . job . title ) ;
34+ setDescription ( props . job . description ) ;
35+ setLocation ( props . job . location ) ;
36+ setCompanyName ( props . job . company_name ) ;
37+ if ( props . job . min_salary ) {
38+ setShowSalary ( true ) ;
39+ setSalary ( [ props . job . min_salary , props . job . max_salary ] ) ;
40+ }
41+ }
42+ } , [ props ] ) ;
43+
2044 const handleSalaryChange = ( e , newValue ) => {
2145 setSalary ( newValue ) ;
2246 } ;
2347
48+ const handleSkillSelection = ( event , value ) => {
49+ setSelectedSkills ( value ) ;
50+ } ;
51+
52+ const submitJobSkills = async ( jobId , skills ) => {
53+ await fetch ( `https://chapi.techstartucalgary.com/jobs/skills/${ jobId } ` , {
54+ method : "POST" ,
55+ headers : {
56+ "Content-Type" : "application/json" ,
57+ Authorization : `Bearer ${ localStorage . getItem ( "access_token" ) } ` ,
58+ } ,
59+ body : JSON . stringify ( skills . map ( ( skill ) => ( { skill } ) ) ) ,
60+ } )
61+ . then ( ( response ) => {
62+ if ( ! response . ok ) {
63+ throw new Error ( "Skills update failed" ) ;
64+ }
65+ } )
66+ . catch ( ( error ) => {
67+ console . error ( error ) ;
68+ } ) ;
69+ } ;
70+
2471 const submitNewJob = async ( event ) => {
2572 event . preventDefault ( ) ;
2673 const formData = new FormData ( event . target ) ;
@@ -34,33 +81,62 @@ function CreateJobModal(props) {
3481 title,
3582 description,
3683 location,
37- company_name,
3884 min_salary,
3985 max_salary,
86+ company_name,
87+ skills : selectedSkills . map ( ( skill ) => ( { skill } ) ) ,
4088 } ;
4189
42- await fetch ( "https://chapi.techstartucalgary.com/jobs" , {
43- method : "POST" ,
44- headers : {
45- "Content-Type" : "application/json" ,
46- Authorization : `Bearer ${ localStorage . getItem ( "access_token" ) } ` ,
47- } ,
48- body : JSON . stringify ( data ) ,
49- } )
50- . then ( ( response ) => {
51- if ( ! response . ok ) {
52- if ( response . status === 401 ) {
53- window . location . href = "#/signin" ;
54- } else {
55- setShowGenericError ( true ) ;
90+ if ( isEditing ) {
91+ await fetch ( `https://chapi.techstartucalgary.com/jobs/${ props . job . id } ` , {
92+ method : "PATCH" ,
93+ headers : {
94+ "Content-Type" : "application/json" ,
95+ Authorization : `Bearer ${ localStorage . getItem ( "access_token" ) } ` ,
96+ } ,
97+ body : JSON . stringify ( data ) ,
98+ } )
99+ . then ( async ( response ) => {
100+ if ( ! response . ok ) {
101+ if ( response . status === 401 ) {
102+ window . location . href = "#/signin" ;
103+ } else {
104+ setShowGenericError ( true ) ;
105+ }
106+ throw new Error ( "Job creation failed" ) ;
56107 }
57- throw new Error ( "Job creation failed" ) ;
58- }
59- props . closeModal ( ) ;
108+ await submitJobSkills ( props . job . id , selectedSkills ) ;
109+ cancelModal ( ) ;
110+ } )
111+ . catch ( ( error ) => {
112+ console . error ( error ) ;
113+ } ) ;
114+ } else {
115+ await fetch ( "https://chapi.techstartucalgary.com/jobs" , {
116+ method : "POST" ,
117+ headers : {
118+ "Content-Type" : "application/json" ,
119+ Authorization : `Bearer ${ localStorage . getItem ( "access_token" ) } ` ,
120+ } ,
121+ body : JSON . stringify ( data ) ,
60122 } )
61- . catch ( ( error ) => {
62- console . error ( error ) ;
63- } ) ;
123+ . then ( async ( response ) => {
124+ if ( ! response . ok ) {
125+ if ( response . status === 401 ) {
126+ window . location . href = "#/signin" ;
127+ } else {
128+ setShowGenericError ( true ) ;
129+ }
130+ throw new Error ( "Job creation failed" ) ;
131+ }
132+ const jobData = await response . json ( ) ;
133+ await submitJobSkills ( jobData . id , selectedSkills ) ;
134+ props . closeModal ( ) ;
135+ } )
136+ . catch ( ( error ) => {
137+ console . error ( error ) ;
138+ } ) ;
139+ }
64140 } ;
65141
66142 const formatCurrency = ( num ) => {
@@ -71,19 +147,63 @@ function CreateJobModal(props) {
71147 } ) ;
72148 } ;
73149
150+ const cancelModal = ( ) => {
151+ setTitle ( "" ) ;
152+ setDescription ( "" ) ;
153+ setLocation ( "" ) ;
154+ setCompanyName ( "" ) ;
155+ setShowSalary ( false ) ;
156+ setShowGenericError ( false ) ;
157+ setSalary ( [ 0 , 0 ] ) ;
158+ setIsEditing ( false ) ;
159+ props . closeModal ( ) ;
160+ } ;
161+
74162 return (
75163 < Dialog open = { props . open } fullWidth >
76- < DialogTitle > Create New Job</ DialogTitle >
77- < form className = "form" onSubmit = { submitNewJob } >
78- < TextField name = "title" label = "Job Title" required />
79- < TextField name = "company_name" label = "Company Name" required />
164+ < DialogTitle >
165+ { isEditing ? "Update Existing Job" : "Create New Job" }
166+ </ DialogTitle >
167+
168+ < form id = "jobForm" className = "form" onSubmit = { submitNewJob } >
169+ < TextField
170+ name = "title"
171+ label = "Job Title"
172+ onChange = { ( e ) => setTitle ( e . target . value ) }
173+ value = { title }
174+ required
175+ />
80176 < TextField
81177 name = "description"
82178 label = "Job Description"
179+ onChange = { ( e ) => setDescription ( e . target . value ) }
180+ value = { description }
83181 multiline
84182 required
85183 />
86- < TextField name = "location" label = "Location" required />
184+ < TextField
185+ name = "location"
186+ label = "Location"
187+ onChange = { ( e ) => setLocation ( e . target . value ) }
188+ value = { location }
189+ required
190+ />
191+ < Autocomplete
192+ multiple
193+ options = { skills }
194+ value = { selectedSkills }
195+ onChange = { handleSkillSelection }
196+ renderInput = { ( params ) => (
197+ < TextField { ...params } label = "Required Skills" variant = "outlined" />
198+ ) }
199+ />
200+ < TextField
201+ name = "company_name"
202+ label = "Company Name"
203+ onChange = { ( e ) => setCompanyName ( e . target . value ) }
204+ value = { company_name }
205+ required
206+ />
87207 < FormControlLabel
88208 control = {
89209 < Switch
@@ -116,9 +236,11 @@ function CreateJobModal(props) {
116236 ) }
117237 </ div >
118238 < div className = "row right-align button-container" >
119- < Button variant = "outlined" /*onClick={cancelModal}*/ > Cancel</ Button >
239+ < Button variant = "outlined" onClick = { cancelModal } >
240+ Cancel
241+ </ Button >
120242 < Button type = "submit" variant = "contained" >
121- { /* isEditing ? `Update Job` : `Post Job`*/ }
243+ { isEditing ? `Update Job` : `Post Job` }
122244 </ Button >
123245 </ div >
124246 </ form >
0 commit comments