1 | import {useDispatch, useSelector} from "react-redux";
|
---|
2 | import React, {useEffect, useState} from "react";
|
---|
3 | import {RecruiterActions} from "../../redux/actions/recruiterActions";
|
---|
4 | import * as yup from "yup";
|
---|
5 | import {useForm} from "react-hook-form";
|
---|
6 | import {yupResolver} from "@hookform/resolvers/yup";
|
---|
7 |
|
---|
8 | // Toast notification
|
---|
9 | import 'react-toastify/dist/ReactToastify.css';
|
---|
10 | import { toast, ToastContainer } from 'react-toastify';
|
---|
11 | import {notifyLogoChange, notifyProfileEdit} from "../../utils/toastUtils";
|
---|
12 | export const RecruiterEditProfile = () => {
|
---|
13 |
|
---|
14 | const dispatch = useDispatch();
|
---|
15 | const auth = useSelector(state => (state.auth.currentUser))
|
---|
16 |
|
---|
17 | const [recruiterDetails, setRecruiterDetails] = useState(null);
|
---|
18 |
|
---|
19 | let logosState = useSelector(state => state.images.logos)
|
---|
20 | const [logoDispatched, setLogoDispatched] = useState(false)
|
---|
21 | const [logoFile, setLogoFile] = useState(null);
|
---|
22 | const [logoPreview, setLogoPreview] = useState(null);
|
---|
23 | const [logoView, setLogoView] = useState(null);
|
---|
24 |
|
---|
25 |
|
---|
26 | useEffect(() => {
|
---|
27 | if (auth) {
|
---|
28 | dispatch(RecruiterActions.fetchRecruiterEditDetailsById(auth.id, (success, response) => {
|
---|
29 | if (success) {
|
---|
30 | setRecruiterDetails(response.data)
|
---|
31 | }
|
---|
32 | }))
|
---|
33 | }
|
---|
34 | }, [auth]);
|
---|
35 |
|
---|
36 | useEffect(() => {
|
---|
37 | if (auth.id) {
|
---|
38 | if (!logoDispatched && !logosState[auth.id]) {
|
---|
39 | dispatch(RecruiterActions.downloadLogo(auth.id, (success, response) => {
|
---|
40 | if (success) {
|
---|
41 | setLogoView(response)
|
---|
42 | setLogoDispatched(true)
|
---|
43 | }
|
---|
44 | }))
|
---|
45 | console.log("LOGO GET")
|
---|
46 | } else {
|
---|
47 | setLogoView(logosState[auth.id])
|
---|
48 | console.log("LOGO STATE")
|
---|
49 | }
|
---|
50 | }
|
---|
51 |
|
---|
52 | }, [auth])
|
---|
53 |
|
---|
54 | const schema = yup.object().shape({
|
---|
55 | email: yup.string().required("Please enter your email"),
|
---|
56 | companyName: yup.string().required("Please enter your company name"),
|
---|
57 | companyDescription: yup.string(),
|
---|
58 | contactEmail: yup.string().required("Please enter your contact email"),
|
---|
59 | contactPhoneNumber: yup.string().required("Please enter your contact phone number"),
|
---|
60 | receptionist: yup.string(),
|
---|
61 | })
|
---|
62 |
|
---|
63 | const {register, handleSubmit, control, formState: {errors}} = useForm({
|
---|
64 | resolver: yupResolver(schema),
|
---|
65 | });
|
---|
66 |
|
---|
67 |
|
---|
68 | const editRecruiterDetails = async (values) => {
|
---|
69 | try {
|
---|
70 | dispatch(RecruiterActions.editRecruiterDetailsById(
|
---|
71 | {
|
---|
72 | email: values.email,
|
---|
73 | companyName: values.companyName,
|
---|
74 | companyDescription: values.companyDescription,
|
---|
75 | contactEmail: values.contactEmail,
|
---|
76 | contactPhoneNumber: values.contactPhoneNumber,
|
---|
77 | receptionist: values.receptionist,
|
---|
78 |
|
---|
79 | }, auth.id, (success, response) => {
|
---|
80 | if (success) {
|
---|
81 | console.log("Recruiter details edited")
|
---|
82 | notifyProfileEdit()
|
---|
83 | //window.location.reload();
|
---|
84 | }
|
---|
85 | }
|
---|
86 | ))
|
---|
87 | } catch (err) {
|
---|
88 | console.error(err)
|
---|
89 | }
|
---|
90 | }
|
---|
91 |
|
---|
92 | const handleButtonClick = () => {
|
---|
93 | document.getElementById('logo-upload-input').click();
|
---|
94 | };
|
---|
95 | const handleLogoChange = (event) => {
|
---|
96 | const file = event.target.files[0];
|
---|
97 | if (file && (file.type === 'image/png' || file.type === 'image/jpeg')) {
|
---|
98 | setLogoFile(file);
|
---|
99 | setLogoPreview(URL.createObjectURL(file));
|
---|
100 | }
|
---|
101 | event.target.value = null;
|
---|
102 | };
|
---|
103 |
|
---|
104 | const handleLogoUpload = async () => {
|
---|
105 | try {
|
---|
106 | const formData = new FormData();
|
---|
107 | formData.append("recruiterId", auth.id);
|
---|
108 | formData.append("logoFile", logoFile);
|
---|
109 |
|
---|
110 | dispatch(RecruiterActions.submitLogo(formData, (success, response) => {
|
---|
111 | if (success) {
|
---|
112 | //console.log("Logo uploaded successfully")
|
---|
113 | notifyLogoChange()
|
---|
114 | setLogoPreview(null)
|
---|
115 | setLogoView(URL.createObjectURL(logoFile))
|
---|
116 | }
|
---|
117 | }))
|
---|
118 |
|
---|
119 | } catch (error) {
|
---|
120 | console.error(error)
|
---|
121 | }
|
---|
122 | }
|
---|
123 |
|
---|
124 | const handleCancelUpload = () => {
|
---|
125 | setLogoFile(null)
|
---|
126 | setLogoPreview(null)
|
---|
127 | console.log(logoPreview)
|
---|
128 | }
|
---|
129 |
|
---|
130 | return (<div className="my-workspace">
|
---|
131 | {logoPreview && (
|
---|
132 | <div className="confirmation-bar">
|
---|
133 | <div className="confirmation-bar-buttons">
|
---|
134 | <button className="cancel-changes" onClick={handleCancelUpload}>Cancel</button>
|
---|
135 | <button className="save-changes" onClick={handleLogoUpload}>Save changes</button>
|
---|
136 |
|
---|
137 | </div>
|
---|
138 | </div>
|
---|
139 | )}
|
---|
140 |
|
---|
141 | <div className="custom-container no-additional-margin">
|
---|
142 | <div className="photo-box">
|
---|
143 | <div>
|
---|
144 | <img
|
---|
145 | src="/images/default-company-banner.jpg"
|
---|
146 | className="company-banner"
|
---|
147 | alt="Company Banner"
|
---|
148 | />
|
---|
149 | {logoPreview ? <>
|
---|
150 | <img
|
---|
151 | src={logoPreview}
|
---|
152 | className="company-logo"
|
---|
153 | alt=""
|
---|
154 | width={200} height={200}
|
---|
155 | />
|
---|
156 | </> : <>
|
---|
157 | <img
|
---|
158 | // loading gif
|
---|
159 | src={logoView}
|
---|
160 | className="company-logo"
|
---|
161 | alt=""
|
---|
162 | width={200} height={200}
|
---|
163 | />
|
---|
164 | </>}
|
---|
165 | </div>
|
---|
166 |
|
---|
167 | <div className="info-tab">
|
---|
168 | <h3>{recruiterDetails && recruiterDetails.companyName}</h3>
|
---|
169 | </div>
|
---|
170 |
|
---|
171 | <div className="edit-buttons">
|
---|
172 | <input
|
---|
173 | type="file"
|
---|
174 | id="logo-upload-input"
|
---|
175 | accept="image/png, image/jpeg"
|
---|
176 | onChange={handleLogoChange}
|
---|
177 | style={{display: 'none'}}
|
---|
178 | />
|
---|
179 | <button onClick={handleButtonClick}>
|
---|
180 | <i className="fa-solid fa-camera"></i> Change logo
|
---|
181 | </button>
|
---|
182 | <button><i className="fa-solid fa-panorama"></i> Change cover photo</button>
|
---|
183 | </div>
|
---|
184 |
|
---|
185 | </div>
|
---|
186 |
|
---|
187 |
|
---|
188 | {/*<i className="fa-solid fa-circle-exclamation">*/}
|
---|
189 | {recruiterDetails && (
|
---|
190 | <div className="floating-wrap">
|
---|
191 | <h5>Company details</h5>
|
---|
192 | <form onSubmit={handleSubmit(editRecruiterDetails)}>
|
---|
193 | <div className="row">
|
---|
194 | <div className="col-md-6">
|
---|
195 | <div className="form-floating mb-3">
|
---|
196 | <input type="text" className="form-control" defaultValue={recruiterDetails.email} {...register("email")}
|
---|
197 | placeholder="David"/>
|
---|
198 | <label htmlFor="floatingFirstName">Email address</label>
|
---|
199 | <p className="error-message">{errors.email?.message}</p>
|
---|
200 | </div>
|
---|
201 |
|
---|
202 | <div className="form-floating mb-3">
|
---|
203 | <input type="text" className="form-control" defaultValue={recruiterDetails.contactEmail} {...register("contactEmail")}
|
---|
204 | placeholder="David"/>
|
---|
205 | <label htmlFor="floatingFirstName">Contact email address</label>
|
---|
206 | <p className="error-message">{errors.contactEmail?.message}</p>
|
---|
207 | </div>
|
---|
208 |
|
---|
209 |
|
---|
210 | <div className="form-floating mb-3">
|
---|
211 | <input type="text" className="form-control" defaultValue={recruiterDetails.contactPhoneNumber} {...register("contactPhoneNumber")}
|
---|
212 | placeholder="David"/>
|
---|
213 | <label htmlFor="floatingFirstName">Contact phone number</label>
|
---|
214 | <p className="error-message">{errors.contactPhoneNumber?.message}</p>
|
---|
215 | </div>
|
---|
216 |
|
---|
217 | <div className="form-floating mb-3">
|
---|
218 | <input type="text" className="form-control" defaultValue={recruiterDetails.receptionist} {...register("receptionist")}
|
---|
219 | placeholder="David"/>
|
---|
220 | <label htmlFor="floatingFirstName">Receptionist</label>
|
---|
221 | <p className="error-message">{errors.receptionist?.message}</p>
|
---|
222 | </div>
|
---|
223 | </div>
|
---|
224 | <div className="col-md-6">
|
---|
225 | <div className="form-floating mb-3">
|
---|
226 | <input type="text" className="form-control" defaultValue={recruiterDetails.companyName} {...register("companyName")}
|
---|
227 | placeholder="David"/>
|
---|
228 | <label htmlFor="floatingCompanyName">Company name</label>
|
---|
229 | <p className="error-message">{errors.companyName?.message}</p>
|
---|
230 | </div>
|
---|
231 |
|
---|
232 | <div className="form-floating mb-3">
|
---|
233 | <textarea placeholder="Company description" defaultValue={recruiterDetails.companyDescription} className="form-control custom-text-area"
|
---|
234 | name="" id="" cols="30" rows="9" {...register("companyDescription")}></textarea>
|
---|
235 | <label htmlFor="floatingCompanyName">Company description</label>
|
---|
236 | </div>
|
---|
237 |
|
---|
238 | </div>
|
---|
239 | </div>
|
---|
240 | <div className="d-flex justify-content-end">
|
---|
241 | <button className="blue-submit-button" type="submit">Save changes</button>
|
---|
242 | </div>
|
---|
243 | </form>
|
---|
244 | </div>
|
---|
245 | )}
|
---|
246 | {/*<div className="line-separator"></div>*/}
|
---|
247 | </div>
|
---|
248 | </div>
|
---|
249 |
|
---|
250 | )
|
---|
251 | } |
---|