sr-npm 1.0.11 → 1.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.prettierrc +16 -0
- package/backend/collectionConsts.js +76 -0
- package/backend/consts.js +55 -110
- package/backend/data.js +354 -264
- package/backend/fetchPositionsFromSRAPI.js +47 -40
- package/backend/index.js +5 -4
- package/backend/queries.js +15 -14
- package/backend/secretsData.js +14 -0
- package/backend/utils.js +81 -4
- package/index.js +4 -5
- package/package.json +14 -3
- package/pages/careersPage.js +457 -0
- package/pages/homePage.js +136 -0
- package/pages/index.js +6 -0
- package/pages/positionPage.js +34 -0
- package/public/filterUtils.js +39 -0
- package/public/index.js +6 -0
- package/public/mapUtils.js +16 -0
- package/public/utils.js +45 -0
- package/tests/fetchPositionsFromSRApiTest.spec.js +35 -0
- package/tests/testsUtils.js +7 -0
- package/.wix/debug.log +0 -111
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
const { getAllPositions } = require('../backend/queries');
|
|
2
|
+
const {wixData} = require('wix-data');
|
|
3
|
+
const { window } = require('@wix/site-window');
|
|
4
|
+
const { query,queryParams,onChange} = require("wix-location-frontend");
|
|
5
|
+
const { location } = require("@wix/site-location");
|
|
6
|
+
|
|
7
|
+
const {
|
|
8
|
+
debounce,
|
|
9
|
+
getFilter,
|
|
10
|
+
} = require('../public/filterUtils');
|
|
11
|
+
const { filterBrokenMarkers } = require('../public/utils');
|
|
12
|
+
let currentLoadedItems =100;
|
|
13
|
+
const itemsPerPage = 100;
|
|
14
|
+
let allJobs=[]
|
|
15
|
+
const RESET_ALL = 'RESET_ALL';
|
|
16
|
+
let pageParamSet=0;
|
|
17
|
+
let thisObjectVar;
|
|
18
|
+
let queryPageVar;
|
|
19
|
+
let queryKeyWordVar;
|
|
20
|
+
let queryDepartmentVar;
|
|
21
|
+
let queryLocationVar;
|
|
22
|
+
let queryJobTypeVar;
|
|
23
|
+
let searchInputBlurredFirstTime=true;
|
|
24
|
+
let deletedParam=false;
|
|
25
|
+
async function careersPageOnReady(_$w,thisObject,queryParams) {
|
|
26
|
+
console.log("queryParams: ", queryParams);
|
|
27
|
+
const { page, keyWord, department, location,jobType } = queryParams;
|
|
28
|
+
queryPageVar=page;
|
|
29
|
+
queryKeyWordVar=keyWord;
|
|
30
|
+
queryDepartmentVar=department;
|
|
31
|
+
queryLocationVar=location;
|
|
32
|
+
queryJobTypeVar=jobType;
|
|
33
|
+
thisObjectVar=thisObject;
|
|
34
|
+
allJobs=await getAllPositions();
|
|
35
|
+
await activateAutoLoad(_$w);
|
|
36
|
+
await bind(_$w);
|
|
37
|
+
await init(_$w);
|
|
38
|
+
await handleUrlParams(_$w);
|
|
39
|
+
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
function activateAutoLoad(_$w)
|
|
44
|
+
{
|
|
45
|
+
_$w("#jobsDataset").onReady(() => {
|
|
46
|
+
updateCount(_$w);
|
|
47
|
+
_$w("#section2").onViewportEnter(() => {
|
|
48
|
+
if (currentLoadedItems<_$w("#jobsDataset").getTotalCount()) {
|
|
49
|
+
loadMoreJobs(_$w);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
console.log("no more jobs")
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async function loadMoreJobs(_$w) {
|
|
59
|
+
let shouldLoad = false;
|
|
60
|
+
if (pageParamSet == 0) {
|
|
61
|
+
shouldLoad = true;
|
|
62
|
+
} else if (query.page % 2 == pageParamSet % 2) {
|
|
63
|
+
shouldLoad = true;
|
|
64
|
+
} else {
|
|
65
|
+
pageParamSet = Number(pageParamSet) + 1;
|
|
66
|
+
}
|
|
67
|
+
if (shouldLoad) {
|
|
68
|
+
_$w("#jobsDataset").loadMore();
|
|
69
|
+
console.log("loading more jobs");
|
|
70
|
+
currentLoadedItems = currentLoadedItems + itemsPerPage;
|
|
71
|
+
const data = _$w("#positionsRepeater").data;
|
|
72
|
+
console.log("data length is : ", data.length);
|
|
73
|
+
setPageParamInUrl();
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
async function setPageParamInUrl() {
|
|
79
|
+
if(queryPageVar){
|
|
80
|
+
queryParams.add({ page: Number(queryPageVar) + 1 })
|
|
81
|
+
queryPageVar=Number(queryPageVar) + 1
|
|
82
|
+
}
|
|
83
|
+
else{
|
|
84
|
+
queryParams.add({ page: 2 })
|
|
85
|
+
queryPageVar=2
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
}
|
|
90
|
+
async function handleUrlParams(_$w) {
|
|
91
|
+
if (queryKeyWordVar) {
|
|
92
|
+
await handleKeyWordParam(_$w,queryKeyWordVar);
|
|
93
|
+
}
|
|
94
|
+
if (queryPageVar) {
|
|
95
|
+
await handlePageParam(_$w);
|
|
96
|
+
}
|
|
97
|
+
if (queryDepartmentVar) {
|
|
98
|
+
await handleDepartmentParam(_$w,queryDepartmentVar);
|
|
99
|
+
}
|
|
100
|
+
if (queryLocationVar) {
|
|
101
|
+
await handleLocationParam(_$w,queryLocationVar);
|
|
102
|
+
}
|
|
103
|
+
if (queryJobTypeVar) {
|
|
104
|
+
await handleJobTypeParam(_$w,queryJobTypeVar);
|
|
105
|
+
}
|
|
106
|
+
await applyFilters(_$w, true); // Skip URL update since we're handling initial URL params
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async function handleKeyWordParam(_$w,keyWord) {
|
|
110
|
+
_$w('#searchInput').value = keyWord;
|
|
111
|
+
// Use applyFilters to maintain consistency instead of directly setting filter
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async function handlePageParam(_$w) {
|
|
115
|
+
|
|
116
|
+
if(allJobs.length/itemsPerPage<queryPageVar){
|
|
117
|
+
console.log(`max page is: ${allJobs.length/itemsPerPage}`)
|
|
118
|
+
queryParams.add({ page: allJobs.length/itemsPerPage })
|
|
119
|
+
}
|
|
120
|
+
if(queryPageVar<=1){
|
|
121
|
+
console.log("min page is : 2")
|
|
122
|
+
pageParamSet=2;
|
|
123
|
+
queryParams.add({ page: 2 })
|
|
124
|
+
}
|
|
125
|
+
if (queryPageVar) {
|
|
126
|
+
pageParamSet=queryPageVar;
|
|
127
|
+
//scrolls a bit to load the dataset data
|
|
128
|
+
await window.scrollTo(0, 200,{scrollAnimation:false});
|
|
129
|
+
for (let i = 2; i <= queryPageVar; i++) {
|
|
130
|
+
await _$w("#jobsDataset").loadMore();
|
|
131
|
+
currentLoadedItems=currentLoadedItems+itemsPerPage
|
|
132
|
+
}
|
|
133
|
+
// the timeout is to wait for the repeater to render, then scroll to the last item.
|
|
134
|
+
setTimeout(() => {
|
|
135
|
+
const data = _$w("#positionsRepeater").data;
|
|
136
|
+
if (data && data.length > 0) {
|
|
137
|
+
//the dataset each time it loads 100 items
|
|
138
|
+
const lastIndex = data.length - itemsPerPage;
|
|
139
|
+
_$w("#positionsRepeater").forEachItem(async ($item, itemData, index) => {
|
|
140
|
+
if (index === lastIndex) {
|
|
141
|
+
await $item("#positionItem").scrollTo();
|
|
142
|
+
console.log("finishied scrolling inside handlePageParam")
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
}, 200);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
async function bind(_$w) {
|
|
152
|
+
await _$w('#jobsDataset').onReady(async () => {
|
|
153
|
+
await updateCount(_$w);
|
|
154
|
+
await updateMapMarkers(_$w);
|
|
155
|
+
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
if (await window.formFactor() === "Mobile") {
|
|
159
|
+
_$w('#dropdownsContainer').collapse();
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function init(_$w) {
|
|
165
|
+
const debouncedSearch = debounce(()=>applyFilters(_$w), 400,thisObjectVar);
|
|
166
|
+
_$w('#searchInput').onInput(debouncedSearch);
|
|
167
|
+
_$w('#searchInput').onBlur(()=>{
|
|
168
|
+
if(searchInputBlurredFirstTime && _$w('#searchInput').value.trim() !== '')
|
|
169
|
+
{
|
|
170
|
+
_$w('#searchInput').focus();
|
|
171
|
+
searchInputBlurredFirstTime=false;
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
_$w('#dropdownDepartment, #dropdownLocation, #dropdownJobType').onChange(()=>{
|
|
175
|
+
console.log("dropdown onChange is triggered");
|
|
176
|
+
applyFilters(_$w);
|
|
177
|
+
});
|
|
178
|
+
_$w('#resetFiltersButton, #clearSearch').onClick(()=>resetFilters(_$w));
|
|
179
|
+
|
|
180
|
+
_$w('#openFiltersButton').onClick(()=>{
|
|
181
|
+
_$w('#dropdownsContainer, #closeFiltersButton').expand();
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
_$w('#closeFiltersButton').onClick(()=>{
|
|
185
|
+
_$w('#dropdownsContainer, #closeFiltersButton').collapse();
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
//URL onChange
|
|
189
|
+
onChange(async ()=>{
|
|
190
|
+
await handleBackAndForth(_$w);
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
async function handleBackAndForth(_$w){
|
|
196
|
+
const newQueryParams=await location.query();
|
|
197
|
+
console.log("newQueryParams: ", newQueryParams);
|
|
198
|
+
if(newQueryParams.department){
|
|
199
|
+
queryDepartmentVar=newQueryParams.department;
|
|
200
|
+
}
|
|
201
|
+
else{
|
|
202
|
+
queryDepartmentVar=undefined;
|
|
203
|
+
deletedParam=true;
|
|
204
|
+
_$w('#dropdownDepartment').value = '';
|
|
205
|
+
}
|
|
206
|
+
if(newQueryParams.location){
|
|
207
|
+
queryLocationVar=newQueryParams.location;
|
|
208
|
+
}
|
|
209
|
+
else{
|
|
210
|
+
queryLocationVar=undefined;
|
|
211
|
+
deletedParam=true
|
|
212
|
+
_$w('#dropdownLocation').value = '';
|
|
213
|
+
}
|
|
214
|
+
if(newQueryParams.keyWord){
|
|
215
|
+
queryKeyWordVar=newQueryParams.keyWord;
|
|
216
|
+
}
|
|
217
|
+
else{
|
|
218
|
+
queryKeyWordVar=undefined;
|
|
219
|
+
deletedParam=true;
|
|
220
|
+
_$w('#searchInput').value = '';
|
|
221
|
+
}
|
|
222
|
+
if(newQueryParams.jobType){
|
|
223
|
+
queryJobTypeVar=newQueryParams.jobType;
|
|
224
|
+
}
|
|
225
|
+
else{
|
|
226
|
+
queryJobTypeVar=undefined;
|
|
227
|
+
deletedParam=true;
|
|
228
|
+
_$w('#dropdownJobType').value = '';
|
|
229
|
+
}
|
|
230
|
+
await handleUrlParams(_$w);
|
|
231
|
+
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
async function applyFilters(_$w, skipUrlUpdate = false) {
|
|
235
|
+
console.log("applying filters");
|
|
236
|
+
const dropdownFiltersMapping = [
|
|
237
|
+
{ elementId: '#dropdownDepartment', field: 'department', value: _$w('#dropdownDepartment').value },
|
|
238
|
+
{ elementId: '#dropdownLocation', field: 'cityText', value: _$w('#dropdownLocation').value },
|
|
239
|
+
{ elementId: '#dropdownJobType', field: 'remote', value: _$w('#dropdownJobType').value},
|
|
240
|
+
{ elementId: '#searchInput', field: 'title', value: _$w('#searchInput').value }
|
|
241
|
+
];
|
|
242
|
+
console.log("dropdownFiltersMapping: ", dropdownFiltersMapping);
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
let filters = [];
|
|
247
|
+
let value;
|
|
248
|
+
|
|
249
|
+
dropdownFiltersMapping.forEach(filter => {
|
|
250
|
+
// Handle RESET_ALL values
|
|
251
|
+
if (filter.value === RESET_ALL) {
|
|
252
|
+
_$w(filter.elementId).value = '';
|
|
253
|
+
filter.value = '';
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// build filters
|
|
257
|
+
if (filter.value && filter.value.trim() !== '') {
|
|
258
|
+
if (!skipUrlUpdate) {
|
|
259
|
+
if(filter.field === 'title'){
|
|
260
|
+
queryParams.add({ keyWord: filter.value });
|
|
261
|
+
}
|
|
262
|
+
if(filter.field === 'department'){
|
|
263
|
+
queryParams.add({ department: encodeURIComponent(filter.value) });
|
|
264
|
+
}
|
|
265
|
+
if(filter.field === 'cityText'){
|
|
266
|
+
queryParams.add({ location: encodeURIComponent(filter.value) });
|
|
267
|
+
}
|
|
268
|
+
if(filter.field === 'remote'){
|
|
269
|
+
if(filter.value === 'true'){
|
|
270
|
+
queryParams.add({ jobType: encodeURIComponent("remote") });
|
|
271
|
+
}
|
|
272
|
+
else{
|
|
273
|
+
queryParams.add({ jobType: encodeURIComponent("onsite") });
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
if(filter.field === 'remote') {
|
|
278
|
+
value = filter.value === 'true';
|
|
279
|
+
} else {
|
|
280
|
+
value = filter.value;
|
|
281
|
+
}
|
|
282
|
+
filters.push({ field: filter.field, searchTerm: value });
|
|
283
|
+
}
|
|
284
|
+
else{
|
|
285
|
+
if (!skipUrlUpdate) {
|
|
286
|
+
if(filter.field === 'title'){
|
|
287
|
+
queryParams.remove(["keyWord" ]);
|
|
288
|
+
}
|
|
289
|
+
if(filter.field === 'department'){
|
|
290
|
+
console.log("removing department from url")
|
|
291
|
+
queryParams.remove(["department" ]);
|
|
292
|
+
}
|
|
293
|
+
if(filter.field === 'cityText'){
|
|
294
|
+
console.log("removing location from url")
|
|
295
|
+
queryParams.remove(["location" ]);
|
|
296
|
+
}
|
|
297
|
+
if(filter.field === 'remote'){
|
|
298
|
+
console.log("removing jobType from url")
|
|
299
|
+
queryParams.remove(["jobType" ]);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
const filter = await getFilter(filters, 'and');
|
|
306
|
+
await _$w('#jobsDataset').setFilter(filter);
|
|
307
|
+
await _$w('#jobsDataset').refresh();
|
|
308
|
+
|
|
309
|
+
const count = await updateCount(_$w);
|
|
310
|
+
console.log("updating map markers");
|
|
311
|
+
await updateMapMarkers(_$w);
|
|
312
|
+
console.log("updating map markers completed");
|
|
313
|
+
count ? _$w('#resultsMultiState').changeState('results') : _$w('#resultsMultiState').changeState('noResults');
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
// Update reset button state
|
|
317
|
+
const hasActiveFilters = filters.length > 0;
|
|
318
|
+
hasActiveFilters? _$w('#resetFiltersButton').enable() : _$w('#resetFiltersButton').disable();
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
async function resetFilters(_$w) {
|
|
324
|
+
_$w('#searchInput, #dropdownDepartment, #dropdownLocation, #dropdownJobType').value = '';
|
|
325
|
+
|
|
326
|
+
await _$w('#jobsDataset').setFilter(wixData.filter());
|
|
327
|
+
await _$w('#jobsDataset').refresh();
|
|
328
|
+
|
|
329
|
+
_$w('#resultsMultiState').changeState('results');
|
|
330
|
+
|
|
331
|
+
_$w('#resetFiltersButton').disable();
|
|
332
|
+
|
|
333
|
+
queryParams.remove(["keyWord", "department","page","location","jobType"]);
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
await updateCount(_$w);
|
|
337
|
+
console.log("reseting map markers");
|
|
338
|
+
await updateMapMarkers(_$w);
|
|
339
|
+
console.log("reseting map markers completed");
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
async function updateCount(_$w) {
|
|
343
|
+
const count = await _$w('#jobsDataset').getTotalCount();
|
|
344
|
+
_$w('#numOfPositionText').text = `Showing ${count} Open Positions`;
|
|
345
|
+
|
|
346
|
+
return count;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
async function handleDepartmentParam(_$w,department) {
|
|
350
|
+
const departmentValue = decodeURIComponent(department);
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
let dropdownOptions = _$w('#dropdownDepartment').options;
|
|
355
|
+
console.log("dropdown options:", dropdownOptions);
|
|
356
|
+
const optionsFromCMS=await wixData.query("AmountOfJobsPerDepartment").find();
|
|
357
|
+
//+1 because of the "All" option
|
|
358
|
+
|
|
359
|
+
if(dropdownOptions.length!==optionsFromCMS.items.length+1){
|
|
360
|
+
fixDropdownOptions('#dropdownDepartment',optionsFromCMS, _$w);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
if (_$w('#dropdownDepartment').options.find(option => option.value === departmentValue))
|
|
364
|
+
{
|
|
365
|
+
console.log("department value found in dropdown options ",departmentValue);
|
|
366
|
+
_$w('#dropdownDepartment').value = departmentValue;
|
|
367
|
+
}
|
|
368
|
+
else{
|
|
369
|
+
console.warn("department value not found in dropdown options");
|
|
370
|
+
queryParams.remove(["department" ]);
|
|
371
|
+
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
function fixDropdownOptions(dropdown,optionsFromCMS, _$w){
|
|
379
|
+
let dropdownOptions = [];
|
|
380
|
+
dropdownOptions=[{
|
|
381
|
+
label: "All",
|
|
382
|
+
value: "RESET_ALL"
|
|
383
|
+
}]
|
|
384
|
+
dropdownOptions.push(...optionsFromCMS.items.map(item=>({
|
|
385
|
+
label: item.title,
|
|
386
|
+
value: item.title
|
|
387
|
+
})));
|
|
388
|
+
_$w(dropdown).options=dropdownOptions;
|
|
389
|
+
console.warn("something is wrong with the dropdown options, fixing it");
|
|
390
|
+
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
async function handleLocationParam(_$w,location) {
|
|
394
|
+
const locationValue = decodeURIComponent(location);
|
|
395
|
+
let dropdownOptions = _$w('#dropdownLocation').options;
|
|
396
|
+
console.log("location dropdown options:", dropdownOptions);
|
|
397
|
+
const optionsFromCMS=await wixData.query("cities").find();
|
|
398
|
+
//+1 because of the "All" option
|
|
399
|
+
if(dropdownOptions.length!==optionsFromCMS.items.length+1){
|
|
400
|
+
fixDropdownOptions('#dropdownLocation',optionsFromCMS, _$w);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
const option=_$w('#dropdownLocation').options.find(option => option.value.toLowerCase() === locationValue.toLowerCase())
|
|
404
|
+
|
|
405
|
+
if(option){
|
|
406
|
+
_$w('#dropdownLocation').value = option.value;
|
|
407
|
+
}
|
|
408
|
+
else{
|
|
409
|
+
console.warn("location value not found in dropdown options");
|
|
410
|
+
queryParams.remove(["location"]);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
async function handleJobTypeParam(_$w,jobType) {
|
|
416
|
+
const jobTypeValue = decodeURIComponent(jobType);
|
|
417
|
+
let dropdownOptions = _$w('#dropdownJobType').options;
|
|
418
|
+
console.log("jobType dropdown options:", dropdownOptions);
|
|
419
|
+
let option;
|
|
420
|
+
if(jobTypeValue.toLowerCase()==="remote"){
|
|
421
|
+
option="true";
|
|
422
|
+
}
|
|
423
|
+
if(jobTypeValue.toLowerCase()==="onsite"){
|
|
424
|
+
option="false";
|
|
425
|
+
}
|
|
426
|
+
if(option){
|
|
427
|
+
_$w('#dropdownJobType').value = option;
|
|
428
|
+
}
|
|
429
|
+
else{
|
|
430
|
+
console.warn("jobType value not found in dropdown options");
|
|
431
|
+
queryParams.remove(["jobType"]);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
async function updateMapMarkers(_$w){
|
|
436
|
+
const numOfItems = await _$w('#jobsDataset').getTotalCount();
|
|
437
|
+
const items = await _$w('#jobsDataset').getItems(0, numOfItems);
|
|
438
|
+
const markers = filterBrokenMarkers(items.items).map(item => {
|
|
439
|
+
const location = item.locationAddress.location;
|
|
440
|
+
return {
|
|
441
|
+
location: {
|
|
442
|
+
latitude: location.latitude,
|
|
443
|
+
longitude: location.longitude
|
|
444
|
+
},
|
|
445
|
+
address: item.locationAddress.formatted,
|
|
446
|
+
title: item.title
|
|
447
|
+
};
|
|
448
|
+
});
|
|
449
|
+
//@ts-ignore
|
|
450
|
+
_$w('#googleMaps').setMarkers(markers);
|
|
451
|
+
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
|
|
455
|
+
module.exports = {
|
|
456
|
+
careersPageOnReady,
|
|
457
|
+
};
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
const {
|
|
2
|
+
debounce,
|
|
3
|
+
getFilter,
|
|
4
|
+
} = require('../public/filterUtils');
|
|
5
|
+
const { handleOnLocationClick } = require('../public/mapUtils');
|
|
6
|
+
const { filterBrokenMarkers } = require('../public/utils');
|
|
7
|
+
const { location } = require('@wix/site-location');
|
|
8
|
+
let thisObjectVar;
|
|
9
|
+
let searchByCityFlag=false;
|
|
10
|
+
async function homePageOnReady(_$w,thisObject) {
|
|
11
|
+
thisObjectVar=thisObject;
|
|
12
|
+
await bind(_$w);
|
|
13
|
+
await init(_$w);
|
|
14
|
+
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function bind(_$w) {
|
|
18
|
+
_$w('#teamRepeater').onItemReady(($item, itemData) => {
|
|
19
|
+
$item('#teamButton').label = `View ${itemData.count} Open Positions`;
|
|
20
|
+
$item('#teamButton').onClick(()=>{
|
|
21
|
+
const department = encodeURIComponent(itemData.title);
|
|
22
|
+
location.to(`/positions?department=${department}`);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
_$w('#citiesDataset').onReady(async () => {
|
|
27
|
+
const numOfItems = await _$w('#citiesDataset').getTotalCount();
|
|
28
|
+
const items = await _$w('#citiesDataset').getItems(0, numOfItems);
|
|
29
|
+
let baseUrl = await location.baseUrl();
|
|
30
|
+
const markers = filterBrokenMarkers(items.items).map(item => {
|
|
31
|
+
const location = item.locationAddress.location;
|
|
32
|
+
const cityName = encodeURIComponent(item.title); // Use the city name from the item
|
|
33
|
+
const cityLinkUrl = `${baseUrl}/positions?location=${cityName}`; // Add city as search parameter
|
|
34
|
+
return {
|
|
35
|
+
location: {
|
|
36
|
+
latitude: location.latitude,
|
|
37
|
+
longitude: location.longitude
|
|
38
|
+
},
|
|
39
|
+
address: item.locationAddress.formatted,
|
|
40
|
+
title: item.title,
|
|
41
|
+
link: cityLinkUrl,
|
|
42
|
+
linkTitle:`View ${item.count} Open Positions`
|
|
43
|
+
};
|
|
44
|
+
});
|
|
45
|
+
//@ts-ignore
|
|
46
|
+
_$w('#googleMaps').setMarkers(markers);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function init(_$w) {
|
|
51
|
+
const debouncedInput = debounce(()=>handleSearchInput(_$w), 400,thisObjectVar);
|
|
52
|
+
|
|
53
|
+
_$w('#searchInput').onInput(debouncedInput);
|
|
54
|
+
_$w('#searchInput').maxLength = 40;
|
|
55
|
+
_$w('#searchButton').onClick(()=>handleSearch(_$w('#searchInput').value));
|
|
56
|
+
|
|
57
|
+
_$w('#searchInput').onKeyPress((event) => {
|
|
58
|
+
if (event.key === 'Enter') {
|
|
59
|
+
handleSearch(_$w('#searchInput').value);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
_$w('#searchInput').onFocus(() => {
|
|
64
|
+
if (_$w(`#resultsContainer`).collapsed) {
|
|
65
|
+
_$w(`#resultsContainer`).expand();
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
_$w('#searchInput').onBlur(() => {
|
|
70
|
+
setTimeout(() => {
|
|
71
|
+
if (!_$w(`#resultsContainer`).collapsed) {
|
|
72
|
+
_$w(`#resultsContainer`).collapse();
|
|
73
|
+
}
|
|
74
|
+
}, 250);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
_$w('#locationItem').onClick((event)=>{
|
|
78
|
+
handleOnLocationClick(event, '#locationsRepeater', '#googleMaps', _$w);
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async function handleSearchInput(_$w) {
|
|
83
|
+
let searchInput;
|
|
84
|
+
let count;
|
|
85
|
+
|
|
86
|
+
searchInput = _$w('#searchInput').value;
|
|
87
|
+
const trimmedInput = searchInput.trim();
|
|
88
|
+
const searchByTitle=[{field: 'title', searchTerm: trimmedInput}];
|
|
89
|
+
const searchByCity=[{field: 'cityText', searchTerm: trimmedInput}];
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
let filter = await getFilter(searchByTitle);
|
|
93
|
+
|
|
94
|
+
await _$w('#jobsDataset').setFilter(filter);
|
|
95
|
+
await _$w('#jobsDataset').refresh();
|
|
96
|
+
|
|
97
|
+
count = _$w('#jobsDataset').getTotalCount();
|
|
98
|
+
|
|
99
|
+
if (count > 0) {
|
|
100
|
+
searchByCityFlag=false;
|
|
101
|
+
_$w('#resultsContainer').expand();
|
|
102
|
+
_$w('#searchMultiStateBox').changeState('results');
|
|
103
|
+
} else {
|
|
104
|
+
filter=await getFilter(searchByCity);
|
|
105
|
+
await _$w('#jobsDataset').setFilter(filter);
|
|
106
|
+
await _$w('#jobsDataset').refresh();
|
|
107
|
+
count = _$w('#jobsDataset').getTotalCount();
|
|
108
|
+
if(count > 0)
|
|
109
|
+
{
|
|
110
|
+
searchByCityFlag=true;
|
|
111
|
+
_$w('#resultsContainer').expand();
|
|
112
|
+
_$w('#searchMultiStateBox').changeState('results');
|
|
113
|
+
}
|
|
114
|
+
else{
|
|
115
|
+
searchByCityFlag=false;
|
|
116
|
+
_$w('#searchMultiStateBox').changeState('noResults');
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function handleSearch(searchInput) {
|
|
122
|
+
const trimmedInput = searchInput.trim();
|
|
123
|
+
if (trimmedInput) {
|
|
124
|
+
if(searchByCityFlag){
|
|
125
|
+
location.to(`/positions?location=${trimmedInput}`);
|
|
126
|
+
}
|
|
127
|
+
else{
|
|
128
|
+
location.to(`/positions?keyWord=${trimmedInput}`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
module.exports = {
|
|
135
|
+
homePageOnReady,
|
|
136
|
+
};
|
package/pages/index.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
const {
|
|
2
|
+
htmlToText
|
|
3
|
+
} = require('../public/utils');
|
|
4
|
+
|
|
5
|
+
async function positionPageOnReady(_$w) {
|
|
6
|
+
|
|
7
|
+
await bind(_$w);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
async function bind(_$w) {
|
|
11
|
+
_$w('#datasetJobsItem').onReady(async () => {
|
|
12
|
+
|
|
13
|
+
const item = await _$w('#datasetJobsItem').getCurrentItem();
|
|
14
|
+
|
|
15
|
+
_$w('#companyDescriptionText').text = htmlToText(item.jobDescription.companyDescription.text);
|
|
16
|
+
_$w('#responsibilitiesText').text = htmlToText(item.jobDescription.jobDescription.text);
|
|
17
|
+
_$w('#qualificationsText').text = htmlToText(item.jobDescription.qualifications.text);
|
|
18
|
+
_$w('#relatedJobsTitleText').text = `More ${item.department} Positions`;
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
_$w('#relatedJobsDataset').onReady(() => {
|
|
22
|
+
const count = _$w('#relatedJobsDataset').getTotalCount();
|
|
23
|
+
if(!count){
|
|
24
|
+
_$w('#relatedJobsSection').collapse();
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
module.exports = {
|
|
32
|
+
positionPageOnReady,
|
|
33
|
+
};
|
|
34
|
+
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
//const { items:wixData } = require('@wix/data');
|
|
2
|
+
const {wixData} = require('wix-data');
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
function getFilter(fieldsToSearch = [], mode = 'or') {
|
|
6
|
+
const baseFilter = wixData.filter();
|
|
7
|
+
// if no fields to search, return empty filter
|
|
8
|
+
if (fieldsToSearch.length === 0) {
|
|
9
|
+
return baseFilter;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// build filters
|
|
13
|
+
let filter;
|
|
14
|
+
fieldsToSearch.forEach(({ field, searchTerm }) => {
|
|
15
|
+
const condition = typeof searchTerm === 'boolean'
|
|
16
|
+
? baseFilter.eq(field, searchTerm)
|
|
17
|
+
: baseFilter.contains(field, searchTerm);
|
|
18
|
+
|
|
19
|
+
filter = filter
|
|
20
|
+
? (mode === 'or' ? filter.or(condition) : filter.and(condition))
|
|
21
|
+
: condition;
|
|
22
|
+
});
|
|
23
|
+
return filter;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function debounce(fn, delay = 400,thisObject) {
|
|
27
|
+
let timeout;
|
|
28
|
+
return function (...args) {
|
|
29
|
+
clearTimeout(timeout);
|
|
30
|
+
console.log("thisObject is: ", thisObject);
|
|
31
|
+
console.log("args is: ", args);
|
|
32
|
+
timeout = setTimeout(() => fn.apply(thisObject, args), delay);
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
module.exports = {
|
|
37
|
+
getFilter,
|
|
38
|
+
debounce
|
|
39
|
+
};
|
package/public/index.js
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
function handleOnLocationClick(event, repeaterId, mapId, _$w) {
|
|
2
|
+
const FOCUS_ZOOM = 13;
|
|
3
|
+
const { itemId } = event.context;
|
|
4
|
+
const itemData = _$w(repeaterId).data.find(item => item._id === itemId);
|
|
5
|
+
|
|
6
|
+
const location = itemData.locationAddress.location;
|
|
7
|
+
|
|
8
|
+
//@ts-ignore
|
|
9
|
+
_$w(mapId).setCenter(location);
|
|
10
|
+
//@ts-ignore
|
|
11
|
+
_$w(mapId).setZoom(FOCUS_ZOOM);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
module.exports = {
|
|
15
|
+
handleOnLocationClick
|
|
16
|
+
};
|