add page functionality
This commit is contained in:
69
kivi-cars/package-lock.json
generated
69
kivi-cars/package-lock.json
generated
@@ -11,9 +11,9 @@
|
||||
"@testing-library/jest-dom": "^5.16.2",
|
||||
"@testing-library/react": "^12.1.3",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"nouislider": "^15.5.1",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-router-dom": "^6.2.2",
|
||||
"react-scripts": "5.0.0",
|
||||
"web-vitals": "^2.1.4"
|
||||
}
|
||||
@@ -7983,6 +7983,14 @@
|
||||
"he": "bin/he"
|
||||
}
|
||||
},
|
||||
"node_modules/history": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/history/-/history-5.3.0.tgz",
|
||||
"integrity": "sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.7.6"
|
||||
}
|
||||
},
|
||||
"node_modules/hoopy": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz",
|
||||
@@ -11157,11 +11165,6 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/nouislider": {
|
||||
"version": "15.5.1",
|
||||
"resolved": "https://registry.npmjs.org/nouislider/-/nouislider-15.5.1.tgz",
|
||||
"integrity": "sha512-V8LNPhLPXLNjkgXLfyzDRGDeKvzZeaiIx5YagMiHnOMqgcRzT75jqvEZYXbSrEffXouwcEShSd8Vllm2Nkwqew=="
|
||||
},
|
||||
"node_modules/npm-run-path": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
|
||||
@@ -13182,6 +13185,30 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-router": {
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.2.2.tgz",
|
||||
"integrity": "sha512-/MbxyLzd7Q7amp4gDOGaYvXwhEojkJD5BtExkuKmj39VEE0m3l/zipf6h2WIB2jyAO0lI6NGETh4RDcktRm4AQ==",
|
||||
"dependencies": {
|
||||
"history": "^5.2.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8"
|
||||
}
|
||||
},
|
||||
"node_modules/react-router-dom": {
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.2.2.tgz",
|
||||
"integrity": "sha512-AtYEsAST7bDD4dLSQHDnk/qxWLJdad5t1HFa1qJyUrCeGgEuCSw0VB/27ARbF9Fi/W5598ujvJOm3ujUCVzuYQ==",
|
||||
"dependencies": {
|
||||
"history": "^5.2.0",
|
||||
"react-router": "6.2.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8",
|
||||
"react-dom": ">=16.8"
|
||||
}
|
||||
},
|
||||
"node_modules/react-scripts": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.0.tgz",
|
||||
@@ -21738,6 +21765,14 @@
|
||||
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
|
||||
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw=="
|
||||
},
|
||||
"history": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/history/-/history-5.3.0.tgz",
|
||||
"integrity": "sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.7.6"
|
||||
}
|
||||
},
|
||||
"hoopy": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz",
|
||||
@@ -24027,11 +24062,6 @@
|
||||
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz",
|
||||
"integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A=="
|
||||
},
|
||||
"nouislider": {
|
||||
"version": "15.5.1",
|
||||
"resolved": "https://registry.npmjs.org/nouislider/-/nouislider-15.5.1.tgz",
|
||||
"integrity": "sha512-V8LNPhLPXLNjkgXLfyzDRGDeKvzZeaiIx5YagMiHnOMqgcRzT75jqvEZYXbSrEffXouwcEShSd8Vllm2Nkwqew=="
|
||||
},
|
||||
"npm-run-path": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
|
||||
@@ -25368,6 +25398,23 @@
|
||||
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz",
|
||||
"integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A=="
|
||||
},
|
||||
"react-router": {
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.2.2.tgz",
|
||||
"integrity": "sha512-/MbxyLzd7Q7amp4gDOGaYvXwhEojkJD5BtExkuKmj39VEE0m3l/zipf6h2WIB2jyAO0lI6NGETh4RDcktRm4AQ==",
|
||||
"requires": {
|
||||
"history": "^5.2.0"
|
||||
}
|
||||
},
|
||||
"react-router-dom": {
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.2.2.tgz",
|
||||
"integrity": "sha512-AtYEsAST7bDD4dLSQHDnk/qxWLJdad5t1HFa1qJyUrCeGgEuCSw0VB/27ARbF9Fi/W5598ujvJOm3ujUCVzuYQ==",
|
||||
"requires": {
|
||||
"history": "^5.2.0",
|
||||
"react-router": "6.2.2"
|
||||
}
|
||||
},
|
||||
"react-scripts": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.0.tgz",
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-router-dom": "^6.2.2",
|
||||
"react-scripts": "5.0.0",
|
||||
"web-vitals": "^2.1.4"
|
||||
},
|
||||
|
||||
@@ -1,10 +1,20 @@
|
||||
import './button.css'
|
||||
|
||||
const StandardBtn = (props) => {
|
||||
|
||||
const {filtersData, setFiltersData, filter} = props.data
|
||||
|
||||
const clickHandler = ( e ) => {
|
||||
setFiltersData(prevData => ({
|
||||
...prevData,
|
||||
[e.target.name]: e.target.value
|
||||
}))
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='standard-btn'>
|
||||
|
||||
<button className='standardBtn'>{props.title}</button>
|
||||
<button name={filter} value={props.title} className='standardBtn' onClick={e => clickHandler(e)}>{props.title}</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
13
kivi-cars/src/components/Button/TitleBtn.js
Normal file
13
kivi-cars/src/components/Button/TitleBtn.js
Normal file
@@ -0,0 +1,13 @@
|
||||
import './button.css'
|
||||
|
||||
const StandardBtn = (props) => {
|
||||
|
||||
return (
|
||||
<div className='standard-btn'>
|
||||
|
||||
<button value={props.title} className='standardBtn'>{props.title}</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default StandardBtn
|
||||
@@ -1,4 +1,5 @@
|
||||
import './ButtonsToolbar.css';
|
||||
import { Link } from 'react-router-dom'
|
||||
import ArrowLeft from '../Button/leftBtn';
|
||||
import ArrowRigh from '../Button/rightBtn';
|
||||
|
||||
@@ -7,10 +8,15 @@ const ButtonsToolbar = (props) => {
|
||||
return (
|
||||
<div className='buttons-toolbar'>
|
||||
<div className='left-group'>
|
||||
<ArrowLeft />
|
||||
<Link to={`${props.routes.prev}`}>
|
||||
<ArrowLeft />
|
||||
</Link>
|
||||
</div>
|
||||
<div className='right-group'>
|
||||
<ArrowRigh/>
|
||||
<Link to={`${props.routes.next}`}>
|
||||
<ArrowRigh/>
|
||||
</Link>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -1,16 +1,25 @@
|
||||
import './categorybtns.css'
|
||||
import StandardBtn from '../Button/StandardBtn'
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
var auto = 'AUTO';
|
||||
var motor = 'MOTOR';
|
||||
var kamion = 'KAMION';
|
||||
|
||||
const CategoryBtns = (props) => {
|
||||
|
||||
let auto = 'Auto';
|
||||
let motor = 'Motor';
|
||||
let kamion = 'Kamion';
|
||||
let filter = 'Vozilo'
|
||||
|
||||
const {filtersData, setFiltersData} = props.data;
|
||||
|
||||
return (
|
||||
<div className='category-btns'>
|
||||
<StandardBtn title={auto}/>
|
||||
<StandardBtn title={motor}/>
|
||||
<StandardBtn title={kamion}/>
|
||||
<Link to='/filters'>
|
||||
<StandardBtn title={auto} data={{filtersData, setFiltersData, filter}}/>
|
||||
</Link>
|
||||
|
||||
<StandardBtn title={motor} data={{filtersData, setFiltersData}}/>
|
||||
<StandardBtn title={kamion} data={{filtersData, setFiltersData}}/>
|
||||
</div>
|
||||
)
|
||||
|
||||
|
||||
@@ -1,12 +1,45 @@
|
||||
import React from "react";
|
||||
import "./Filters.css";
|
||||
import Cars from "../../data/cars";
|
||||
import Filter from "./Filter/Filter";
|
||||
import Color from '../../data/color';
|
||||
import AirCondition from "../../data/air-condition";
|
||||
import Seats from "../../data/seats";
|
||||
import Sensors from "../../data/sensors";
|
||||
import Gearbox from "../../data/gearbox";
|
||||
import Lights from "../../data/lights";
|
||||
import Checkbox from "./Filter/Checkbox";
|
||||
import CheckBox from "../../data/checkbox";
|
||||
|
||||
|
||||
const AdvancedFilters = (props) => {
|
||||
|
||||
const {filtersData, setFiltersData} = props.data
|
||||
const data = [Color, AirCondition, Seats, Gearbox, Sensors, Lights]
|
||||
let index = 0
|
||||
|
||||
const AdvancedFilters = () => {
|
||||
|
||||
return(
|
||||
<div className="filters-container">
|
||||
|
||||
<div className="filters-content">
|
||||
{
|
||||
data.map(item => {
|
||||
index += 1;
|
||||
return(
|
||||
<Filter key={index} ime={item.ime} tipovi={item.tipovi} data={{filtersData, setFiltersData}}/>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
<div className="checkbox-content">
|
||||
{
|
||||
CheckBox.map(item => {
|
||||
index += 1;
|
||||
return(
|
||||
<Checkbox key={index} title={item} data={{filtersData, setFiltersData}}/>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
24
kivi-cars/src/components/Filters/Filter/Checkbox.css
Normal file
24
kivi-cars/src/components/Filters/Filter/Checkbox.css
Normal file
@@ -0,0 +1,24 @@
|
||||
*{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.checkbox-div{
|
||||
padding: 0.5em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.checkbox-title{
|
||||
margin-right: 0.5em
|
||||
}
|
||||
|
||||
.checkbox{
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 541px){
|
||||
.checkbox-div{
|
||||
font-size: 1.5em;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import './Checkbox.css';
|
||||
|
||||
const Checkbox = (props) => {
|
||||
|
||||
|
||||
const {filtersData, setFiltersData} = props.data
|
||||
const [isChecked, setIsChecked] = useState(false)
|
||||
|
||||
|
||||
const changeHandler = ( event ) => {
|
||||
setFiltersData(prevData => ({
|
||||
...prevData,
|
||||
[event.target.name]: isChecked
|
||||
}))
|
||||
}
|
||||
|
||||
return(
|
||||
<div className="checkbox-div">
|
||||
<label className="checkbox-title" htmlFor={`${props.title}`}>{props.title}</label>
|
||||
<input type="checkbox" name={props.title} className="checkbox" id={`${props.title}`} onChange={(e) => {changeHandler(e); setIsChecked(!isChecked)}}/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Checkbox;
|
||||
@@ -1,19 +1,37 @@
|
||||
import React from "react";
|
||||
import React, {useEffect, useState} from "react";
|
||||
import "./DoubleFilter.css";
|
||||
|
||||
const DoubleFilter = (props) => {
|
||||
|
||||
const defaultV = 0
|
||||
const {filtersData, setFiltersData} = props.data
|
||||
const [doubleFilterData, setDoubleFilterData] = useState({})
|
||||
|
||||
const changeHandler = ( e ) => {
|
||||
setDoubleFilterData(prevData => ({
|
||||
...prevData,
|
||||
[e.target.name]: e.target.value
|
||||
}))
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
setFiltersData(prevData => ({
|
||||
...prevData,
|
||||
[props.title]: doubleFilterData
|
||||
}))
|
||||
}, [doubleFilterData])
|
||||
|
||||
return (
|
||||
<div className="doubleFilter-component">
|
||||
<label htmlFor="filters-div">{props.title}</label>
|
||||
<div className="double-filters" id="filters-div">
|
||||
<div className="filter">
|
||||
<label htmlFor="od" className="filter-info">Od</label>
|
||||
<input placeholder="Unesite" id="od" className="filter-number" defaultValue={props.fields.default} type="number" min={props.fields.min} max={props.fields.max} step={props.fields.step} />
|
||||
<input placeholder="Unesite" id="od" name="Od" className="filter-number" type="number" min={props.fields.min} max={props.fields.max} onChange={(e) => changeHandler(e)}/>
|
||||
</div>
|
||||
<div className="filter">
|
||||
<label htmlFor="do" className="filter-info">Do</label>
|
||||
<input placeholder="Unesite" id="do" className="filter-number" defaultValue={props.fields.default} type="number" min={props.fields.min} max={props.fields.max} step={props.fields.step} />
|
||||
<input placeholder="Unesite" id="do" name="Do" className="filter-number" type="number" max={props.fields.max} onChange={(e) => changeHandler(e)}/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,13 +2,23 @@ import React from "react";
|
||||
import './Filter.css';
|
||||
|
||||
const Filter = (props) => {
|
||||
|
||||
const {filtersData, setFiltersData} = props.data
|
||||
|
||||
const changeHandler = ( event ) => {
|
||||
setFiltersData(prevData => ({
|
||||
...prevData,
|
||||
[event.target.name]: event.target.value
|
||||
}))
|
||||
}
|
||||
|
||||
return(
|
||||
<div className="filter-component">
|
||||
<label htmlFor={props.ime} className="filter-name">{props.ime}</label>
|
||||
<select className="dropdown-list" name={props.ime} id={props.ime}>
|
||||
<select className="dropdown-list" name={props.ime} id={props.ime} onChange={(event) => changeHandler(event)}>
|
||||
{props.tipovi.map((tip, i) => {
|
||||
return (
|
||||
<option key={i} value={tip}>{tip}</option>
|
||||
<option key={i} value={tip} name={tip}>{tip}</option>
|
||||
)
|
||||
})}
|
||||
</select>
|
||||
|
||||
@@ -12,5 +12,36 @@
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.filters-content{
|
||||
padding: 2em;
|
||||
width: 90%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-evenly;
|
||||
border-bottom: 2px solid #02adba;
|
||||
}
|
||||
|
||||
.checkbox-content{
|
||||
padding: 2em 0.5em;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 541px){
|
||||
.filters-content{
|
||||
padding: 2em 5em;
|
||||
}
|
||||
|
||||
.checkbox-content{
|
||||
width: ;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import React from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import "./Filters.css";
|
||||
import Filter from "./Filter/Filter";
|
||||
import DoubleFilter from "./Filter/DoubleFilter";
|
||||
import Cars from "../../data/cars";
|
||||
import Cubes from "../../data/cubes";
|
||||
import Type from "../../data/type";
|
||||
@@ -8,63 +10,69 @@ import Transmission from "../../data/transmission";
|
||||
import Drive from "../../data/drive";
|
||||
import Condition from "../../data/condition";
|
||||
import Doors from "../../data/doors";
|
||||
import Filter from "./Filter/Filter";
|
||||
import DoubleFilter from "./Filter/DoubleFilter";
|
||||
import Year from "../../data/year";
|
||||
import Price from "../../data/price";
|
||||
import HorsePower from "../../data/horsepower";
|
||||
import Kilowats from "../../data/kilowats";
|
||||
import Kilometers from "../../data/kilometers";
|
||||
|
||||
const StandardFilters = () => {
|
||||
const StandardFilters = (props) => {
|
||||
|
||||
let brand_index = 5
|
||||
let index = 0
|
||||
const {filtersData, setFiltersData} = props.data;
|
||||
const [brandIndex, setBrandIndex] = useState(0);
|
||||
let index = 0;
|
||||
|
||||
const brands = Cars.map(brand => {
|
||||
return brand.brand
|
||||
})
|
||||
|
||||
const models = Cars[brand_index].models
|
||||
useEffect(() => {
|
||||
if(filtersData.Marka)setBrandIndex(brands.indexOf(filtersData.Marka))
|
||||
}, [filtersData])
|
||||
|
||||
const models = Cars[brandIndex].models
|
||||
|
||||
const Brands = {
|
||||
"ime": "Marka",
|
||||
"tipovi": ["Odaberite", ...brands]
|
||||
"tipovi": brands
|
||||
}
|
||||
|
||||
const Models = {
|
||||
"ime": "Modeli",
|
||||
"tipovi": ["Odaberite", ...models]
|
||||
"ime": "Model",
|
||||
"tipovi": models
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
const data = [Fuel, Type]
|
||||
const data1 = [Transmission, Drive, Condition, Doors]
|
||||
const data2 = [Price, Year, Cubes, HorsePower, Kilowats]
|
||||
const data2 = [Price, Year, Kilometers, Cubes, HorsePower, Kilowats]
|
||||
|
||||
|
||||
return(
|
||||
<div className="filters-container">
|
||||
<Filter ime={Brands.ime} tipovi={Brands.tipovi} />
|
||||
<Filter ime={Models.ime} tipovi={Models.tipovi} />
|
||||
<Filter ime={Brands.ime} tipovi={Brands.tipovi} data={{filtersData, setFiltersData}}/>
|
||||
<Filter ime={Models.ime} tipovi={Models.tipovi} data={{filtersData, setFiltersData}}/>
|
||||
|
||||
{data.map(item => {
|
||||
index += 1;
|
||||
return(
|
||||
<Filter key={index} ime={item.ime} tipovi={item.tipovi}/>
|
||||
<Filter key={index} ime={item.ime} tipovi={item.tipovi} data={{filtersData, setFiltersData}}/>
|
||||
)
|
||||
})}
|
||||
|
||||
{data2.map(item => {
|
||||
index += 1;
|
||||
return(
|
||||
<DoubleFilter key={index} title={item.title} fields={item.fields} />
|
||||
<DoubleFilter key={index} title={item.title} fields={item.fields} data={{filtersData, setFiltersData}}/>
|
||||
)
|
||||
})}
|
||||
|
||||
{data1.map(item => {
|
||||
index += 1;
|
||||
return(
|
||||
<Filter key={index} ime={item.ime} tipovi={item.tipovi}/>
|
||||
<Filter key={index} ime={item.ime} tipovi={item.tipovi} data={{filtersData, setFiltersData}}/>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
|
||||
.links-container{
|
||||
background-color: #fff;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.filters-links{
|
||||
22
kivi-cars/src/components/FiltersNavbar/FiltersNav.js
Normal file
22
kivi-cars/src/components/FiltersNavbar/FiltersNav.js
Normal file
@@ -0,0 +1,22 @@
|
||||
import './FiltersNav.css';
|
||||
|
||||
const FiltersNav = (props) => {
|
||||
|
||||
const {toggle, setToggle} = props.toggle;
|
||||
|
||||
|
||||
return(
|
||||
<div className="links-container">
|
||||
<ul className="filters-links">
|
||||
<li className={toggle ? `filters-link active`: `filters-link`} onClick={() => setToggle(true)}>
|
||||
<a id="standard-filters" >Filteri</a>
|
||||
</li>
|
||||
<li className={!toggle ? `filters-link active`: `filters-link`} onClick={() => setToggle(false)}>
|
||||
<a id="advanced-filters" >Napredni filteri</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default FiltersNav;
|
||||
@@ -11,6 +11,7 @@ header {
|
||||
resize: both;
|
||||
padding: 20px;
|
||||
font-size: 25px;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 700px) {
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
import './FiltersNav.css';
|
||||
|
||||
const FiltersNav = () => {
|
||||
|
||||
|
||||
return(
|
||||
<div className="links-container">
|
||||
<ul className="filters-links">
|
||||
<li className="filters-link active">
|
||||
<a id="standard-filters">Filteri</a>
|
||||
</li>
|
||||
<li className="filters-link">
|
||||
<a id="advanced-filters">Napredni filteri</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default FiltersNav;
|
||||
@@ -1,14 +1,37 @@
|
||||
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
|
||||
import './css/App.css';
|
||||
import React from 'react';
|
||||
import { React, useEffect, useState } from 'react';
|
||||
import CategoryPage from './CategoryPage';
|
||||
import LandingPage from './LandingPage';
|
||||
import FiltersPage from './FiltersPage';
|
||||
import EmailPage from './EmailPage';
|
||||
import CongratsPage from './CongratsPage';
|
||||
import LinkR from '../data/routes';
|
||||
|
||||
|
||||
function App() {
|
||||
|
||||
const info = 'Dobrodosli na stranicu kivi!'
|
||||
const [filtersData, setFiltersData] = useState({})
|
||||
|
||||
useEffect(() => {
|
||||
console.log(filtersData)
|
||||
}, [filtersData])
|
||||
|
||||
|
||||
return (
|
||||
<div className="App">
|
||||
{/* here import components */}
|
||||
<Router>
|
||||
<Routes>
|
||||
|
||||
<Route path='/' element={<LandingPage />} />
|
||||
<Route path='category' element={<CategoryPage data={{filtersData, setFiltersData}} routes={LinkR.category} />}/>
|
||||
<Route path='filters' element={<FiltersPage data={{filtersData, setFiltersData}} routes={LinkR.filters}/>}/>
|
||||
<Route path='email' element={<EmailPage data={{filtersData, setFiltersData}} routes={LinkR.email} />}/>
|
||||
<Route path='congrats' element={<CongratsPage data={{filtersData, setFiltersData}} routes={LinkR.congrats} />}/>
|
||||
|
||||
</Routes>
|
||||
</Router>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,16 +3,17 @@ import ButtonsToolbar from '../components/ButtonsToolbar/ButtonsToolbar';
|
||||
import CategoryBtns from '../components/CategoryBtns/categorybtns'
|
||||
import './css/CategoryPage.css'
|
||||
|
||||
function CategoryPage() {
|
||||
function CategoryPage(props) {
|
||||
|
||||
const {filtersData, setFiltersData} = props.data
|
||||
|
||||
const naslov = 'IZABERITE KATEGORIJU'
|
||||
|
||||
return (
|
||||
<div className="category">
|
||||
<Header header={naslov}/>
|
||||
<ButtonsToolbar/>
|
||||
<ButtonsToolbar routes={props.routes}/>
|
||||
<div className='category-buttons'>
|
||||
<CategoryBtns/>
|
||||
<CategoryBtns data={{filtersData, setFiltersData}}/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import Header from '../components/Header/Header';
|
||||
import StandardBtn from '../components/Button/StandardBtn';
|
||||
import TitleBtn from '../components/Button/TitleBtn';
|
||||
import './css/CongratsPage.css'
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
function CongratsPage() {
|
||||
|
||||
@@ -10,7 +12,7 @@ function CongratsPage() {
|
||||
return (
|
||||
<div className="congrats-page">
|
||||
<Header header={naslov}/>
|
||||
<div>
|
||||
<div className='paragh-div'>
|
||||
<div className='first-paragh'>
|
||||
<h2 className='h2'>ČESTITAMO! Potvrđeni email je poslat na vašu email adresu.</h2>
|
||||
</div>
|
||||
@@ -21,7 +23,10 @@ function CongratsPage() {
|
||||
<h1 className='h1'>Ako želite novu pretragu idete na</h1>
|
||||
</div>
|
||||
|
||||
<StandardBtn title={btnTitle}/>
|
||||
<Link to='/'>
|
||||
<TitleBtn title={btnTitle}/>
|
||||
</Link>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
3
kivi-cars/src/containers/DataContext.js
Normal file
3
kivi-cars/src/containers/DataContext.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import {createContext} from 'react';
|
||||
|
||||
|
||||
@@ -1,31 +1,74 @@
|
||||
import {useContext, useState, useEffect} from 'react';
|
||||
import { DataContext } from './DataContext';
|
||||
import './css/EmailPage.css'
|
||||
import Header from '../components/Header/Header';
|
||||
import ButtonsToolbar from '../components/ButtonsToolbar/ButtonsToolbar';
|
||||
import StandardBtn from '../components/Button/StandardBtn';
|
||||
import TitleBtn from '../components/Button/TitleBtn';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
|
||||
function EmailPage(props) {
|
||||
|
||||
const {filtersData, setFiltersData} = props.data
|
||||
const [error, setError] = useState(false)
|
||||
|
||||
|
||||
const [state, setState] = useState({
|
||||
email: "",
|
||||
confirmEmail: ""
|
||||
})
|
||||
|
||||
const header = "SLANJE OBAVJEŠTENJA";
|
||||
var title1 = 'Odmah';
|
||||
var title2 = 'Dnevno';
|
||||
var title3 = 'ZAVRŠI';
|
||||
let title1 = 'Odmah';
|
||||
let title2 = 'Dnevno';
|
||||
let title3 = 'ZAVRŠI';
|
||||
let errmsg = 'Email does not match!';
|
||||
let filter = 'Slanje'
|
||||
|
||||
|
||||
const emailCheck = (e, ec) => {
|
||||
if(e !== "" && e === ec){
|
||||
setError(false)
|
||||
setFiltersData(prevData => ({
|
||||
...prevData,
|
||||
"email": state.email
|
||||
}))
|
||||
return error
|
||||
}else {
|
||||
setError(true)
|
||||
return error
|
||||
}
|
||||
}
|
||||
|
||||
const updateInput = (event) => {
|
||||
setState(prevState => ({
|
||||
...prevState,
|
||||
[event.target.name]: event.target.value
|
||||
}))
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
emailCheck(state.email, state.confirmEmail)
|
||||
}, [state])
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Header header={header}/>
|
||||
<ButtonsToolbar/>
|
||||
<div>
|
||||
<ButtonsToolbar routes={props.routes}/>
|
||||
<div className="info">
|
||||
<h2 className='h2'>Slanje obavještenja</h2>
|
||||
</div>
|
||||
<div className='buttons-container'>
|
||||
<StandardBtn title={title1}/>
|
||||
<StandardBtn title={title2}/>
|
||||
<StandardBtn data={{filtersData, setFiltersData, filter}} title={title1}/>
|
||||
<StandardBtn data={{filtersData, setFiltersData, filter}} title={title2}/>
|
||||
</div>
|
||||
<div className='form'>
|
||||
<form method="POST" id="form-email">
|
||||
<div className='email-div'>
|
||||
<input id="email" name='email' placeholder='vas.email@mail.com' required size='250'/>
|
||||
<input id="confirmEmail" name='confirmEmail' placeholder='potvrdite.email@mail.com' required size='250'/>
|
||||
<input type="email" id="email" name='email' placeholder='vas.email@mail.com' required size='250' onChange={updateInput} />
|
||||
<input type="email" id="confirmEmail" name='confirmEmail' placeholder='potvrdite.email@mail.com' required size='250' onChange={updateInput} />
|
||||
<p style={{color: "red"}} >{error ? errmsg : null}</p>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
@@ -36,7 +79,11 @@ function EmailPage(props) {
|
||||
</h3>
|
||||
</div>
|
||||
<div>
|
||||
<StandardBtn title={title3}/>
|
||||
{error ? (<TitleBtn title={title3} /> ) : (
|
||||
<Link to="/congrats">
|
||||
<TitleBtn title={title3} />
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,20 +1,30 @@
|
||||
import React from "react";
|
||||
import {React, useState} from "react";
|
||||
import './css/FiltersPage.css';
|
||||
import Header from "../components/Header/Header";
|
||||
import ButtonsToolbar from "../components/ButtonsToolbar/ButtonsToolbar";
|
||||
import FiltersNav from '../components/Searchfilters/FiltersNav'
|
||||
import FiltersNav from '../components/FiltersNavbar/FiltersNav'
|
||||
import StandardFilters from "../components/Filters/Standard-filters";
|
||||
import AdvancedFilters from "../components/Filters/Advanced-filters";
|
||||
|
||||
const FiltersPage = () => {
|
||||
const FiltersPage = (props) => {
|
||||
|
||||
const naslov = "Filteri za pretrazivanje"
|
||||
const [toggle, setToggle] = useState(true)
|
||||
const {filtersData, setFiltersData} = props.data
|
||||
|
||||
const showFilters = (toggle) => {
|
||||
if(toggle){
|
||||
return <StandardFilters data={{filtersData, setFiltersData}}/>
|
||||
}
|
||||
return <AdvancedFilters data={{filtersData, setFiltersData}}/>;
|
||||
}
|
||||
|
||||
return(
|
||||
<div className="FiltersPage">
|
||||
<Header header={naslov}/>
|
||||
<ButtonsToolbar />
|
||||
<FiltersNav />
|
||||
<StandardFilters />
|
||||
<ButtonsToolbar routes={props.routes}/>
|
||||
<FiltersNav toggle={{toggle, setToggle}}/>
|
||||
{showFilters(toggle)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import logo from '../assets/logo.png'
|
||||
import StandardBtn from '../components/Button/StandardBtn';
|
||||
import TitleBtn from '../components/Button/TitleBtn';
|
||||
import Header from '../components/Header/Header';
|
||||
import './css/LandingPage.css'
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
function LandingPage() {
|
||||
|
||||
@@ -21,7 +22,10 @@ function LandingPage() {
|
||||
<h2 id='besplatno'> BESPLATNO </h2>
|
||||
|
||||
</div>
|
||||
<StandardBtn title={naziv}/>
|
||||
<Link to='/category'>
|
||||
<TitleBtn title={naziv}/>
|
||||
</Link>
|
||||
|
||||
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
.paragh-div{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.first-paragh {
|
||||
padding-top: 20px;
|
||||
margin-top: 50px;
|
||||
|
||||
@@ -71,4 +71,8 @@ textarea:focus, input:focus{
|
||||
align-items: center;
|
||||
margin: auto;
|
||||
|
||||
}
|
||||
|
||||
.info{
|
||||
display: flex;
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
const AirCondition = {
|
||||
"ime" : "Klima",
|
||||
"tipovi" : [
|
||||
"Odaberite",
|
||||
"Jednozonska",
|
||||
"Dvozonska",
|
||||
"Trozonska",
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
const Cars = [
|
||||
{
|
||||
"brand": "Odaberite",
|
||||
"models": [
|
||||
"Odaberite marku "
|
||||
]
|
||||
},
|
||||
{
|
||||
"brand": "Acura",
|
||||
"models": [
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const Checkbox = [
|
||||
const CheckBox = [
|
||||
"ABS",
|
||||
"ESP",
|
||||
"Tempomat",
|
||||
@@ -12,11 +12,15 @@ const Checkbox = [
|
||||
"Daljinsko zaključavanje",
|
||||
"ISOFIX",
|
||||
"Registrovan",
|
||||
"Xenon",
|
||||
"LED",
|
||||
"Laser",
|
||||
"Električni podizači stakala",
|
||||
"Naslon za ruke",
|
||||
"Električni retrovizor",
|
||||
"Turbo",
|
||||
"Naslon za ruke",
|
||||
"Start/Stop",
|
||||
"Turbo",
|
||||
"Stranac",
|
||||
"Pakring assistent",
|
||||
"Senzor mrtvog ugla",
|
||||
"Servisna knjiga",
|
||||
@@ -26,12 +30,9 @@ const Checkbox = [
|
||||
"Masažna sjedišta",
|
||||
"Memorija sjedišta",
|
||||
"Panorama",
|
||||
"Xenon",
|
||||
"LED",
|
||||
"Laser",
|
||||
"Ocarinjen",
|
||||
"Udaren",
|
||||
"Stranac"
|
||||
|
||||
]
|
||||
|
||||
export default Checkbox;
|
||||
export default CheckBox;
|
||||
10
kivi-cars/src/data/kilometers.js
Normal file
10
kivi-cars/src/data/kilometers.js
Normal file
@@ -0,0 +1,10 @@
|
||||
const Kilometers = {
|
||||
"title": "Kilometraza",
|
||||
"fields": {
|
||||
"min": 0,
|
||||
"max": 1000000,
|
||||
"step": 1000
|
||||
}
|
||||
}
|
||||
|
||||
export default Kilometers;
|
||||
15
kivi-cars/src/data/routes.js
Normal file
15
kivi-cars/src/data/routes.js
Normal file
@@ -0,0 +1,15 @@
|
||||
const LinkR = {
|
||||
"category": {
|
||||
"prev": "/",
|
||||
"next": "/filters"
|
||||
},
|
||||
"filters": {
|
||||
"prev": "/category",
|
||||
"next": "/email"
|
||||
},
|
||||
"email": {
|
||||
"prev": "/filters",
|
||||
"next": "/congrats"
|
||||
}
|
||||
}
|
||||
export default LinkR;
|
||||
Reference in New Issue
Block a user