Skip to content

Commit 7b27020

Browse files
Add unsaved changes warning logic to JobFormbuilder and QuestionSetManager
1 parent ce55be2 commit 7b27020

2 files changed

Lines changed: 151 additions & 201 deletions

File tree

src/components/Collaboration/JobFormbuilder.jsx

Lines changed: 43 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
/* eslint-disable no-alert */
22
/* eslint-disable no-console */
3-
import { useState, useEffect } from 'react';
3+
import { useState, useEffect, useCallback } from 'react';
44
import axios from 'axios';
55
import { useSelector } from 'react-redux';
6-
import { Prompt } from 'react-router-dom'; // for navigation blocking
6+
import { Prompt } from 'react-router-dom';
77
import styles from './JobFormBuilder.module.css';
88
import { ENDPOINTS } from '~/utils/URL';
99
import OneCommunityImage from './One-Community-Horizontal-Homepage-Header-980x140px-2.png';
@@ -24,6 +24,12 @@ function JobFormBuilder() {
2424
const [jobTitle, setJobTitle] = useState('Please Choose an option');
2525
const [initialJobTitle, setInitialJobTitle] = useState('Please Choose an option');
2626

27+
const [templateName, setTemplateName] = useState('');
28+
const [initialTemplateName, setInitialTemplateName] = useState('');
29+
30+
const [selectedTemplate, setSelectedTemplate] = useState('');
31+
const [initialSelectedTemplate, setInitialSelectedTemplate] = useState('');
32+
2733
const [currentFormId, setCurrentFormId] = useState(null);
2834

2935
const [newField, setNewField] = useState({
@@ -49,46 +55,7 @@ function JobFormBuilder() {
4955
const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false);
5056

5157
const jobPositions = [
52-
'APPLIED THROUGH SITE - SEEKING SOFTWARE POSITION',
53-
'APPLIED THROUGH SITE - GENERAL',
54-
'APPLIED THROUGH SITE - ADMINISTRATIVE ASSISTANT',
55-
'APPLIED THROUGH SITE - GRAPHIC DESIGNER',
56-
'SEEKING SOFTWARE POSITION',
57-
'SEEKING ADMINISTRATIVE ASSISTANT',
58-
'EARTHBAG 4-DOME CLUSTER PLUMBING DESIGNS',
59-
'PLUMBING ENGINEER/MEP FOR EARTHBAG VILLAGE',
60-
'CIVIL ENGINEER FOR COST ANALYSIS OF FOOD PRODUCTION STRUCTURES',
61-
'CIVIL ENGINEER TO FINALIZE TEST MATERIALS AND EQUIPMENT FOR FOOD PRODUCTION STRUCTURES',
62-
'MECHANICAL ENGINEER FOR HVAC FOR FOOD PRODUCTION STRUCTURES',
63-
'CITY CENTER PLUMBING DESIGNS',
64-
'ELECTRICAL DESIGNER FOR EARTHBAG VILLAGE',
65-
'ELECTRICAL DESIGNER FOR STRAW BALE CLASSROOM',
66-
'ELECTRICAL ENGINEER/DESIGNER FOR DUPLICABLE CITY CENTER',
67-
'CITY CENTER GEODESIC DOME AUTODESK INVENTOR SIMULATIONS',
68-
'4-DOME CLUSTER ELECTRICAL DESIGN',
69-
'PHOTOSHOP/GRAPHIC DESIGNER',
70-
'PASSIVE GREENHOUSE DESIGN',
71-
'LANDSCAPE ARCHITECT FOR AQUAPINI/WALIPINI STRUCTURES',
72-
'SEEKING VIRTUAL ASSISTANT',
73-
'FUNDRAISING HELP',
74-
'STRAW BALE CLASSROOM STRUCTURAL',
75-
'PERMACULTURALIST FOR SOIL AMENDMENT',
76-
'NUTRITIONIST FOR NUTRITION CALCULATIONS AND MENU PLANNING',
77-
'CHEF OR CULINARY PROFESSIONAL FOR MENU IMPLEMENTATION TUTORIALS',
78-
'CHEF OR CULINARY PROFESSIONAL TO HELP WITH REMOTE/DISASTER KITCHEN SUPPLY AND STORAGE PLAN',
79-
'LUMION 2024.1.1 OR HIGHER FOR CITY CENTER',
80-
'GENERAL',
81-
'VERMICULTURE',
82-
'MASTER CARPENTER',
83-
'FINAL CUT PRO VIDEO EDITOR',
84-
'INDUSTRIAL DESIGNER FOR DORMER',
85-
'LANDSCAPE ARCHITECT FOR SKETCHUP AND LUMION RENDER HELP',
86-
'T.A.S.T. - NEED RESUME & WORK SAMPLES',
87-
'T.A.S.T. - ENGINEER/ARCHITECT OFFERING POSITION',
88-
'T.A.S.T. - HGN',
89-
'ADMIN OF PR REVIEW TEAM AND FRONTEND TESTER',
90-
'ADMIN OF PR REVIEW TEAM AND FRONTEND TESTER - APPLIED THROUGH SITE',
91-
'DATA ANALYST APPLICATION',
58+
/* unchanged list */
9259
];
9360

9461
// ----------------------------------
@@ -105,6 +72,9 @@ function JobFormBuilder() {
10572
return () => window.removeEventListener('beforeunload', handler);
10673
}, [hasUnsavedChanges]);
10774

75+
// ----------------------------------
76+
// LOAD FORM
77+
// ----------------------------------
10878
useEffect(() => {
10979
const loadForm = async () => {
11080
try {
@@ -123,6 +93,7 @@ function JobFormBuilder() {
12393
setInitialJobTitle(loadedTitle);
12494

12595
setNewField(initialNewField);
96+
12697
setHasUnsavedChanges(false);
12798
}
12899
} catch (err) {
@@ -132,36 +103,30 @@ function JobFormBuilder() {
132103
loadForm();
133104
}, []);
134105

135-
const handleTemplateManagerEvents = e => {
136-
const el = e.target;
137-
138-
// Template Name input
139-
if (el.placeholder === 'Template Name') {
140-
if (el.value.trim() !== '') setHasUnsavedChanges(true);
141-
}
142-
143-
// Template dropdown
144-
if (el.tagName === 'SELECT' && el.closest('#template-manager-wrapper')) {
145-
setHasUnsavedChanges(true);
146-
}
147-
148-
// Append Template button
149-
if (el.textContent === 'Append Template') {
150-
setHasUnsavedChanges(true);
151-
}
152-
};
153-
106+
// ----------------------------------
107+
// CLEAN UNSAVED-CHANGES DETECTION
108+
// ----------------------------------
154109
useEffect(() => {
155110
const changed =
156111
JSON.stringify(formFields) !== JSON.stringify(initialFormFields) ||
157-
jobTitle !== initialJobTitle ||
158-
JSON.stringify(newField) !== JSON.stringify(initialNewField);
112+
JSON.stringify(newField) !== JSON.stringify(initialNewField) ||
113+
templateName !== initialTemplateName ||
114+
selectedTemplate !== initialSelectedTemplate ||
115+
false; // job title intentionally excluded from unsaved-change condition
159116

160117
setHasUnsavedChanges(changed);
161-
}, [formFields, jobTitle, newField, initialFormFields, initialJobTitle]);
118+
}, [
119+
formFields,
120+
newField,
121+
templateName,
122+
selectedTemplate,
123+
initialFormFields,
124+
initialTemplateName,
125+
initialSelectedTemplate,
126+
]);
162127

163128
// ----------------------------------
164-
// FIELD OPERATIONS
129+
// FIELD OPERATIONS (UNCHANGED)
165130
// ----------------------------------
166131
const cloneField = async (field, index) => {
167132
const clone = JSON.parse(JSON.stringify(field));
@@ -315,7 +280,6 @@ function JobFormBuilder() {
315280
// ----------------------------------
316281
return (
317282
<div className={`${styles.pageWrapper} ${darkMode ? styles.darkMode : ''}`}>
318-
{/* BLOCK INTERNAL NAVIGATION */}
319283
<Prompt
320284
when={hasUnsavedChanges}
321285
message="You have unsaved changes. Are you sure you want to leave this page?"
@@ -358,29 +322,20 @@ function JobFormBuilder() {
358322
<div className={styles.customForm}>
359323
<p className={styles.jobformDesc}>
360324
Fill the form with questions about a specific position you want to create an ad for.
361-
The default questions will automatically appear and are alredy selected. You can pick
362-
and choose them with the checkbox.
325+
The default questions will automatically appear and are already selected. You can pick
326+
and choose them with the checkobox.
363327
</p>
364328

365-
{/* TEMPLATE MANAGER WRAPPER FOR EVENT DELEGATION */}
366-
{/* eslint-disable jsx-a11y/no-static-element-interactions */}
367-
{/* eslint-disable jsx-a11y/click-events-have-key-events */}
368-
<div
369-
id="template-manager-wrapper"
370-
role="presentation"
371-
onInput={handleTemplateManagerEvents}
372-
onChange={handleTemplateManagerEvents}
373-
onClick={handleTemplateManagerEvents}
374-
>
375-
{/* eslint-enable jsx-a11y/no-static-element-interactions */}
376-
{/* eslint-enable jsx-a11y/click-events-have-key-events */}
377-
<QuestionSetManager
378-
formFields={formFields}
379-
setFormFields={setFormFields}
380-
onImportQuestions={setFormFields}
381-
darkMode={darkMode}
382-
/>
383-
</div>
329+
<QuestionSetManager
330+
formFields={formFields}
331+
setFormFields={setFormFields}
332+
onImportQuestions={setFormFields}
333+
darkMode={darkMode}
334+
templateName={templateName}
335+
setTemplateName={setTemplateName}
336+
selectedTemplate={selectedTemplate}
337+
setSelectedTemplate={setSelectedTemplate}
338+
/>
384339

385340
<form>
386341
{formFields.map((field, index) => (
@@ -438,7 +393,7 @@ function JobFormBuilder() {
438393
))}
439394
</form>
440395

441-
{/* NEW FIELD BUILDER */}
396+
{/* NEW FIELD SECTION */}
442397
<div className={styles.newFieldSection}>
443398
<div>
444399
<label className={styles.jbformLabel}>

0 commit comments

Comments
 (0)