zmiany do mobile, filtrowanie, poprawki
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
97b7e8726d
commit
45a2c8252e
@ -21,7 +21,7 @@ function App() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={`${styles.flexStart} mt-18 sm:mt-[6.5rem]`}>
|
<div className={`${styles.flexStart} mt-18 sm:mt-[4.5rem] md:mt-[6.5rem]`}>
|
||||||
<div className={`${styles.boxWidth2} `}>
|
<div className={`${styles.boxWidth2} `}>
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route path="/home" element={<Home />} />
|
<Route path="/home" element={<Home />} />
|
||||||
|
|||||||
106
src/components/CategorySelect.jsx
Normal file
106
src/components/CategorySelect.jsx
Normal file
@ -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 (
|
||||||
|
<div className='mb-3'>
|
||||||
|
<p className='text-center'>Kategorie</p>
|
||||||
|
<div className='flex flex-wrap gap-y-2 mt-1 '>
|
||||||
|
{selectedCategoryIds.map(id => {
|
||||||
|
const category = categories.find(cat => cat.id === id);
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={id}
|
||||||
|
onClick={() => 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 '
|
||||||
|
>
|
||||||
|
<p className='font-poppins text-sm'>{category.name}
|
||||||
|
<span className='relative -top-[2px] left-1'>×</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className='border-2 rounded-lg px-3 py-1 w-full mt-2'
|
||||||
|
value={inputValue}
|
||||||
|
onChange={handleInputChange}
|
||||||
|
placeholder='Wpisz kategorię...'
|
||||||
|
/>
|
||||||
|
{inputValue.length >= 1 && suggestions.length > 0 && (
|
||||||
|
<div className='absolute h-40 w-[90%] overflow-y-auto'>
|
||||||
|
{suggestions.map(suggestion => (
|
||||||
|
<div
|
||||||
|
className='mx-3 p-3 border-2 border-gray-300 bg-gray-100 hover:bg-gray-200 cursor-pointer'
|
||||||
|
key={suggestion.id}
|
||||||
|
onClick={() => handleSuggestionClick(suggestion)}
|
||||||
|
>
|
||||||
|
{suggestion.name}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
CategorySelect.propTypes = {
|
||||||
|
setSearchQuery: PropTypes.func.isRequired,
|
||||||
|
searchQuery: PropTypes.shape({
|
||||||
|
categories: PropTypes.arrayOf(PropTypes.string)
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CategorySelect
|
||||||
@ -11,11 +11,11 @@ const Cookies = props => {
|
|||||||
if (!show) return null;
|
if (!show) return null;
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className='bg-gray-500 opacity-90 h-32 w-full fixed bottom-0 z-40 flex justify-center items-center'>
|
<div className='bg-neutral-900 opacity-[99%] h-24 sm:h-16 w-full fixed bottom-0 z-40 flex justify-center items-center'>
|
||||||
<p className=' text-black'>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
|
<p className='mx-5 text-justify text-white font-'>Korzystamy z plików cookie, aby zapewnić prawidłowe działanie witryny. </p>
|
||||||
<button className='bg-white px-4 py-2 rounded-md ml-4'
|
<button className= 'bg-white px-4 py-2 rounded-md ml-4 mr-4 ring-2 ring-dimWhite hover:ring-4 duration-300 font-semibold'
|
||||||
onClick={() => {handleCookies; setShow(!show)}}>
|
onClick={() => {handleCookies; setShow(!show)}}>
|
||||||
Zgoda</button>
|
Wyrażenie zgody</button>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@ -1,91 +1,185 @@
|
|||||||
|
import { useCallback, useEffect, useMemo } from 'react';
|
||||||
import Search from './Search'
|
import PropTypes from 'prop-types';
|
||||||
import { useEffect, useState } from 'react';
|
import Search from './Search';
|
||||||
import { categories, work_from_home, employment_types } from '../consts';
|
|
||||||
import propTypes from 'prop-types';
|
|
||||||
import Selector from './Selector';
|
import Selector from './Selector';
|
||||||
const Filter = (props) => {
|
import RangeSlider from './RangeSlider';
|
||||||
useEffect(() => {
|
import CategorySelect from './CategorySelect';
|
||||||
console.log(props.searchQuery)
|
import { categories, work_from_home, employment_types } from '../consts';
|
||||||
}, [props.searchQuery]);
|
|
||||||
|
const Filter = ({ isOpen, searchQuery, setSearchQuery, clearSearchQuery, onClick }) => {
|
||||||
|
const [min_salary, max_salary] = [0, 100000];
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
console.log(searchQuery);
|
||||||
|
}, [searchQuery]);
|
||||||
|
|
||||||
|
|
||||||
const handle_checked_change = (e) => {
|
const handleRangeChange = useCallback((newMin, newMax) => {
|
||||||
const { name, value, checked } = e.target;
|
setSearchQuery(prevState => ({
|
||||||
props.setSearchQuery(prevState => {
|
...prevState,
|
||||||
const newArray = checked
|
min_salary: newMin,
|
||||||
? [...(prevState[name] || []), value]
|
max_salary: newMax
|
||||||
: (prevState[name] || []).filter(item => item !== value);
|
}));
|
||||||
return { ...prevState, [name]: newArray };
|
}, [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 (
|
return (
|
||||||
// idea - make the page whole page grayed out and only the filter is visible
|
<div className={`z-10 flex flex-col bg-dimWhite collapsible px-3 sm:px-4 ${isOpen ? 'expanded border-4' : ''}`}>
|
||||||
<div className={`z-10 bg-dimWhite collapsible px-3 sm:px-4 ${!props.isOpen ? '' : 'expanded border-4'}`}>
|
<div className="grid grid-cols-2 md:grid-cols-3 mb-2">
|
||||||
<div className='grid grid-cols-2 sm:grid-cols-3 mb-2'>
|
<div className="hidden md:block" />
|
||||||
<div className='hidden sm:block'></div>
|
<p className="mx-auto mt-3 place-self-center text-center font-poppins font-semibold text-xl text-gray-600">Filtry</p>
|
||||||
<p className='mx-auto mt-3 text-center font-poppins font-semibold text-xl text-gray-600'>Filtry</p>
|
<button
|
||||||
|
className="rounded-xl mt-4 w-32 py-1 bg-slate-400 hover:bg-slate-600 duration-100"
|
||||||
<button className='rounded-xl mt-4 ph-6 w-32 bg-slate-400 hover:bg-slate-600 duration-100 ' onClick={props.clearSearchQuery}>
|
onClick={clearSearchQuery}
|
||||||
<span className='p-2 text-sm font-bold text-center font-poppins text-white'>Wyczyść filtry</span>
|
>
|
||||||
|
<span className="p-2 text-sm font-bold text-center font-poppins text-white">Wyczyść filtry</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Search
|
||||||
|
label="Wyszukaj ogłoszenie"
|
||||||
|
placeholder="Wpisz nazwę stanowiska..."
|
||||||
|
name="name"
|
||||||
|
type="text"
|
||||||
|
value={searchQuery.name || ''}
|
||||||
|
onChange={(e) => handleChange(e, 'name')}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div className="grid grid-cols-2 gap-x-4">
|
||||||
|
<Search
|
||||||
|
label="Min. wynagrodzenie"
|
||||||
|
label2="wynagrodzenie"
|
||||||
|
placeholder="Wpisz kwotę minimalną..."
|
||||||
|
name="min_salary"
|
||||||
|
type="text"
|
||||||
|
value={searchQuery.min_salary || ''}
|
||||||
|
onChange={(e) => handleChange(e, 'min_salary')}
|
||||||
|
/>
|
||||||
|
<Search
|
||||||
|
label="Max. wynagrodzenie"
|
||||||
|
placeholder="Wpisz kwotę maksymalną..."
|
||||||
|
name="max_salary"
|
||||||
|
type="text"
|
||||||
|
value={searchQuery.max_salary || ''}
|
||||||
|
onChange={(e) => handleChange(e, 'max_salary')}
|
||||||
|
/>
|
||||||
|
<RangeSlider
|
||||||
|
min={min_salary}
|
||||||
|
max={max_salary}
|
||||||
|
minVal={searchQuery.min_salary || min_salary}
|
||||||
|
maxVal={searchQuery.max_salary || max_salary}
|
||||||
|
setSearchQuery={setSearchQuery}
|
||||||
|
onRangeChange={handleRangeChange}
|
||||||
|
isOpen={isOpen}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<CategorySelect
|
||||||
|
setSearchQuery = {setSearchQuery}
|
||||||
|
searchQuery = {searchQuery}
|
||||||
|
clearSearchQuery = {clearSearchQuery}
|
||||||
|
/>
|
||||||
|
{/* <Selector
|
||||||
|
value_to_map_from={categories}
|
||||||
|
name="Kategorie"
|
||||||
|
inputname="categories"
|
||||||
|
onChange={handleCheckedChange}
|
||||||
|
state={searchQuery || {}}
|
||||||
|
/> */}
|
||||||
|
{/* <Selector
|
||||||
|
value_to_map_from={work_from_home}
|
||||||
|
name="Praca zdalna"
|
||||||
|
inputname="employment_types"
|
||||||
|
onChange={handleCheckedChange}
|
||||||
|
state={searchQuery || {}}
|
||||||
|
/>
|
||||||
|
<Selector
|
||||||
|
value_to_map_from={employment_types}
|
||||||
|
name="Typ kontraktu"
|
||||||
|
inputname="employment_types"
|
||||||
|
onChange={handleCheckedChange}
|
||||||
|
state={searchQuery || {}}
|
||||||
|
/> */}
|
||||||
|
|
||||||
|
<button className={filterButtonClass} onClick={onClick}>
|
||||||
|
Filtruj
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
);
|
||||||
<Search label='Wyszukaj ogłoszenie'
|
|
||||||
placeholder='Wpisz nazwę stanowiska...'
|
|
||||||
name='name'
|
|
||||||
setSearchQuery={props.setSearchQuery}
|
|
||||||
_type='text'
|
|
||||||
value={props.searchQuery.name || ''}/>
|
|
||||||
<Search label='Lokalizacja'
|
|
||||||
placeholder='Wpisz lokalizację...'
|
|
||||||
name='localization'
|
|
||||||
_type='text'
|
|
||||||
setSearchQuery={props.setSearchQuery}
|
|
||||||
value={props.searchQuery.localization || ''} />
|
|
||||||
<Search label='Min. wynagrodzenie'
|
|
||||||
placeholder='Wpisz kwotę minimalną...'
|
|
||||||
name='min_salary'
|
|
||||||
_type='text'
|
|
||||||
setSearchQuery={props.setSearchQuery}
|
|
||||||
value={props.searchQuery.min_salary || '' } />
|
|
||||||
<Search label='Max. wynagrodzenie'
|
|
||||||
placeholder='Wpisz kwotę maksymalną...'
|
|
||||||
name='max_salary'
|
|
||||||
setSearchQuery={props.setSearchQuery}
|
|
||||||
_type='text'
|
|
||||||
value={props.searchQuery.max_salary || ''}/>
|
|
||||||
<Selector value_to_map_from={categories} name='Kategorie' inputname='categories' onChange={handle_checked_change} state={props.searchQuery || {} }/>
|
|
||||||
<Selector value_to_map_from={work_from_home} s name='Praca zdalna' inputname='work_from_home' state={props.searchQuery || {}} onChange={handle_checked_change}/>
|
|
||||||
<Selector value_to_map_from={employment_types} name='Typ kontraktu' inputname='employment' state={props.searchQuery || {}} onChange={handle_checked_change} />
|
|
||||||
|
|
||||||
<button className='bg-gray-600 text-white py-1 sm:py-3 px-12 col-span-2 mx-auto rounded-md font-semibold text-xl hover:bg-gray-500 duration-150 my-3 sm:my-5 sm:min-h-full'
|
|
||||||
onClick={props.onClick}
|
|
||||||
>
|
|
||||||
Filtruj
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Filter.propTypes = {
|
Filter.propTypes = {
|
||||||
isOpen: propTypes.bool,
|
isOpen: PropTypes.bool.isRequired,
|
||||||
searchQuery: propTypes.object,
|
searchQuery: PropTypes.shape({
|
||||||
setSearchQuery: propTypes.func,
|
name: PropTypes.string,
|
||||||
categories: propTypes.array,
|
min_salary: PropTypes.number,
|
||||||
clearSearchQuery: propTypes.func,
|
max_salary: PropTypes.number,
|
||||||
onClick: propTypes.func
|
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 = {
|
Filter.defaultProps = {
|
||||||
searchQuery: {
|
searchQuery: {
|
||||||
categories: [],
|
categories: [],
|
||||||
work_from_home: [],
|
work_from_home: [],
|
||||||
employment: []
|
employment_types: []
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Filter;
|
export default Filter;
|
||||||
76
src/components/RangeSlider.jsx
Normal file
76
src/components/RangeSlider.jsx
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
import { useRef, useEffect, useCallback } from 'react';
|
||||||
|
import propTypes from 'prop-types';
|
||||||
|
|
||||||
|
|
||||||
|
const RangeSlider = ({ min, max, minVal, maxVal, setSearchQuery, onRangeChange, isOpen }) => {
|
||||||
|
const minValRef = useRef(minVal);
|
||||||
|
const maxValRef = useRef(maxVal);
|
||||||
|
const range = useRef(null);
|
||||||
|
|
||||||
|
const getPercent = useCallback(
|
||||||
|
(value) => Math.round(((value - min) / (max - min)) * 100),
|
||||||
|
[min, max]
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const minPercent = getPercent(minVal === '' ? min : minVal);
|
||||||
|
const maxPercent = getPercent(maxVal === '' ? max : maxVal);
|
||||||
|
|
||||||
|
if (range.current) {
|
||||||
|
range.current.style.left = `${minPercent}%`;
|
||||||
|
range.current.style.width = `${maxPercent - minPercent}%`;
|
||||||
|
}
|
||||||
|
}, [minVal, maxVal, getPercent, min, max]);
|
||||||
|
|
||||||
|
const handleChange = useCallback((event) => {
|
||||||
|
const { id, value } = event.target;
|
||||||
|
const numValue = Number(value);
|
||||||
|
|
||||||
|
let newMinVal = minVal === '' ? min : minVal;
|
||||||
|
let newMaxVal = maxVal === '' ? max : maxVal;
|
||||||
|
|
||||||
|
if (id === 'range1') {
|
||||||
|
newMinVal = numValue;
|
||||||
|
minValRef.current = newMinVal;
|
||||||
|
} else if (id === 'range2') {
|
||||||
|
newMaxVal = numValue;
|
||||||
|
maxValRef.current = newMaxVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
onRangeChange(newMinVal, newMaxVal);
|
||||||
|
}, [minVal, maxVal, min, max, onRangeChange]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='col-span-2 my-5 px-8 slider-wrapper'>
|
||||||
|
<input
|
||||||
|
id="range1"
|
||||||
|
type="range"
|
||||||
|
min={min}
|
||||||
|
step={100}
|
||||||
|
max={max}
|
||||||
|
value={minVal === '' ? min : minVal}
|
||||||
|
onChange={handleChange}
|
||||||
|
className={`thumb w-[85%] sm:w-[84%] thumb--left thumb--animatedin thumb--animatedout`}
|
||||||
|
style={isOpen ? { zIndex: (minVal === '' ? min : minVal) > (maxVal === '' ? max - 100 : maxVal - 100) ? 5 : undefined, } : { display: 'none' }}
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
id="range2"
|
||||||
|
type="range"
|
||||||
|
min={min}
|
||||||
|
max={max}
|
||||||
|
step={100}
|
||||||
|
value={maxVal === '' ? max : maxVal}
|
||||||
|
onChange={handleChange}
|
||||||
|
className={`thumb w-[85%] sm:w-[84%] thumb--right thumb--animatedin thumb--animatedout sm`}
|
||||||
|
style={isOpen ? {} : { display: 'none'}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div className="slider" >
|
||||||
|
<div className="slider__track " />
|
||||||
|
<div ref={range} className="slider__range" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default RangeSlider;
|
||||||
@ -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' : ''} `}/></div>
|
className={`h-12 border-2 rounded-xl px-5 mx-4 w-full ${!require_salary ? 'bg-slate-200' : ''} `}/></div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<p className='font-poppins font-semibold text-slate-700 text-center text-[14px] mt-1 mb-2'>Typ kontraktu</p>
|
<p className='font-poppins font-semibold text-slate-700 text-center text-[14px] mt-1 mb-2'>Typ <br className='hidden sm:block md:hidden'/>kontraktu</p>
|
||||||
<select
|
<select
|
||||||
value={formData['employment_type'] || 'default' }
|
value={formData['employment_type'] || 'default' }
|
||||||
name='employmentType'
|
name='employmentType'
|
||||||
@ -96,7 +96,7 @@ const Salary = ({handleChange, formData, removeFields, setFormData}) => {
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className='font-poppins font-semibold text-slate-700 text-center text-[14px] mt-1 mb-2'>Praca zdalna</p>
|
<p className='font-poppins font-semibold text-slate-700 text-center text-[14px] mt-1 mb-2'>Praca <br className='block md:hidden'/> zdalna</p>
|
||||||
<select
|
<select
|
||||||
value={formData['work_from_home'] || 'default' }
|
value={formData['work_from_home'] || 'default' }
|
||||||
name='workFromHome'
|
name='workFromHome'
|
||||||
|
|||||||
@ -21,13 +21,13 @@ useEffect(() => {
|
|||||||
}, [props.value])
|
}, [props.value])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='grid sm:py-1'
|
<div className='grid sm:py-1 '
|
||||||
onMouseEnter={() => setIsHovered(true)}
|
onMouseEnter={() => setIsHovered(true)}
|
||||||
onMouseLeave={() => setIsHovered(false)}
|
onMouseLeave={() => setIsHovered(false)}
|
||||||
>
|
>
|
||||||
<label className="mx-2 text-l font- text-center font-poppins no-spin-buttons"
|
<label className="mx-2 text-l text-center ml-3 font-poppins no-spin-buttons"
|
||||||
htmlFor="search">
|
htmlFor="search">
|
||||||
{props.label}
|
<p className='text-sm'>{props.label}</p>
|
||||||
<span className='text-sm text-red-700'>
|
<span className='text-sm text-red-700'>
|
||||||
{check_errors(props.value, props.name) ? '' : ' *'}
|
{check_errors(props.value, props.name) ? '' : ' *'}
|
||||||
</span>
|
</span>
|
||||||
@ -38,9 +38,9 @@ useEffect(() => {
|
|||||||
placeholder={props.placeholder}
|
placeholder={props.placeholder}
|
||||||
name={props.name}
|
name={props.name}
|
||||||
id={props.name}
|
id={props.name}
|
||||||
onChange={(e) => props.setSearchQuery(prevState => ({...prevState, [props.name]: e.target.value}))}
|
onChange={props.onChange}
|
||||||
className={`border-2
|
className={`border-2 ${ props.name === 'min_salary' || props.name === 'max_salary' ? 'w-[12rem] xs:w-[20rem] sm:w-full md:w-full lg:w-full' : '' }
|
||||||
bg-white h-8 px-5 pr-16 mx-3 rounded-lg
|
bg-white h-8 px-5 rounded-lg
|
||||||
text-sm focus:outline-none ${check_errors(props.value, props.name) ? 'border-gray-300': 'border-red-700' }`}/>
|
text-sm focus:outline-none ${check_errors(props.value, props.name) ? 'border-gray-300': 'border-red-700' }`}/>
|
||||||
{isHovered && <div className='text-red-700 text-sm relative'>
|
{isHovered && <div className='text-red-700 text-sm relative'>
|
||||||
{check_errors(props.value, props.name) ? '' : 'Wartość musi być liczbą!'}
|
{check_errors(props.value, props.name) ? '' : 'Wartość musi być liczbą!'}
|
||||||
@ -55,7 +55,8 @@ Search.propTypes = {
|
|||||||
name: propTypes.string,
|
name: propTypes.string,
|
||||||
setSearchQuery: propTypes.func,
|
setSearchQuery: propTypes.func,
|
||||||
value: propTypes.string,
|
value: propTypes.string,
|
||||||
_type: propTypes.string
|
_type: propTypes.string,
|
||||||
|
onChange: propTypes.func
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Search
|
export default Search
|
||||||
|
|||||||
@ -1,33 +1,35 @@
|
|||||||
import propTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
const Selector = (props) => {
|
const Selector = (props) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className='grid grid-cols-2 sm:gap-[1px]'>
|
<div className='grid grid-cols-2 sm:gap-[1px]'>
|
||||||
<span className='col-span-2 mx-auto text-l font- text-center font-poppins'>{props.name}</span>
|
<span className='col-span-2 mx-auto text-l font- text-center font-poppins'>{props.name}</span>
|
||||||
{props.value_to_map_from.map((value_to_map_from) => (
|
{props.value_to_map_from.map((value_to_map_from) => (
|
||||||
<label key={value_to_map_from.id} className
|
<label key={value_to_map_from.id} className='flex items-center justify-start text-sm font-poppins font-semibold text-gray-600'>
|
||||||
='flex items-center justify-start text-sm font-poppins font-semibold text-gray-600'>
|
<input
|
||||||
<input type='checkbox' name={props.inputname} value={value_to_map_from.id}
|
type='checkbox'
|
||||||
onChange={props.onChange}
|
name={props.inputname}
|
||||||
className='mr-2'
|
value={value_to_map_from.id}
|
||||||
checked={props.state[props.inputname]?.includes(value_to_map_from.id)}
|
onChange={props.onChange}
|
||||||
/>
|
className='mr-2'
|
||||||
{value_to_map_from.name}
|
checked={Array.isArray(props.state[props.inputname]) && props.state[props.inputname].includes(value_to_map_from.id)}
|
||||||
</label>
|
/>
|
||||||
))}
|
{value_to_map_from.name}
|
||||||
</div>
|
</label>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
Selector.propTypes = {
|
Selector.propTypes = {
|
||||||
value_to_map_from: propTypes.array,
|
value_to_map_from: PropTypes.array,
|
||||||
setSearchQuery: propTypes.func,
|
setSearchQuery: PropTypes.func,
|
||||||
name: propTypes.string,
|
name: PropTypes.string,
|
||||||
inputname: propTypes.string,
|
inputname: PropTypes.string,
|
||||||
onChange: propTypes.func,
|
onChange: PropTypes.func,
|
||||||
state: propTypes.array
|
state: PropTypes.object
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Selector
|
export default Selector
|
||||||
@ -102,15 +102,15 @@ const StepFourJoblisting = ({ handleChange, formData, nextStep, prevStep }) => {
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={prevStep}
|
onClick={prevStep}
|
||||||
className="h-12 w-72 rounded-xl bg-gray-700 font-poppins font-semibold text-[14px] scale-100 text-white hover:scale-125 duration-300"
|
className="h-16 md:h-12 w-80 md:w-72 rounded-xl bg-gray-700 font-poppins font-semibold text-[14px] text-white hover:scale-125 duration-300"
|
||||||
>
|
>
|
||||||
<span className="text-[18px]">←</span> Przejdź do
|
<span className="text-[18px]">←</span> Przejdź do <br className="block md:hidden"/>
|
||||||
poprzedniego kroku
|
poprzedniego kroku
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={nextStep}
|
onClick={nextStep}
|
||||||
className="h-12 w-72 rounded-xl bg-gray-700 font-poppins font-semibold text-[14px] scale-100 text-white hover:scale-125 duration-300"
|
className="h-16 md:h-12 w-80 md:w-72 rounded-xl bg-gray-700 font-poppins font-semibold text-[14px] text-white hover:scale-125 duration-300"
|
||||||
>
|
>
|
||||||
Przejdź do następnego kroku
|
Przejdź do następnego kroku
|
||||||
<span className="text-[18px]">→</span>{" "}
|
<span className="text-[18px]">→</span>{" "}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
import styles from "../style";
|
import styles from "../style";
|
||||||
import propTypes from "prop-types";
|
import propTypes from "prop-types";
|
||||||
|
import { lorem_ipsum, lorem_ipsum_premium, lorem_ipsum_starter } from "../consts";
|
||||||
|
|
||||||
const StepOneJoblisting = ({ nextStep, handleChange, formData }) => {
|
const StepOneJoblisting = ({ nextStep, handleChange, formData }) => {
|
||||||
// Funkcja do obsługi kliknięcia na div i aktualizacji stanu
|
// Funkcja do obsługi kliknięcia na div i aktualizacji stanu
|
||||||
@ -9,48 +10,62 @@ const StepOneJoblisting = ({ nextStep, handleChange, formData }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const activeStyle =
|
const activeStyle =
|
||||||
"h-[500px] w-64 border-4 rounded-xl border-stone-200 bg-gray-200 div-transition scale-125";
|
"h-[200px] sm:h-[350px] md:h-min w-64 pb-4 border-4 rounded-xl border-stone-200 bg-gray-200 div-transition scale-105 sm:scale-110";
|
||||||
const inactiveStyle =
|
const inactiveStyle =
|
||||||
"h-[500px] w-64 rounded-xl bg-gray-200 border-gray-200 div-transition cursor-pointer hover:bg-gray-300";
|
"h-[200px] sm:h-[350px] md:h-min w-64 pb-4 rounded-xl bg-gray-200 border-gray-200 div-transition cursor-pointer hover:bg-gray-300";
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div
|
<div
|
||||||
className={` grid grid-cols-1 ${styles.paddingX} pb-8 pt-8 gap-1 h-full`}
|
className={`grid grid-cols-1 ${styles.paddingX} pb-8 mt-24 xs:mt-2 xs:pt-8 gap-1 h-full`}
|
||||||
>
|
>
|
||||||
<h1 className={`${styles.heading1} text-center`}>
|
<h1 className={`text-center text-2xl sm:text-[40px] font-bold`}>
|
||||||
Zacznij dodawać ogłoszenie z izaac.pl
|
Zacznij dodawać <br className="block md:hidden" /> ogłoszenie z izaac.pl
|
||||||
</h1>
|
</h1>
|
||||||
<p className={`${styles.paragraph} text-center`}>
|
<p className={`text-center text-xl mt-3`}>
|
||||||
Wybierz pakiet najlepiej odpowiadający Twoim potrzebom
|
Wybierz pakiet najlepiej <br className="block md:hidden" />odpowiadający Twoim potrzebom
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className={` ${styles.flexStart} ${styles.paddingX} gap-16 mt-20`}>
|
<div className="h-[300px] sm:h-[600px]">
|
||||||
{/* Przykładowe divy jako przyciski wyboru */}
|
<div className={` ${styles.flexStart} ${styles.paddingX} gap-3 xs:gap-5 sm:gap-8 mt-6`}>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
className={
|
className={
|
||||||
formData.posting_option === "M" ? activeStyle : inactiveStyle
|
formData.posting_option === "M" ? activeStyle : inactiveStyle
|
||||||
}
|
}
|
||||||
onClick={handleDivClick("M")}
|
onClick={handleDivClick("M")}
|
||||||
>
|
>
|
||||||
<p className={`${styles.paragraph} text-center mt-4`}>Starter</p>
|
<p
|
||||||
|
className={`font-poppins text-l
|
||||||
|
sm:text-xl text-center mt-4`}>
|
||||||
|
Starter
|
||||||
|
</p>
|
||||||
|
<ul className="hidden md:block">
|
||||||
|
{lorem_ipsum_starter.map((lorem_ipsum) =>
|
||||||
|
(<li className="text-sm lista-outside mx-8 text-justify list-inside">{lorem_ipsum}</li>)
|
||||||
|
)}
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div className="h-[400px] w-0.5 bg-gray-300"></div>
|
<div className="h-[150px] sm:h-[250px] md:h-[300px] w-0.5 bg-gray-300"></div>
|
||||||
<div
|
<div
|
||||||
className={
|
className={
|
||||||
formData.posting_option === "S" ? activeStyle : inactiveStyle
|
formData.posting_option === "S" ? activeStyle : inactiveStyle
|
||||||
}
|
}
|
||||||
onClick={handleDivClick("S")}
|
onClick={handleDivClick("S")}
|
||||||
>
|
>
|
||||||
<p className={`${styles.paragraph} text-center mt-4`}>Standard</p>
|
<p className={`font-poppins text-l sm:text-xl text-center mt-4`}>Standard</p>
|
||||||
<div className="mt-6">
|
<div className="mt-2">
|
||||||
<p className={`${styles.paragraph} text-center`}>
|
<p className={`font-poppins text-sm sm:text-[14px] text-center mb-2`}>
|
||||||
najczęsciej wybierany
|
najczęsciej wybierany
|
||||||
</p>
|
</p>
|
||||||
|
<ul className="hidden md:block">
|
||||||
|
{lorem_ipsum.map((lorem_ipsum) =>
|
||||||
|
(<li className="text-sm lista-outside mx-8 text-justify list-inside">{lorem_ipsum}</li>)
|
||||||
|
)}
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="h-[400px] w-0.5 bg-gray-300"></div>
|
<div className="h-[150px] sm:h-[250px] md:h-[300px] w-0.5 bg-gray-300"></div>
|
||||||
<div
|
<div
|
||||||
className={
|
className={
|
||||||
formData.posting_option === "P" ? activeStyle : inactiveStyle
|
formData.posting_option === "P" ? activeStyle : inactiveStyle
|
||||||
@ -58,21 +73,26 @@ const StepOneJoblisting = ({ nextStep, handleChange, formData }) => {
|
|||||||
onClick={handleDivClick("P")}
|
onClick={handleDivClick("P")}
|
||||||
style={{ cursor: "pointer" }}
|
style={{ cursor: "pointer" }}
|
||||||
>
|
>
|
||||||
<p className={`${styles.paragraph} text-center mt-4`}>Premium</p>
|
<p className={`font-poppins text-l sm:text-xl text-center mt-4`}>Premium</p>
|
||||||
|
<ul className="hidden md:block">
|
||||||
|
{lorem_ipsum_premium.map((lorem_ipsum) =>
|
||||||
|
(<li className="text-sm lista-outside mx-8 text-justify list-inside">{lorem_ipsum}</li>)
|
||||||
|
)}
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid pt-32 items-center justify-center">
|
</div>
|
||||||
|
<div className="w-full">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={nextStep}
|
onClick={nextStep}
|
||||||
className="h-12 w-72 rounded-xl bg-gray-700
|
className="absolute inset-x-0 md:-left-4 bottom-[4rem] mx-auto h-12 w-72 rounded-xl bg-gray-700
|
||||||
font-poppins font-semibold text-[14px] text-white
|
font-poppins font-semibold text-[14px] text-white
|
||||||
hover:scale-125 duration-300"
|
hover:scale-125 duration-300"
|
||||||
>
|
>
|
||||||
Przejdź do następnego kroku
|
Przejdź do następnego kroku
|
||||||
<span className="text-[18px]">→</span>{" "}
|
<span className="text-[18px]">→</span>{" "}
|
||||||
</button>
|
</button>
|
||||||
<div className="h-12 w-full"></div>
|
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import propTypes from 'prop-types';
|
import propTypes from 'prop-types';
|
||||||
|
import MaximumLength from '@ckeditor/ckeditor5-react'
|
||||||
import { categories, experience_levels } from '../consts';
|
import { categories, experience_levels } from '../consts';
|
||||||
import styles from '../style'
|
import styles from '../style'
|
||||||
import { CKEditor } from '@ckeditor/ckeditor5-react';
|
import { CKEditor } from '@ckeditor/ckeditor5-react';
|
||||||
@ -17,7 +17,7 @@ const StepTwoJoblisting = ({ nextStep, prevStep, handleChange, formData, setForm
|
|||||||
const data = editor.getData();
|
const data = editor.getData();
|
||||||
setEditorData(data);
|
setEditorData(data);
|
||||||
}
|
}
|
||||||
|
const max_char = 600;
|
||||||
const handleNextStep = () => {
|
const handleNextStep = () => {
|
||||||
if (validateForm()) {
|
if (validateForm()) {
|
||||||
console.log(errors)
|
console.log(errors)
|
||||||
@ -137,6 +137,16 @@ const StepTwoJoblisting = ({ nextStep, prevStep, handleChange, formData, setForm
|
|||||||
editor={ClassicEditor}
|
editor={ClassicEditor}
|
||||||
data={formData['content'] || ''}
|
data={formData['content'] || ''}
|
||||||
required
|
required
|
||||||
|
// config={{
|
||||||
|
// plugins: [WordCount],
|
||||||
|
// toolbar: ['wordCount'],
|
||||||
|
// wordCount: {
|
||||||
|
// onUpdate: stats => {
|
||||||
|
// console.log(stats.words, stats.characters)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// }}
|
||||||
onChange={(event, editor) => {
|
onChange={(event, editor) => {
|
||||||
const data = editor.getData();
|
const data = editor.getData();
|
||||||
handleChange('content')(data); // Wywołanie zmodyfikowanej funkcji handleChange
|
handleChange('content')(data); // Wywołanie zmodyfikowanej funkcji handleChange
|
||||||
@ -205,11 +215,11 @@ const StepTwoJoblisting = ({ nextStep, prevStep, handleChange, formData, setForm
|
|||||||
formData={formData}/>
|
formData={formData}/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={`${styles.flexCenter} p-20 gap-20`}>
|
<div className={`${styles.flexCenter} py-10 gap-20`}>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={prevStep}
|
onClick={prevStep}
|
||||||
className='h-12 w-72 rounded-xl bg-gray-700
|
className='h-16 md:h-12 w-80 md:w-72 rounded-xl bg-gray-700
|
||||||
font-poppins font-semibold text-[14px] scale-100
|
font-poppins font-semibold text-[14px] scale-100
|
||||||
text-white hover:scale-125 duration-300'>
|
text-white hover:scale-125 duration-300'>
|
||||||
<span className='text-[18px]'>←</span>
|
<span className='text-[18px]'>←</span>
|
||||||
@ -217,7 +227,7 @@ const StepTwoJoblisting = ({ nextStep, prevStep, handleChange, formData, setForm
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={handleNextStep}
|
onClick={handleNextStep}
|
||||||
className='h-12 w-72 rounded-xl
|
className='h-16 md:h-12 w-80 md:w-72 rounded-xl
|
||||||
bg-gray-700 font-poppins
|
bg-gray-700 font-poppins
|
||||||
font-semibold text-[14px] scale-100
|
font-semibold text-[14px] scale-100
|
||||||
text-white hover:scale-125 duration-300'>
|
text-white hover:scale-125 duration-300'>
|
||||||
|
|||||||
@ -96,9 +96,21 @@ const WorkApp = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const [searchQuery, setSearchQuery] = useState({});
|
const [searchQuery, setSearchQuery] = useState({
|
||||||
|
min_salary: '',
|
||||||
|
max_salary: '',
|
||||||
|
categories: [],
|
||||||
|
name: ''
|
||||||
|
});
|
||||||
const clearSearchQuery = () => {
|
const clearSearchQuery = () => {
|
||||||
setSearchQuery({});
|
setSearchQuery({
|
||||||
|
min_salary: '',
|
||||||
|
max_salary: '',
|
||||||
|
categories: [],
|
||||||
|
name: ''
|
||||||
|
});
|
||||||
|
getSkills();
|
||||||
|
setIsOpen(!isOpen)
|
||||||
};
|
};
|
||||||
|
|
||||||
const [selectedOgloszenie, setSelectedOgloszenie] = useState(ogloszenia[0]);
|
const [selectedOgloszenie, setSelectedOgloszenie] = useState(ogloszenia[0]);
|
||||||
@ -144,13 +156,11 @@ const WorkApp = () => {
|
|||||||
<div
|
<div
|
||||||
className={`relative bg-gray-100 w-full sm:w-[40%]
|
className={`relative bg-gray-100 w-full sm:w-[40%]
|
||||||
${isOpen ? 'h-[100vh] overflow-y-hidden' : 'sm:overflow-y-auto'}
|
${isOpen ? 'h-[100vh] overflow-y-hidden' : 'sm:overflow-y-auto'}
|
||||||
sm:h-[89vh] ${
|
sm:h-[89vh] ${isDetailsVisible ? "hidden sm:block" : "block" }`}
|
||||||
isDetailsVisible ? "hidden sm:block" : "block"
|
|
||||||
} `}
|
|
||||||
>
|
>
|
||||||
<div className="z-10 sticky top-[70px] sm:top-0 w-[100vw] sm:w-full">
|
<div className="z-10 sticky top-[70px] sm:top-0 w-[100vw] sm:w-full">
|
||||||
<div className="z-10 w-full fixed sm:sticky top-[4.4rem] sm:top-0 min-h-fit bg-slate-300 flex items-center place-content-center py-1 sm:py-2">
|
<div className="z-10 w-full fixed sm:sticky top-[4.4rem] sm:top-0 min-h-fit bg-slate-300 flex items-center place-content-center py-1 sm:py-2">
|
||||||
<h1 className="text-center text-xl sm:text-2xl font-poppins font-semibold text-slate-800 py-2 mx-6">
|
<h1 className="text-center text-xl sm:text-l md:text-2xl font-poppins font-semibold text-slate-800 py-2 mx-2">
|
||||||
Oferty pracy
|
Oferty pracy
|
||||||
</h1>
|
</h1>
|
||||||
<button
|
<button
|
||||||
|
|||||||
@ -326,4 +326,35 @@ export const employment_types = [
|
|||||||
"id": "INT",
|
"id": "INT",
|
||||||
"name": "Staż",
|
"name": "Staż",
|
||||||
},
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
export const lorem_ipsum = [
|
||||||
|
"Lorem ipsum dolor sit amet",
|
||||||
|
"consectetur adipiscing elit",
|
||||||
|
"sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. ",
|
||||||
|
"Ut enim ad minim veniam",
|
||||||
|
"quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. ",
|
||||||
|
'Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. ',
|
||||||
|
"Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
|
||||||
|
]
|
||||||
|
|
||||||
|
export const lorem_ipsum_starter = [
|
||||||
|
"Lorem ipsum dolor sit amet",
|
||||||
|
"consectetur adipiscing elit",
|
||||||
|
"sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. ",
|
||||||
|
"Ut enim ad minim veniam",
|
||||||
|
"quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. ",
|
||||||
|
]
|
||||||
|
|
||||||
|
export const lorem_ipsum_premium = [
|
||||||
|
"Lorem ipsum dolor sit amet",
|
||||||
|
"consectetur adipiscing elit",
|
||||||
|
"sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. ",
|
||||||
|
"Ut enim ad minim veniam",
|
||||||
|
"quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. ",
|
||||||
|
'Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. ',
|
||||||
|
"Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
|
||||||
|
"sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. ",
|
||||||
|
"Ut enim ad minim veniam",
|
||||||
|
"quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. ",
|
||||||
]
|
]
|
||||||
150
src/index.css
150
src/index.css
@ -154,6 +154,10 @@ input[type="number"] {
|
|||||||
list-style: inside;
|
list-style: inside;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.lista-outside {
|
||||||
|
list-style: outside;
|
||||||
|
}
|
||||||
|
|
||||||
.sidebar-show {
|
.sidebar-show {
|
||||||
-webkit-animation: slide-top 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;
|
-webkit-animation: slide-top 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;
|
||||||
animation: slide-top 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;
|
animation: slide-top 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;
|
||||||
@ -162,4 +166,148 @@ input[type="number"] {
|
|||||||
.sidebar-hide {
|
.sidebar-hide {
|
||||||
-webkit-animation: slide-down 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;
|
-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;
|
animation: slide-down 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.slider-wrapper {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.slider__track,
|
||||||
|
.slider__range,
|
||||||
|
.slider__left-value,
|
||||||
|
.slider__right-value {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider__track,
|
||||||
|
.slider__range {
|
||||||
|
border-radius: 3px;
|
||||||
|
max-width: 100%;
|
||||||
|
width: 100%;
|
||||||
|
height: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider__track {
|
||||||
|
background-color: #ced4da;
|
||||||
|
width: 100;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider__range {
|
||||||
|
background-color: #9fe5e1;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider__left-value,
|
||||||
|
.slider__right-value {
|
||||||
|
color: #dee2e6;
|
||||||
|
font-size: 12px;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider__left-value {
|
||||||
|
left: 6px;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider__right-value {
|
||||||
|
right: -4px;
|
||||||
|
color: black;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Removing the default appearance */
|
||||||
|
.thumb,
|
||||||
|
.thumb::-webkit-slider-thumb {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumb {
|
||||||
|
pointer-events: none;
|
||||||
|
position: absolute;
|
||||||
|
height: 0;
|
||||||
|
outline: none;
|
||||||
|
transition-duration: 0.5s;
|
||||||
|
transition-property: display;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumb--left {
|
||||||
|
z-index: 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumb--right {
|
||||||
|
z-index: 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For Chrome browsers */
|
||||||
|
.thumb::-webkit-slider-thumb {
|
||||||
|
background-color: #f1f5f7;
|
||||||
|
border: none;
|
||||||
|
border-radius: 50%;
|
||||||
|
box-shadow: 0 0 1px 1px #ced4da;
|
||||||
|
cursor: pointer;
|
||||||
|
height: 18px;
|
||||||
|
width: 18px;
|
||||||
|
margin-top: 4px;
|
||||||
|
pointer-events: all;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For Firefox browsers */
|
||||||
|
.thumb::-moz-range-thumb {
|
||||||
|
background-color: #f1f5f7;
|
||||||
|
border: none;
|
||||||
|
border-radius: 50%;
|
||||||
|
box-shadow: 0 0 1px 1px #ced4da;
|
||||||
|
cursor: pointer;
|
||||||
|
height: 18px;
|
||||||
|
width: 18px;
|
||||||
|
margin-top: 4px;
|
||||||
|
pointer-events: all;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@-webkit-keyframes fadeIn {
|
||||||
|
from { opacity: 0; }
|
||||||
|
to { opacity: 1; }
|
||||||
|
}
|
||||||
|
@keyframes fadeIn {
|
||||||
|
from { opacity: 0; }
|
||||||
|
to { opacity: 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumb--animatedin {
|
||||||
|
animation: fadeIn 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@-webkit-keyframes fadeOut {
|
||||||
|
from { opacity: 1; }
|
||||||
|
to { opacity: 0; }
|
||||||
|
}
|
||||||
|
@keyframes fadeOut {
|
||||||
|
from { opacity: 1; }
|
||||||
|
to { opacity: 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumb--animatedout {
|
||||||
|
animation: fadeOut 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.t-width {
|
||||||
|
width: 84%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-width {
|
||||||
|
width: 16rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user