@@ -8,48 +8,50 @@ import Toast from "../components/toast/toast.astro";
8
8
import " ../styles/main.css" ;
9
9
import categories from " ../data/profileCategories.json" ;
10
10
11
- let categoriesList = [];
11
+ interface Category {
12
+ key: string ;
13
+ text: string ;
14
+ }
15
+
16
+ let categoriesList: Category [] = [];
12
17
for (const key in categories ) {
13
- categories [key ].key = key ;
14
- categoriesList .push (categories [key ]);
18
+ categoriesList .push ({ key: key , text: categories [key ].text });
15
19
}
16
20
---
17
21
18
22
<BaseLayout
19
23
title =" Publicar Nuevo Empleo | CuCoders"
20
24
description =" Atrae al mejor talento de la tecnología con nuestras ofertas de empleo en CuCoders. Publica una nueva oferta y encuentra al candidato perfecto para tu empresa. ¡Descubre cómo puedes conectarte con la comunidad de programadores de Cuba y atraer al mejor talento hoy mismo en CuCoders!"
21
25
>
22
-
23
-
24
- <div class =" lg:max-w-[58rem] mx-auto w-full md:mt-12" >
25
- <div
26
- id =" newJobsAlert"
27
- class =" flex p-4 hidden mt-5 md:mt-0 text-sm mb-6 text-blue-800 border border-blue-300 rounded-lg bg-blue-50 dark:bg-gray-800 dark:text-blue-400 dark:border-blue-800"
28
- role =" alert"
29
- >
30
- <svg
31
- aria-hidden =" true"
32
- class =" flex-shrink-0 inline w-5 h-5 mr-3"
33
- fill =" currentColor"
34
- viewBox =" 0 0 20 20"
35
- xmlns =" http://www.w3.org/2000/svg"
36
- ><path
37
- fill-rule =" evenodd"
38
- d =" M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z"
39
- clip-rule =" evenodd" ></path ></svg
26
+ <div class =" lg:max-w-[58rem] mx-auto w-full md:mt-12" >
27
+ <div
28
+ id =" newJobsAlert"
29
+ class =" flex p-4 hidden mt-5 md:mt-0 text-sm mb-6 text-blue-800 border border-blue-300 rounded-lg bg-blue-50 dark:bg-gray-800 dark:text-blue-400 dark:border-blue-800"
30
+ role =" alert"
40
31
>
41
- <span class =" sr-only" >Info</span >
42
- <div >
32
+ <svg
33
+ aria-hidden =" true"
34
+ class =" flex-shrink-0 inline w-5 h-5 mr-3"
35
+ fill =" currentColor"
36
+ viewBox =" 0 0 20 20"
37
+ xmlns =" http://www.w3.org/2000/svg"
38
+ ><path
39
+ fill-rule =" evenodd"
40
+ d =" M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z"
41
+ clip-rule =" evenodd" ></path ></svg
42
+ >
43
+ <span class =" sr-only" >Info</span >
44
+ <div >
43
45
<span class =" font-medium" >Antes de publicar su anuncio, asegúrese de respetar las siguientes normas.</span >
44
- <ul class =" mt-1.5 ml-4 list-disc list-inside" >
45
- <li >Solo publicar ofertas de trabajo.</li >
46
- <li >No publicar candidaturas (Que estas buscando trabajo).</li >
47
- <li >No promocionar Servicios.</li >
48
- <li >No repetir el mismo anuncio en el plazo de un mes.</li >
49
- <li >No publicar ofertas de trabajos engañosas o inmorales.</li >
46
+ <ul class =" mt-1.5 ml-4 list-disc list-inside" >
47
+ <li >Solo publicar ofertas de trabajo.</li >
48
+ <li >No publicar candidaturas (Que estas buscando trabajo).</li >
49
+ <li >No promocionar Servicios.</li >
50
+ <li >No repetir el mismo anuncio en el plazo de un mes.</li >
51
+ <li >No publicar ofertas de trabajos engañosas o inmorales.</li >
50
52
</ul >
51
53
</div >
52
- <!-- <button
54
+ <!-- <button
53
55
type="button"
54
56
class="ml-auto -mx-1.5 -my-1.5 bg-blue-50 text-blue-500 rounded-lg focus:ring-2 focus:ring-blue-400 p-1.5 hover:bg-blue-200 inline-flex h-8 w-8 dark:bg-gray-800 dark:text-blue-300 dark:hover:bg-gray-700"
55
57
data-dismiss-target="#newJobsAlert"
@@ -64,9 +66,8 @@ for (const key in categories) {
64
66
clip-rule="evenodd"></path></svg
65
67
>
66
68
</button> -->
69
+ </div >
67
70
</div >
68
- </div >
69
-
70
71
71
72
<form
72
73
id =" job-form"
@@ -100,7 +101,7 @@ for (const key in categories) {
100
101
<div class =" mb-6" >
101
102
<label for =" message" class =" block mb-2 text-sm font-medium text-gray-900 dark:text-white" >Categorías *</label >
102
103
<!-- styles for this element are defined in styles/main.css-->
103
- <select id =" categories" name =" state[]" multiple placeholder = " Categorías " autocomplete =" off" >
104
+ <select id =" categories" name =" state[]" multiple autocomplete =" off" >
104
105
<option value =" " >Select a state...</option >
105
106
{ categoriesList .map ((category ) => <option value = { category .key } >{ category .text } </option >)}
106
107
</select >
@@ -171,12 +172,27 @@ for (const key in categories) {
171
172
import dayjs from "dayjs";
172
173
import { showToast } from "../components/toast/toast";
173
174
175
+ const blacklist = ["
[email protected] ", "karma"];
176
+
174
177
const jobForm = document.getElementById("job-form");
175
- jobForm.addEventListener("submit", addJob, true) ;
178
+ const addJobBtn = document.getElementById("addJobBtn") as HTMLButtonElement ;
176
179
177
- async function addJob(e) {
180
+ if (jobForm) {
181
+ jobForm.addEventListener("submit", addJob, true);
182
+ }
183
+
184
+ async function addJob(e: Event) {
178
185
e.preventDefault();
179
186
const data = createJobData();
187
+
188
+ if (isBlacklisted(data)) {
189
+ showToast(
190
+ "Su contacto está en la lista negra por haber incumplido anteriormente las normas para publicar un anuncio. Si cree que esto es un error, por favor contáctenos.",
191
+ true
192
+ );
193
+ return;
194
+ }
195
+
180
196
disableBtn();
181
197
try {
182
198
const response = await fetch(backend_url + "api/jobs/new-job", { method: "POST", body: JSON.stringify(data) });
@@ -188,12 +204,47 @@ for (const key in categories) {
188
204
}
189
205
}
190
206
191
- function getElem(id) {
192
- return <HTMLInputElement>document.getElementById(id);
207
+ function isBlacklisted(data: any) {
208
+ const contactFields = [
209
+ data.applyEmail.toLowerCase(),
210
+ data.applyTelegramUser.toLowerCase(),
211
+ data.applyPhone.toLowerCase(),
212
+ ];
213
+
214
+ for (const field of contactFields) {
215
+ if (field && blacklist.includes(field.toLowerCase())) {
216
+ return true;
217
+ }
218
+ }
219
+ return false;
220
+ }
221
+
222
+ function getElem(id: string): HTMLInputElement {
223
+ return document.getElementById(id) as HTMLInputElement;
193
224
}
194
225
195
226
function createJobData() {
196
- let data = {
227
+ let data: {
228
+ title: string;
229
+ salary: string;
230
+ description: string;
231
+ categories: string[];
232
+ freelance: boolean;
233
+ fulltime: boolean;
234
+ parttime: boolean;
235
+ remote: boolean;
236
+ presential: boolean;
237
+ relocate: boolean;
238
+ location: string;
239
+ pubDate: string;
240
+ applyEmail: string;
241
+ applyUrl: string;
242
+ applyTelegramUser: string;
243
+ applyPhone: string;
244
+ organization: string;
245
+ organizationWebsite: string;
246
+ slug: string;
247
+ } = {
197
248
title: getElem("title").value,
198
249
salary: getElem("salary").value,
199
250
description: getElem("description").value,
@@ -215,21 +266,28 @@ for (const key in categories) {
215
266
slug: getElem("title").value.replace(/[^a-zA-Z0-9]+/g, "-"),
216
267
};
217
268
218
- for (let option of document.getElementById("categories").options) {
219
- if (option.selected) {
220
- data.categories.push(option.value);
269
+ const categoriesSelect = document.getElementById("categories") as HTMLSelectElement;
270
+ if (categoriesSelect) {
271
+ for (let option of categoriesSelect.options) {
272
+ if (option.selected) {
273
+ data.categories.push(option.value);
274
+ }
221
275
}
222
276
}
223
277
return data;
224
278
}
225
279
226
280
function disableBtn() {
227
- addJobBtn.disabled = true;
228
- addJobBtn.textContent = "Publicando...";
281
+ if (addJobBtn) {
282
+ addJobBtn.disabled = true;
283
+ addJobBtn.textContent = "Publicando...";
284
+ }
229
285
}
230
286
231
287
function enableBtn() {
232
- addJobBtn.disabled = false;
233
- addJobBtn.textContent = "Publicar Empleo";
288
+ if (addJobBtn) {
289
+ addJobBtn.disabled = false;
290
+ addJobBtn.textContent = "Publicar Empleo";
291
+ }
234
292
}
235
293
</script >
0 commit comments