diff --git a/index.html b/index.html index b7a44d1..586bd2f 100644 --- a/index.html +++ b/index.html @@ -7,7 +7,7 @@ - izaac frontend + Izaac - praca dla inżynierów
diff --git a/src/App.jsx b/src/App.jsx index 9905387..1be36b2 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -7,38 +7,29 @@ import { Route, Routes } from "react-router-dom"; import Contact from "./components/Contact"; import Mininav from "./components/Mininav"; import AddJobListing from "./components/AddJobListing"; -import { useState, useEffect } from "react"; -import axios from "axios"; -import EmployerPanel from "./components/EmployerPanel"; function App() { - const loc = () => { - if (location.pathname.startsWith("work/jobposting")) { - return ""; - } else { - return "overflow-hidden"; - } - }; return ( -
-
- -
+
+
+ {/* */} +
-
+
} /> } /> - } /> + } /> } /> - } /> - } /> + } /> + } /> + {/* } /> */} {/* 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/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..0a4dd71 100644 --- a/src/components/Filter.jsx +++ b/src/components/Filter.jsx @@ -1,30 +1,128 @@ -import React from 'react' + import Search from './Search' - - +import { useEffect, useState } from 'react'; +import { categories, work_from_home, employment_types } from '../consts'; +import propTypes from 'prop-types'; +import Selector from './Selector'; const Filter = (props) => { - if (!props.isOpen) return null; - return ( -
- - - - + useEffect(() => { + console.log(props.searchQuery) + console.log(selectedCategories) + console.log(selectedWorkFromHome) + console.log(selectedEmploymentTypes) + console.log(valueminSalary) + }, [props.searchQuery]); - +
+ + + + + + + + + +
) -} +}; -export default Filter +Filter.propTypes = { + isOpen: propTypes.bool, + searchQuery: propTypes.object, + setSearchQuery: propTypes.func, + categories: propTypes.array, + clearSearchQuery: propTypes.func, + onClick: propTypes.func +}; + +export default Filter; 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 dc73c5a..2cbdd58 100644 --- a/src/components/JobOfferContent.jsx +++ b/src/components/JobOfferContent.jsx @@ -9,7 +9,7 @@ const JobOfferContent = ({ id, skills }) => { 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..8d12194 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,7 +20,7 @@ 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..de97710 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' @@ -112,5 +112,18 @@ const Salary = ({handleChange, formData, removeFields, setFormData}) => {
) } +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..76282aa 100644 --- a/src/components/Search.jsx +++ b/src/components/Search.jsx @@ -1,19 +1,61 @@ -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 33d1aa1..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', @@ -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 9e87d33..9dde322 100644 --- a/src/components/StepFourJoblisting.jsx +++ b/src/components/StepFourJoblisting.jsx @@ -1,6 +1,9 @@ -import React from "react"; +import propTypes from "prop-types"; + import styles from "../style"; import TextDivider from "./TextDivider"; + + const StepFourJoblisting = ({ handleChange, formData, nextStep, prevStep }) => { return (
@@ -120,4 +123,11 @@ const StepFourJoblisting = ({ handleChange, formData, nextStep, prevStep }) => { ); }; +StepFourJoblisting.propTypes = { + handleChange: propTypes.func, + formData: propTypes.object, + nextStep: propTypes.func, + prevStep: propTypes.func, +}; + export default StepFourJoblisting; diff --git a/src/components/StepOneJoblisting.jsx b/src/components/StepOneJoblisting.jsx index a2fd41e..213a6ef 100644 --- a/src/components/StepOneJoblisting.jsx +++ b/src/components/StepOneJoblisting.jsx @@ -1,5 +1,7 @@ -import React from "react"; + import styles from "../style"; +import propTypes from "prop-types"; + const StepOneJoblisting = ({ nextStep, handleChange, formData }) => { // Funkcja do obsługi kliknięcia na div i aktualizacji stanu const handleDivClick = (value) => () => { @@ -76,4 +78,10 @@ const StepOneJoblisting = ({ nextStep, handleChange, formData }) => { ); }; +StepOneJoblisting.propTypes = { + nextStep: propTypes.func, + handleChange: propTypes.func, + formData: propTypes.object, +}; + export default StepOneJoblisting; diff --git a/src/components/StepThreeJoblisting.jsx b/src/components/StepThreeJoblisting.jsx index 35a3653..defa578 100644 --- a/src/components/StepThreeJoblisting.jsx +++ b/src/components/StepThreeJoblisting.jsx @@ -1,12 +1,13 @@ -import React, { useEffect } from 'react'; + import DOMPurify from 'dompurify'; -import styles from '../style'; import TextDivider from './TextDivider'; import ListingSmall from './ListingSmall'; import { IzaacLOGO } from '../assets' import SkillsList from './SkillList'; +import PropTypes from 'prop-types'; + const StepThreeJoblisting = ({ formData, prevStep, skills, handleSubmit }) => { // Funkcja do przetwarzania HTML i dodawania klas const processHTML = (htmlString) => { @@ -103,4 +104,11 @@ const StepThreeJoblisting = ({ formData, prevStep, skills, handleSubmit }) => { ); } +StepThreeJoblisting.propTypes = { + formData: PropTypes.object, + prevStep: PropTypes.func, + skills: PropTypes.array, + handleSubmit: PropTypes.func +} + export default StepThreeJoblisting; diff --git a/src/components/StepTwoJoblisting.jsx b/src/components/StepTwoJoblisting.jsx index 09028dd..c462bae 100644 --- a/src/components/StepTwoJoblisting.jsx +++ b/src/components/StepTwoJoblisting.jsx @@ -1,4 +1,7 @@ -import React, { useState } from 'react' +import { useState } from 'react' +import propTypes from 'prop-types'; + +import { categories, experience_levels } from '../consts'; import styles from '../style' import { CKEditor } from '@ckeditor/ckeditor5-react'; import ClassicEditor from '@ckeditor/ckeditor5-build-classic'; @@ -7,8 +10,6 @@ import SkillsSelector from './SkillsSelector'; import Salary from './Salary'; import { placeholderImage } from '../assets'; -import { categories, experience_levels } from '../consts'; - const StepTwoJoblisting = ({ nextStep, prevStep, handleChange, formData, setFormData, removeFields, skills }) => { const [editorData, setEditorData] = useState(''); const [imageSrc, setImageSrc] = useState(placeholderImage); @@ -230,4 +231,14 @@ const StepTwoJoblisting = ({ nextStep, prevStep, handleChange, formData, setForm ) } +StepTwoJoblisting.propTypes = { + nextStep: propTypes.func, + prevStep: propTypes.func, + handleChange: propTypes.func, + formData: propTypes.object, + setFormData: propTypes.func, + removeFields: propTypes.func, + skills: propTypes.array +} + export default StepTwoJoblisting diff --git a/src/components/Success.jsx b/src/components/Success.jsx index 9de475b..a6c76c0 100644 --- a/src/components/Success.jsx +++ b/src/components/Success.jsx @@ -1,4 +1,4 @@ -import React from 'react' + import TextDivider from './TextDivider' const Success = () => { diff --git a/src/components/TextDivider.jsx b/src/components/TextDivider.jsx index e1a9f94..292a4a7 100644 --- a/src/components/TextDivider.jsx +++ b/src/components/TextDivider.jsx @@ -1,6 +1,7 @@ -import React from 'react' -const TextDivider = ({text }) => { +import propTypes from 'prop-types' + +const TextDivider = ({ text }) => { return (
@@ -13,4 +14,7 @@ const TextDivider = ({text }) => { ) } +TextDivider.propTypes = { + text: propTypes.string +} export default TextDivider diff --git a/src/components/WorkApp.jsx b/src/components/WorkApp.jsx index 24ce4b6..f0e3b3f 100644 --- a/src/components/WorkApp.jsx +++ b/src/components/WorkApp.jsx @@ -2,13 +2,15 @@ import React from "react"; import { useState, useEffect } from "react"; import ListingSmall from "./ListingSmall"; -import SkillRender from "./SkillRender"; -import Search from "./Search"; +// import SkillRender from "./SkillRender"; +// import Search from "./Search"; import Filter from "./Filter"; -import Category from "./Category"; +// import Category from "./Category"; import JobOfferContent from "./JobOfferContent"; import { categories } from "../consts"; import axios from "axios"; +import { Link, useParams } from "react-router-dom"; + function renderCircles(level) { let numberOfFilledCircles; @@ -44,11 +46,17 @@ function renderCircles(level) { } const WorkApp = () => { + let { id } = useParams(); + const [isDetailsVisible, setIsDetailsVisible] = useState(false); // Czy szczegóły są widoczne const [isOpen, setIsOpen] = useState(false); - // Funkcja pobierająca dane z API + // useEffect(() => { + // if (!isOpen) { + // setSearchQuery({ name: "", localization: "", min_salary: "", max_salary: "" }); + // }}, [isOpen]); + const [ogloszenia, setOgloszenia] = useState([]); const [skills, setSkills] = useState([]); @@ -64,12 +72,15 @@ const WorkApp = () => { // console.log(data); if (data.length > 0) { setSelectedOgloszenie(data[0]); - // console.log(data[0]) + console.log(data[0]) } } catch (error) { console.error(error); } }; + if (id === undefined) { + id = ogloszenia[0]?.id; + } const getSkills = async () => { try { @@ -86,26 +97,27 @@ const WorkApp = () => { const [searchQuery, setSearchQuery] = useState({}); + const clearSearchQuery = () => { + setSearchQuery({}); + }; + const [selectedOgloszenie, setSelectedOgloszenie] = useState(ogloszenia[0]); useEffect(() => { getOgloszenia(); getSkills(); + }, []); + useEffect(() => { + document.title = `Izaac - ${selectedOgloszenie?.name}`; + }, [selectedOgloszenie?.name]); + const handleOgloszenieClick = (ogloszenie) => { setSelectedOgloszenie(ogloszenie); setIsDetailsVisible(true); // Pokaż szczegóły na urządzeniach mobilnych }; - const prevSlide = () => { - setCurrentSlide( - (prevSlide) => (prevSlide - 1 + categories.length) % categories.length - ); - }; - const nextSlide = () => { - setCurrentSlide((prevSlide) => (prevSlide + 1) % categories.length); - }; - const [currentSlide, setCurrentSlide] = React.useState(0); + // Funkcja do powrotu do listy ogłoszeń const handleBackToList = () => { setIsDetailsVisible(false); @@ -125,53 +137,50 @@ const WorkApp = () => { }, []); return ( -
-
-
- - {categories.map((category, index) => ( -
- { getOgloszenia({ category: category.id }); }} - /> -
- ))} - -
+
+
+
-
-

+
+
+

Oferty pracy

+
-
- {isOpen && } +
+ {getOgloszenia(searchQuery) + setIsOpen(!isOpen) + }}/>
+
+
{ogloszenia.map((ogloszenie, index) => ( + { require_salary={ogloszenie.require_salary} image={ogloszenie.image} index={index} - onClick={() => handleOgloszenieClick(ogloszenie)} + onClick={() => {handleOgloszenieClick(ogloszenie)}} + selected={selectedOgloszenie?.id === ogloszenie.id} + blur={isOpen ? 'blur' : ''} /> + ))} +
{isDetailsVisible && (
@@ -202,19 +215,8 @@ const WorkApp = () => { )} {selectedOgloszenie && ( - + )} - {/*
- {Object.entries(selectedOgloszenie.neededSkills).map(([skill, level]) => ( - - ))} -
-
- {selectedOgloszenie.tresc} -
*/}

diff --git a/src/consts/index.js b/src/consts/index.js index 314d91f..079ff4f 100644 --- a/src/consts/index.js +++ b/src/consts/index.js @@ -169,12 +169,12 @@ export const linki = [ }, { "id": "2", - "name": "work/postings", + "name": "work/joboffers", "title": "Ogłoszenia", }, { "id": "3", - "name": "work/jobposting", + "name": "work/addjoboffer", "title": "Dodaj ogłoszenie", }, { diff --git a/src/index.css b/src/index.css index f9d7ff6..96f809a 100644 --- a/src/index.css +++ b/src/index.css @@ -22,6 +22,27 @@ } } +/* @layer components { + .no-spin-buttons::-webkit-inner-spin-button, + .no-spin-buttons::-webkit-outer-spin-button { + @apply -webkit-appearance-none margin-0; + } + .no-spin-buttons { + @apply -moz-appearance-textfield; + } +} */ + +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + -webkit-appearance: none; + margin: 0; +} + +/* Dla Firefox */ +input[type="number"] { + -moz-appearance: textfield; +} + @tailwind components; @tailwind utilities; @@ -60,11 +81,43 @@ } /* Expanded state styles */ -.expanded { - max-height: fit-content; /* Adjust as needed */ - opacity: 1; +.collapsible { + max-height: 0; + overflow: hidden; + transition-property: all; + transition-timing-function: ease-in-out; + transition-duration: 0.5s; } +/* Styl dla elementu, gdy jest rozwinięty */ +.collapsible.expanded { + max-height: 1000px; /* Przykładowa maksymalna wysokość, może wymagać dostosowania */ + opacity: 1; + transition-property: all; + transition-timing-function: ease-in-out; + transition-duration: 0.5s; +} + +.div-transition { + transition-property: filter; + transition-duration: 1s; + transition-timing-function: ease-in-out; +} + + +.noblur { + filter: blur(0px); + transition-property: filter; + transition-duration: 0.5s; + transition-timing-function: ease-in-out; +} + +.blur { + filter: blur(5px); + transition-property: filter; + transition-duration: 0.5s; + transition-timing-function: ease-in-out; +} .minus-z-index { z-index: -10; } @@ -109,59 +162,4 @@ .sidebar-hide { -webkit-animation: slide-down 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) both; animation: slide-down 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) both; -} - -@-webkit-keyframes slide-top { - 0% { - -webkit-transform: translateX(600px); - transform: translateX(600px); - } - 100% { - -webkit-transform: translateX(0); - transform: translateX(0); - } -} - -@keyframes slide-top { - 0% { - -webkit-transform: translateX(600px); - transform: translateX(600px); - } - 100% { - -webkit-transform: translateX(0); - transform: translateX(0); - } -} - -@-webkit-keyframes slide-down { - 0% { - -webkit-transform: translateX(0); - transform: translateX(0); - } - 100% { - -webkit-transform: translateX(600px); - transform: translateX(600px); - } -} - -@keyframes slide-down { - 0% { - -webkit-transform: translateX(0); - transform: translateX(0); - } - 100% { - -webkit-transform: translateX(600px); - transform: translateX(600px); - } -} - - -@media (max-width: 768px) { - .details-section { - display: none; - } - .list-section { - display: block; - } -} - +} \ No newline at end of file diff --git a/tailwind.config.js b/tailwind.config.js index 0d1d585..aca5157 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -7,7 +7,7 @@ module.exports = { colors: { primary: "#00040f", secondary: "#00f6ff", - dimWhite: "rgba(255, 255, 255, 0.7)", + dimWhite: "rgba(255, 255, 255, 0.8)", dimBlue: "rgba(9, 151, 124, 0.1)", }, fontFamily: {