+
-
+
} />
} />
- } />
+ } />
} />
- } />
- } />
+ } />
+ } />
+ {/* } /> */}
{/* Add more routes as needed */}
+
diff --git a/src/components/AddJobListing.jsx b/src/components/AddJobListing.jsx
index e7966f7..25ce10c 100644
--- a/src/components/AddJobListing.jsx
+++ b/src/components/AddJobListing.jsx
@@ -1,4 +1,4 @@
-import React, { useState, useEffect } from 'react'
+import { useState, useEffect } from 'react'
import StepOneJoblisting from './StepOneJoblisting';
import StepTwoJoblisting from './StepTwoJoblisting';
import StepThreeJoblisting from './StepThreeJoblisting';
diff --git a/src/components/Category.jsx b/src/components/Category.jsx
index 0d00e66..6c1d314 100644
--- a/src/components/Category.jsx
+++ b/src/components/Category.jsx
@@ -1,4 +1,4 @@
-import React from 'react'
+import propTypes from 'prop-types'
const Category = (props) => {
return (
@@ -15,4 +15,11 @@ const Category = (props) => {
)
}
+Category.propTypes = {
+ name: propTypes.string,
+ func: propTypes.func,
+ small: propTypes.bool,
+ last: propTypes.bool
+}
+
export default Category
diff --git a/src/components/CategorySelect.jsx b/src/components/CategorySelect.jsx
new file mode 100644
index 0000000..886f1d3
--- /dev/null
+++ b/src/components/CategorySelect.jsx
@@ -0,0 +1,106 @@
+import { useEffect, useState } from 'react';
+import PropTypes from 'prop-types';
+import { categories } from '../consts';
+import { search } from '../assets';
+
+const CategorySelect = props => {
+ const [inputValue, setInputValue] = useState('');
+ const [suggestions, setSuggestions] = useState([]);
+ const [selectedCategoryIds, setSelectedCategoryIds] = useState([]);
+
+ useEffect(() => {
+ console.log(suggestions);
+ console.log(selectedCategoryIds);
+ }, [suggestions, selectedCategoryIds]);
+
+ useEffect(() => {
+ if (props.searchQuery && props.searchQuery.categories) {
+ setSelectedCategoryIds(props.searchQuery.categories);
+ }
+ }, [props.searchQuery]);
+
+ // useEffect(() =>{
+ // setSelectedCategoryIds([])
+ // }, [props.clearSearchQuery])
+
+ const handleInputChange = (e) => {
+ const value = e.target.value;
+ setInputValue(value);
+ if (value.length > 0) {
+ setSuggestions(categories.filter(category =>
+ category.name.toLowerCase().includes(value.toLowerCase()) &&
+ !selectedCategoryIds.includes(category.id)
+ ));
+ } else {
+ setSuggestions([]);
+ }
+ }
+
+ const handleSuggestionClick = (suggestion) => {
+ if (!selectedCategoryIds.includes(suggestion.id)) {
+ const newSelectedIds = [...selectedCategoryIds, suggestion.id];
+ setSelectedCategoryIds(newSelectedIds);
+ props.setSearchQuery(prevState => ({...prevState, categories: newSelectedIds }));
+ }
+ setInputValue('');
+ setSuggestions([]);
+ }
+
+ const handleRemoveCategory = (id) => {
+ const newSelectedIds = selectedCategoryIds.filter(prevId => prevId !== id);
+ setSelectedCategoryIds(newSelectedIds);
+ props.setSearchQuery({ categories: newSelectedIds });
+ }
+
+ return (
+
+
Kategorie
+
+ {selectedCategoryIds.map(id => {
+ const category = categories.find(cat => cat.id === id);
+ return (
+
handleRemoveCategory(id)}
+ className='min-w-fit w-8 py-1 px-2 mr-3 border-2 hover:bg-gray-300 rounded-xl hover:cursor-pointer '
+ >
+
{category.name}
+ ×
+
+
+ );
+ })}
+
+
+ {inputValue.length >= 1 && suggestions.length > 0 && (
+
+ {suggestions.map(suggestion => (
+
handleSuggestionClick(suggestion)}
+ >
+ {suggestion.name}
+
+ ))}
+
+ )}
+
+ )
+}
+
+CategorySelect.propTypes = {
+ setSearchQuery: PropTypes.func.isRequired,
+ searchQuery: PropTypes.shape({
+ categories: PropTypes.arrayOf(PropTypes.string)
+ })
+
+}
+
+export default CategorySelect
\ No newline at end of file
diff --git a/src/components/Cookies.jsx b/src/components/Cookies.jsx
new file mode 100644
index 0000000..ddcdc57
--- /dev/null
+++ b/src/components/Cookies.jsx
@@ -0,0 +1,29 @@
+import propTypes from 'prop-types'
+import { useState } from 'react'
+const Cookies = props => {
+ const handleCookies = () => {
+ localStorage.setItem('cookies', true)
+ }
+ const cookies = localStorage.getItem('cookies')
+ // if(cookies) return null
+ const [show, setShow] = useState(true)
+ if (cookies) return null;
+ if (!show) return null;
+ return (
+ <>
+
+
Korzystamy z plików cookie, aby zapewnić prawidłowe działanie witryny.
+
+
+
+ >
+ )
+}
+
+Cookies.propTypes = {
+
+}
+
+export default Cookies
\ No newline at end of file
diff --git a/src/components/EmployerPanel.jsx b/src/components/EmployerPanel.jsx
index 29c2569..2eb63d1 100644
--- a/src/components/EmployerPanel.jsx
+++ b/src/components/EmployerPanel.jsx
@@ -1,4 +1,4 @@
-import React from "react";
+
import { ogloszenia } from "../consts";
import ListingSmall from "./ListingSmall";
import { useState } from "react";
diff --git a/src/components/Filter.jsx b/src/components/Filter.jsx
index 06ecb69..33fc1dd 100644
--- a/src/components/Filter.jsx
+++ b/src/components/Filter.jsx
@@ -1,30 +1,185 @@
-import React from 'react'
-import Search from './Search'
+import { useCallback, useEffect, useMemo } from 'react';
+import PropTypes from 'prop-types';
+import Search from './Search';
+import Selector from './Selector';
+import RangeSlider from './RangeSlider';
+import CategorySelect from './CategorySelect';
+import { categories, work_from_home, employment_types } from '../consts';
+
+const Filter = ({ isOpen, searchQuery, setSearchQuery, clearSearchQuery, onClick }) => {
+ const [min_salary, max_salary] = [0, 100000];
+
+ useEffect(() => {
+ console.log(searchQuery);
+ }, [searchQuery]);
-const Filter = (props) => {
- if (!props.isOpen) return null;
+ const handleRangeChange = useCallback((newMin, newMax) => {
+ setSearchQuery(prevState => ({
+ ...prevState,
+ min_salary: newMin,
+ max_salary: newMax
+ }));
+ }, [setSearchQuery]);
+
+ const handleChange = useCallback((e, name) => {
+ const value = e.target.value;
+ const numValue = parseInt(value, 10);
+
+ setSearchQuery(prevState => {
+ switch (name) {
+ case 'name':
+ return { ...prevState, name: value };
+ case 'min_salary':
+ if (value === '' || isNaN(numValue)) {
+ return { ...prevState, min_salary: '' };
+ }
+ return { ...prevState, min_salary: numValue };
+ case 'max_salary':
+ if (value === '' || isNaN(numValue)) {
+ return { ...prevState, max_salary: '' };
+ }
+ return { ...prevState, max_salary: numValue };
+ default:
+ return prevState;
+ }
+ });
+ }, [setSearchQuery]);
+
+ const handleCheckedChange = useCallback((e) => {
+ const { name, value, checked } = e.target;
+ setSearchQuery(prevState => {
+ // Sprawdź, czy dla danej nazwy już istnieje tablica w stanie
+ if (!prevState[name]) {
+ prevState[name] = [];
+ }
+
+ if (checked) {
+ // Jeśli checkbox jest zaznaczony, dodaj wartość do odpowiedniej tablicy
+ return {
+ ...prevState,
+ [name]: [...prevState[name], value]
+ };
+ } else {
+ // Jeśli checkbox jest odznaczony, usuń wartość z odpowiedniej tablicy
+ return {
+ ...prevState,
+ [name]: prevState[name].filter(item => item !== value)
+ };
+ }
+ });
+ }, [setSearchQuery]);
+
+ const filterButtonClass = useMemo(() => (
+ 'bg-gray-600 text-white py-1 sm:py-3 px-12 mx-auto sm:mx-40 col-span-2 rounded-md font-semibold ' +
+ 'text-xl hover:bg-gray-500 duration-300 hover:scale-110 my-3 sm:my-5 sm:min-h-full'
+ ), []);
+
return (
-
-
-
-
-
+
+
+
+
Filtry
+
+
+
+
handleChange(e, 'name')}
+ />
-
+
+ handleChange(e, 'min_salary')}
+ />
+ handleChange(e, 'max_salary')}
+ />
+
+
+
+ {/* */}
+ {/*
+ */}
+
+
- )
-}
+ );
+};
-export default Filter
+Filter.propTypes = {
+ isOpen: PropTypes.bool.isRequired,
+ searchQuery: PropTypes.shape({
+ name: PropTypes.string,
+ min_salary: PropTypes.number,
+ max_salary: PropTypes.number,
+ categories: PropTypes.arrayOf(PropTypes.string),
+ work_from_home: PropTypes.arrayOf(PropTypes.string),
+ employment_types: PropTypes.arrayOf(PropTypes.string)
+ }),
+ setSearchQuery: PropTypes.func.isRequired,
+ clearSearchQuery: PropTypes.func.isRequired,
+ onClick: PropTypes.func.isRequired
+};
+
+Filter.defaultProps = {
+ searchQuery: {
+ categories: [],
+ work_from_home: [],
+ employment_types: []
+ }
+};
+
+export default Filter;
\ No newline at end of file
diff --git a/src/components/Home.jsx b/src/components/Home.jsx
index e633d2f..53a2fc7 100644
--- a/src/components/Home.jsx
+++ b/src/components/Home.jsx
@@ -1,4 +1,4 @@
-import React from 'react'
+
import styles from '../style'
const Home = () => {
return (
diff --git a/src/components/ImageUpload.jsx b/src/components/ImageUpload.jsx
index 0a7643c..f4612e9 100644
--- a/src/components/ImageUpload.jsx
+++ b/src/components/ImageUpload.jsx
@@ -1,7 +1,7 @@
-import React, { useState, useRef, useEffect } from 'react';
+import { useState, useRef, useEffect } from 'react';
import { placeholderImage } from '../assets';
import axios from 'axios';
-
+import propTypes from 'prop-types';
const ImageUpload = ({setFormData, data}) => {
const [imageSrc, setImageSrc] = useState(placeholderImage);
@@ -83,4 +83,9 @@ const ImageUpload = ({setFormData, data}) => {
);
};
+ImageUpload.propTypes = {
+ setFormData: propTypes.func,
+ data: propTypes.object
+};
+
export default ImageUpload;
diff --git a/src/components/JobOfferContent.jsx b/src/components/JobOfferContent.jsx
index 5eb5983..2cbdd58 100644
--- a/src/components/JobOfferContent.jsx
+++ b/src/components/JobOfferContent.jsx
@@ -1,14 +1,15 @@
import { useEffect, useState } from 'react';
import axios from 'axios';
import DOMPurify from 'dompurify';
-import SkillRender from './SkillRender'; // Ensure this import is correctly pointing to your SkillRender component
+import SkillRender from './SkillRender';
+// eslint-disable-next-line react/prop-types
const JobOfferContent = ({ id, skills }) => {
const [jobOffer, setJobOffer] = useState(null);
const fetchJobOfferById = async (jobId) => {
try {
- const response = await axios.get(`https://izaac.knck.pl/api/jobposting/joboffers/${jobId}`);
+ const response = await axios.get(`https://izaac.knck.pl/api/jobposting/joboffers/${jobId}/?format=json`);
setJobOffer(response.data);
} catch (error) {
console.error('Failed to fetch job offer:', error);
diff --git a/src/components/ListingSmall.jsx b/src/components/ListingSmall.jsx
index d41da5e..2e0f147 100644
--- a/src/components/ListingSmall.jsx
+++ b/src/components/ListingSmall.jsx
@@ -1,11 +1,12 @@
-import React from 'react'
-import { IzaacLOGO } from '../assets'
-const ListingSmall = ({ id, name, company_name, min_salary, max_salary, require_salary, index, onClick, _class, image }) => {
+import { IzaacLOGO } from '../assets'
+import propTypes from 'prop-types'
+
+const ListingSmall = ({ id, name, company_name, min_salary, max_salary, require_salary, index, onClick, _class, image, selected, blur }) => {
return (
@@ -14,7 +15,7 @@ const ListingSmall = ({ id, name, company_name, min_salary, max_salary, require_
{name}
-
{company_name}
+
{company_name}
{/* Wyświetlenie wynagrodzenia pod nazwą, jeśli jest wymagane */}
{require_salary && (
{min_salary} - {max_salary} PLN
@@ -24,4 +25,19 @@ const ListingSmall = ({ id, name, company_name, min_salary, max_salary, require_
);
};
-export default ListingSmall;
\ No newline at end of file
+export default ListingSmall;
+
+ListingSmall.propTypes = {
+ id: propTypes.number,
+ name: propTypes.string,
+ company_name: propTypes.string,
+ min_salary: propTypes.number,
+ max_salary: propTypes.number,
+ require_salary: propTypes.bool,
+ index: propTypes.number,
+ onClick: propTypes.func,
+ _class: propTypes.string,
+ image: propTypes.string,
+ selected: propTypes.bool,
+ blur: propTypes.string
+}
\ No newline at end of file
diff --git a/src/components/Login.jsx b/src/components/Login.jsx
index 8f0a335..c19e092 100644
--- a/src/components/Login.jsx
+++ b/src/components/Login.jsx
@@ -1,4 +1,4 @@
-import React from 'react'
+import propTypes from 'prop-types';
import styles from '../style';
const Login = ({isOpen, onClose}) => {
@@ -31,4 +31,9 @@ const Login = ({isOpen, onClose}) => {
)
}
+Login.propTypes = {
+ isOpen: propTypes.bool,
+ onClose: propTypes.func
+}
+
export default Login
diff --git a/src/components/Mininav.jsx b/src/components/Mininav.jsx
index c5d5593..5ae1c5e 100644
--- a/src/components/Mininav.jsx
+++ b/src/components/Mininav.jsx
@@ -1,8 +1,7 @@
-import React, { useState } from 'react'
+import { useState } from 'react'
import Register from './Register';
import Login from './Login';
-import { BrowserRouter as Router } from "react-router-dom";
-import { Route, Routes } from "react-router-dom";
+
const Mininav = () => {
const [isPopupOpen, setPopupOpen] = useState(false)
@@ -17,7 +16,7 @@ const Mininav = () => {
<>
{/* Link otwierający modal */}
-
Panel pracodawcy
+ {/*
Panel pracodawcy */}
diff --git a/src/components/NavBar.jsx b/src/components/NavBar.jsx
index 9d94ae7..3138b2d 100644
--- a/src/components/NavBar.jsx
+++ b/src/components/NavBar.jsx
@@ -1,10 +1,10 @@
-import React from 'react'
import { linki, linki_home } from '../consts';
import { close, search, menu, IzaacLOGO} from '../assets';
import { useState } from 'react';
import { useLocation } from 'react-router-dom';
import { Link } from 'react-router-dom';
import Mininav from './Mininav';
+
const NavBar = () => {
const[toggle, setToggle] = useState(false)
const[toggleSearch, setToggleSearch] = useState(false)
@@ -20,10 +20,10 @@ const NavBar = () => {
const currentLinks = getLinks()
return (
-
)
}
-
+Register.propTypes = {
+ isOpen: propTypes.bool,
+ onClose: propTypes.func
+}
export default Register
diff --git a/src/components/Salary.jsx b/src/components/Salary.jsx
index 762ea0f..fe016c9 100644
--- a/src/components/Salary.jsx
+++ b/src/components/Salary.jsx
@@ -1,5 +1,5 @@
-import React, { useState, useEffect } from 'react'
-import styles from '../style'
+import { useState, useEffect } from 'react'
+import propTypes from 'prop-types'
import {employment_types, work_from_home } from '../consts'
@@ -82,7 +82,7 @@ const Salary = ({handleChange, formData, removeFields, setFormData}) => {
className={`h-12 border-2 rounded-xl px-5 mx-4 w-full ${!require_salary ? 'bg-slate-200' : ''} `}/>
-
Typ kontraktu
+
Typ
kontraktu
-
Praca zdalna
+
Praca
zdalna
)
}
+Salary.propTypes = {
+ handleChange: propTypes.func,
+ formData: propTypes.object,
+ removeFields: propTypes.func,
+ setFormData: propTypes.func,
+ min_salary: propTypes.string,
+ max_salary: propTypes.string,
+ require_salary: propTypes.bool,
+ employment_type: propTypes.string,
+ work_from_home: propTypes.string
+
+}
export default Salary
+
diff --git a/src/components/Search.jsx b/src/components/Search.jsx
index 15cae22..a0ff788 100644
--- a/src/components/Search.jsx
+++ b/src/components/Search.jsx
@@ -1,19 +1,62 @@
-import React from 'react'
+
+import { useEffect, useState } from 'react'
+import propTypes from 'prop-types'
const Search = (props) => {
- return (
-
-
);
};
+SkillsList.propTypes = {
+ skillData: propTypes.array,
+ skill_names: propTypes.array,
+};
export default SkillsList;
diff --git a/src/components/SkillRender.jsx b/src/components/SkillRender.jsx
index 384c9f3..df6dcd7 100644
--- a/src/components/SkillRender.jsx
+++ b/src/components/SkillRender.jsx
@@ -1,5 +1,4 @@
-import React from 'react'
-
+import propTypes from 'prop-types';
const levelMappings = {
'N': 'Nice to have',
@@ -31,7 +30,7 @@ const SkillRender = ({key, skill, level,}) => {
return (
-
+
{skill}
@@ -42,4 +41,10 @@ const SkillRender = ({key, skill, level,}) => {
)
};
+SkillRender.propTypes = {
+ key: propTypes.number,
+ skill: propTypes.string,
+ level: propTypes.string,
+};
+
export default SkillRender;
\ No newline at end of file
diff --git a/src/components/SkillsSelector.jsx b/src/components/SkillsSelector.jsx
index ce91a39..cbcbe9b 100644
--- a/src/components/SkillsSelector.jsx
+++ b/src/components/SkillsSelector.jsx
@@ -1,6 +1,6 @@
-import React, { useState, useEffect } from 'react';
+import { useState, useEffect } from 'react';
+import propTypes from 'prop-types';
import SelectedSkill from './SelectedSkill';
-import axios from 'axios';
const SkillsSelector = ({ formData, setFormData, skills }) => {
const [inputValue, setInputValue] = useState('');
@@ -101,4 +101,10 @@ const SkillsSelector = ({ formData, setFormData, skills }) => {
);
};
+SkillsSelector.propTypes = {
+ formData: propTypes.object.isRequired,
+ setFormData: propTypes.func.isRequired,
+ skills: propTypes.array.isRequired
+};
+
export default SkillsSelector;
diff --git a/src/components/StepFourJoblisting.jsx b/src/components/StepFourJoblisting.jsx
index c0a12e4..3980a4d 100644
--- a/src/components/StepFourJoblisting.jsx
+++ b/src/components/StepFourJoblisting.jsx
@@ -1,13 +1,16 @@
-import React from "react";
+import propTypes from "prop-types";
+
import styles from "../style";
import TextDivider from "./TextDivider";
+
+
const StepFourJoblisting = ({ handleChange, formData, nextStep, prevStep }) => {
return (
-
+
Imię
@@ -21,8 +24,9 @@ const StepFourJoblisting = ({ handleChange, formData, nextStep, prevStep }) => {
id="first_name"
onChange={handleChange("first_name")}
placeholder="Twoje imię..."
- className={`border-b-2 px-4 my-2 ${styles.paragraph}`}
+ className={`px-4 mt-2 ${styles.paragraph}`}
/>
+
@@ -37,8 +41,9 @@ const StepFourJoblisting = ({ handleChange, formData, nextStep, prevStep }) => {
id="last_name"
onChange={handleChange("last_name")}
placeholder="Twoje nazwisko..."
- className={`border-b-2 px-4 my-2 ${styles.paragraph}`}
+ className={`px-4 mt-2 ${styles.paragraph}`}
/>
+
@@ -53,15 +58,15 @@ const StepFourJoblisting = ({ handleChange, formData, nextStep, prevStep }) => {
id="contact_email"
onChange={handleChange("contact_email")}
placeholder="Adres mailowy..."
- className={`border-b-2 px-4 my-2 ${styles.paragraph}`}
+ className={`px-4 mt-2 ${styles.paragraph}`}
/>
+
-
+
Nazwa firmy
*
-
{
onChange={handleChange("company_name")}
id="company_name"
placeholder="Wpisz nazwę firmy..."
- className={`border-b-2 px-4 mr-12 my-2 ${styles.paragraph} col-span-2 `}
+ className={`px-4 mt-2 ${styles.paragraph}`}
/>
-
+
@@ -88,23 +93,24 @@ const StepFourJoblisting = ({ handleChange, formData, nextStep, prevStep }) => {
onChange={handleChange("vat_number")}
id="vat_number"
placeholder="Wpisz nip..."
- className={`border-b-2 px-4 my-2 ${styles.paragraph} `}
- />
+ className={`px-4 mt-2 ${styles.paragraph}`}
+ />
+