Browse Source

Scraper details

scraperSetails
Nikola Ignjatovic 4 years ago
parent
commit
1f534270a0

+ 23
- 0
package-lock.json View File

@@ -4617,6 +4617,11 @@
}
}
},
"classnames": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz",
"integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA=="
},
"clean-css": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz",
@@ -13928,6 +13933,14 @@
"scheduler": "^0.20.2"
}
},
"react-easy-swipe": {
"version": "0.0.21",
"resolved": "https://registry.npmjs.org/react-easy-swipe/-/react-easy-swipe-0.0.21.tgz",
"integrity": "sha512-OeR2jAxdoqUMHIn/nS9fgreI5hSpgGoL5ezdal4+oO7YSSgJR8ga+PkYGJrSrJ9MKlPcQjMQXnketrD7WNmNsg==",
"requires": {
"prop-types": "^15.5.8"
}
},
"react-error-overlay": {
"version": "6.0.9",
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.9.tgz",
@@ -14022,6 +14035,16 @@
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz",
"integrity": "sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg=="
},
"react-responsive-carousel": {
"version": "3.2.19",
"resolved": "https://registry.npmjs.org/react-responsive-carousel/-/react-responsive-carousel-3.2.19.tgz",
"integrity": "sha512-lOO6CscsxnQoNnrmLXNXu7u3U0znY44jGloX9Zayki9+OdUs63YXypSgV7dzaTmlem4SXy4rIXBR8+gjA9zyxg==",
"requires": {
"classnames": "^2.2.5",
"prop-types": "^15.5.8",
"react-easy-swipe": "^0.0.21"
}
},
"react-router": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-5.2.0.tgz",

+ 1
- 0
package.json View File

@@ -23,6 +23,7 @@
"react-helmet-async": "^1.0.9",
"react-i18next": "^11.10.0",
"react-redux": "^7.2.4",
"react-responsive-carousel": "^3.2.19",
"react-router-dom": "^5.2.0",
"react-scripts": "4.0.3",
"react-select": "^4.3.1",

+ 3
- 2
src/App.js View File

@@ -3,7 +3,8 @@ import { Router } from 'react-router-dom';
import { Helmet } from 'react-helmet-async';
import i18next from 'i18next';
import history from './store/utils/history';
import Header from './components/Header/Header';
//import Header from './components/Header/Header';
import "react-responsive-carousel/lib/styles/carousel.min.css";
// import Sidebar from './components/Sidebar/Sidebar';
import AppRoutes from './AppRoutes';

@@ -16,7 +17,7 @@ const App = () => (
</title>
</Helmet>
<>
<Header />
{/* <Header /> */}
{/* <Sidebar /> */}
<AppRoutes />
</>

+ 7
- 0
src/assets/styles/_custom.scss View File

@@ -8,4 +8,11 @@
.cursor-pointer
{
cursor: pointer;
}
a{
color: #007bff!important;
cursor: pointer;
}
h1{
font-size: 80px!important;
}

+ 130
- 0
src/components/CardApartments/CardApartments.js View File

@@ -0,0 +1,130 @@
import React from 'react';
import PropTypes from 'prop-types';
import getHours from '../../helpers/GetTodaysWorkingHours';
import './CardApartments.scss';

const CardApartments = ({result, index}) => {
const carouselId = "carouselExampleIndicators".concat(index);
const carouselIndicator = "#".concat(carouselId);
return(
<>
<div className="card">
<div className="card-body">
{result.lastUpdate !=undefined ?
<div className="ribbon-wrapper ribbon-lg">
<div className="ribbon bg-primary">
{result.lastUpdate}
</div>
</div> :''
}
<div className="row">
<div className="col-md-4">
<div id={carouselId} className="carousel slide" data-ride="carousel">
<ol className="carousel-indicators">
{result.images.map((image, i) =>
(image !== undefined && image.src !==undefined ?
i === 1 ?
<li data-target={carouselIndicator} data-slide-to={i} className="active"></li>
:
<li data-target={carouselIndicator} data-slide-to={i} className=""></li>
:""
))}
</ol>
<div className="carousel-inner">
{
result.images.map((image, i) =>
(image !== undefined && image.src !== undefined ?
i === 0 ?
<div className="carousel-item active" key={i} >
<img height="269px" className="d-block w-100"
src={image.src}
alt= {i} />
</div>
:
<div className="carousel-item" key={i} >
<img height="269px" className="d-block w-100"
src={image.src}
alt= {i} />
</div>
:'')
)
}
</div>
<a className="carousel-control-prev" href={carouselIndicator} role="button"
data-slide="prev">
<span className="carousel-control-custom-icon" aria-hidden="true">
<i className="fas fa-chevron-left"></i>
</span>
<span className="sr-only">Previous</span>
</a>
<a className="carousel-control-next" href={carouselIndicator} role="button"
data-slide="next">
<span className="carousel-control-custom-icon" aria-hidden="true">
<i className="fas fa-chevron-right"></i>
</span>
<span className="sr-only">Next</span>
</a>
</div>
</div>
<div className="col-md-8">
{result.name !== undefined ? <h2><a>{result.name}

</a>
{result.contact != undefined && result.contact.officeHours && getHours(result.contact.officeHours) !== null ? <span className="text-black-50 text-sm"><i className="fas fa-clock"></i> Open { getHours(result.contact.officeHours)} Today</span>: '' }
</h2>: ''}
{result.address != undefined ?
<p className="lead">
{result.address.street !== undefined ? <span> {result.address.street}, </span>:''}
{result.address.city !== undefined ? <span> {result.address.city}, </span>:''}
{result.address.zip !== undefined ? <span> {result.address.zip.code} {result.address.zip.state}</span>:''}
</p>
: ''}
{result.rentInfo !=undefined ? <h3 className="strong">{result.rentInfo}</h3>:'' }
<p className="card-text mb-1">
{result.description !== undefined ? result.description.substr(0,100) + "..." : ''}
</p>
<div className="row">
<div className="col-md-8">
<div className="row">
<div className="col">
{
result.features.map((feature, i) => <p key={i} className="badge badge-primary">{feature}</p>)
}
</div>
</div>
<div className="row">
{ result.contact !== undefined && result.contact.phone != undefined ? <span className="mr-3 lead"><i className="fas fa-phone">{result.contact.phone}</i></span> : ''}
{ result.contact !== undefined && result.contact.url !== undefined ? <span className="mr-3 lead"><a href={result.contact.url}><i className="fas fa-external-link-square-alt"></i> View property site</a></span>: '' }
</div>
</div>
<div className="col-md-3">
<div className="info-box mb-0">
<span className="info-box-icon bg-danger"><i className="far fa-star"></i></span>
{result.review != undefined ?
<div className="info-box-content">
<span className="info-box-text">Review</span>
<span className="info-box-number">{result.review} stars</span>
</div>
:''}
</div>
</div>
</div>

</div>
</div>
</div>
</div>
</>
);
}

CardApartments.propTypes = {
result: PropTypes.object,
index : PropTypes.string
}
export default CardApartments;

+ 4
- 0
src/components/CardApartments/CardApartments.scss View File

@@ -0,0 +1,4 @@
.image-height
{
height: 269px;
}

+ 122
- 0
src/components/CardCondos/CardCondos.js View File

@@ -0,0 +1,122 @@
import React from 'react';
import PropTypes from 'prop-types';

const CardCondos = ({result, index}) => {
const carouselId = "carouselExampleIndicators".concat(index);
const carouselIndicator = "#".concat(carouselId);

return(
<>
<div className="card">
<div className="card-body">
{result.lastUpdate !=undefined ?
<div className="ribbon-wrapper ribbon-lg">
<div className="ribbon bg-primary">
{result.lastUpdate}
</div>
</div> :''
}
<div className="row">
<div className="col-md-4">
<div id={carouselId} className="carousel slide" data-ride="carousel">
<ol className="carousel-indicators">
{result.images.map((image, i) =>
(image !== undefined && image.src !==undefined ?
i === 1 ?
<li data-target={carouselIndicator} data-slide-to={i} className="active"></li>
:
<li data-target={carouselIndicator} data-slide-to={i} className=""></li>
:""
))}
</ol>
<div className="carousel-inner">
{
result.images.map((image, i) =>
(image !== undefined && image.src !== undefined ?
i === 0 ?
<div className="carousel-item active" key={i} >
<img height="269px" className="d-block w-100"
src={image.src}
alt= {i} />
</div>
:
<div className="carousel-item" key={i} >
<img height="269px" className="d-block w-100"
src={image.src}
alt= {i} />
</div>
:'')
)
}
</div>
<a className="carousel-control-prev" href={carouselIndicator} role="button"
data-slide="prev">
<span className="carousel-control-custom-icon" aria-hidden="true">
<i className="fas fa-chevron-left"></i>
</span>
<span className="sr-only">Previous</span>
</a>
<a className="carousel-control-next" href={carouselIndicator} role="button"
data-slide="next">
<span className="carousel-control-custom-icon" aria-hidden="true">
<i className="fas fa-chevron-right"></i>
</span>
<span className="sr-only">Next</span>
</a>
</div>
</div>
<div className="col-md-8">
{result.name !== undefined ? <h2><a>{result.name}

</a>
</h2>: ''}
{result.address != undefined ?
<p className="lead">
{result.address.street !== undefined ? <span> {result.address.street}, </span>:''}
{result.address.city !== undefined ? <span> {result.address.city}, </span>:''}
{result.address.zip !== undefined ? <span> {result.address.zip.code} {result.address.zip.state}</span>:''}
</p>
: ''}
{result.rentInfo !=undefined ? <h3 className="strong">{result.rentInfo}</h3>:'' }
<p className="card-text mb-1">
{result.description !== undefined ? result.description.substr(0,100) + "..." : ''}
</p>
<div className="row">
<div className="col-md-8">
<div className="row">
<div className="col">
{
result.features.map((feature, i) => <p key={i} className="badge badge-primary">{feature}</p>)
}
</div>
</div>
<div className="row">
{ result.contact !== undefined && result.contact.phone != undefined ? <span className="mr-3 lead"><i className="fas fa-phone">{result.contact.phone}</i></span> : ''}
{ result.contact !== undefined && result.contact.agentFullName ? <span className="mr-3 lead"><i className="fas fa-user"></i>{result.contact.agentFullName}</span>: '' }
</div>
</div>
</div>

</div>
</div>
</div>
</div>
</>
);

}

CardCondos.propTypes = {
result: PropTypes.object,
index : PropTypes.string
}

export default CardCondos;

+ 122
- 0
src/components/CardHouses/CardHouses.js View File

@@ -0,0 +1,122 @@
import React from 'react';
import PropTypes from 'prop-types';

const CardHouses = ({result, index}) => {
const carouselId = "carouselExampleIndicators".concat(index);
const carouselIndicator = "#".concat(carouselId);

return(
<>
<div className="card">
<div className="card-body">
{result.lastUpdate !=undefined ?
<div className="ribbon-wrapper ribbon-lg">
<div className="ribbon bg-primary">
{result.lastUpdate}
</div>
</div> :''
}
<div className="row">
<div className="col-md-4">
<div id={carouselId} className="carousel slide" data-ride="carousel">
<ol className="carousel-indicators">
{result.images.map((image, i) =>
(image !== undefined && image.src !==undefined ?
i === 1 ?
<li data-target={carouselIndicator} data-slide-to={i} className="active"></li>
:
<li data-target={carouselIndicator} data-slide-to={i} className=""></li>
:""
))}
</ol>
<div className="carousel-inner">
{
result.images.map((image, i) =>
(image !== undefined && image.src !== undefined ?
i === 0 ?
<div className="carousel-item active" key={i} >
<img height="269px" className="d-block w-100"
src={image.src}
alt= {i} />
</div>
:
<div className="carousel-item" key={i} >
<img height="269px" className="d-block w-100"
src={image.src}
alt= {i} />
</div>
:'')
)
}
</div>
<a className="carousel-control-prev" href={carouselIndicator} role="button"
data-slide="prev">
<span className="carousel-control-custom-icon" aria-hidden="true">
<i className="fas fa-chevron-left"></i>
</span>
<span className="sr-only">Previous</span>
</a>
<a className="carousel-control-next" href={carouselIndicator} role="button"
data-slide="next">
<span className="carousel-control-custom-icon" aria-hidden="true">
<i className="fas fa-chevron-right"></i>
</span>
<span className="sr-only">Next</span>
</a>
</div>
</div>
<div className="col-md-8">
{result.name !== undefined ? <h2><a>{result.name}

</a>
</h2>: ''}
{result.address != undefined ?
<p className="lead">
{result.address.street !== undefined ? <span> {result.address.street}, </span>:''}
{result.address.city !== undefined ? <span> {result.address.city}, </span>:''}
{result.address.zip !== undefined ? <span> {result.address.zip.code} {result.address.zip.state}</span>:''}
</p>
: ''}
{result.rentInfo !=undefined ? <h3 className="strong">{result.rentInfo}</h3>:'' }
<p className="card-text mb-1">
{result.description !== undefined ? result.description.substr(0,100) + "..." : ''}
</p>
<div className="row">
<div className="col-md-8">
<div className="row">
<div className="col">
{
result.features.map((feature, i) => <p key={i} className="badge badge-primary">{feature}</p>)
}
</div>
</div>
<div className="row">
{ result.contact !== undefined && result.contact.phone != undefined ? <span className="mr-3 lead"><i className="fas fa-phone">{result.contact.phone}</i></span> : ''}
{ result.contact !== undefined && result.contact.agentFullName ? <span className="mr-3 lead"><i className="fas fa-user"></i>{result.contact.agentFullName}</span>: '' }
</div>
</div>
</div>

</div>
</div>
</div>
</div>
</>
);

}

CardHouses.propTypes = {
result: PropTypes.object,
index : PropTypes.string
}

export default CardHouses;

+ 1
- 1
src/components/ScrapeRequest/ScrappeStatus.jsx View File

@@ -7,7 +7,7 @@ const ScrappeStatus = ({ status, handleExecute, id }) => {
const { t } = useTranslation();
console.log("id", id)
if (status === 'requested')
return <button type="submit" className="btn btn-xs btn-block btn-primary" onClick={() => handleExecute(id)}><i className="fa fa-bell"></i>{t('common.execute')}</button>
return <button type="submit" className="btn btn-xs btn-block btn-primary" onClick={() => handleExecute(id)}><i className="fa fa-bell" ></i>{t('common.execute')}</button>
else if (status === 'done')
return <span className='badge bg-success'>Done</span>
else

+ 9
- 9
src/components/ScrappeDetails/ScrappeDetails.js View File

@@ -2,35 +2,35 @@ import React from 'react';
import PropTypes from 'prop-types';
import { useTranslation } from 'react-i18next';
import ScrappeStatus from '../../components/ScrapeRequest/ScrappeStatus'
const ScrappeDetails = (details) => {
const ScrappeDetails = ({details}) => {
const {t} = useTranslation();
return (
(details.details) ?
(details) ?
<section>
<h2>Scrappe Details</h2>
<br/>
<div className="row">
<div className="com-md-4">
{
(details.details.location) ?
<h3>{details.details.location}</h3>
(details.location) ?
<h3>{details.location}</h3>
: ''}
{
(details.details.estimate) ?
<span className="text-muted">{t('scrapeRequest.EstimatedTime')} {(new Date(details.details.estimate)).toLocaleString()}</span>
(details.estimate) ?
<span className="text-muted">{t('scrapeRequest.EstimatedTime')} {(new Date(details.estimate)).toLocaleString()}</span>
: ''}
</div>
<div className="col-md-4">
{
(details.details.filters && details.details.filters.length > 0) ?
(details.filters && details.filters.length > 0) ?
<div className="filters-cont">
<h3>Filters</h3>
{details.details.filters.map((filter,i) => <span className="badge bg-primary m-1" key={i}>{filter.name}</span>) }
{details.filters.map((filter,i) => <span className="badge bg-primary m-1" key={i}>{filter.name}:{filter.value}</span>) }
</div>
:'' }
</div>
<div className="col-md-1">
{details.details.status ? <ScrappeStatus status = {details.details.status} /> : '' }
{details.status ? <ScrappeStatus status = {details.status} /> : '' }
</div>
</div>

+ 0
- 18
src/components/ScrappeResult/ScrapeResult.js View File

@@ -1,18 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';

const ScrappeResult = (result) => {

return (
<div>
Result
</div>
);

}

ScrappeResult.propTypes = {
result: PropTypes.object
};

export default ScrappeResult;

+ 25
- 0
src/components/ScrappeResult/ScrappeResult.js View File

@@ -0,0 +1,25 @@
import React from 'react';
import PropTypes from 'prop-types';
//import CardApartments from '../CardApartments/CardApartments'
import CardHouses from '../CardHouses/CardHouses';
const ScrappeResult = ({result, type, index}) => {
return (
<>
{console.log(type)}
{
//if(type="aparments")
// <CardApartments index = {index} result={result} />

//else if(type="houses")
<CardHouses index ={index} result={result} />
}
</>
);

}
ScrappeResult.propTypes = {
result: PropTypes.object,
type: PropTypes.object,
index :PropTypes.string
};
export default ScrappeResult;

+ 2
- 0
src/constants/days.js View File

@@ -0,0 +1,2 @@
export const Saturday = 6;
export const Sunday = 7;

+ 3
- 0
src/constants/workingHours.js View File

@@ -0,0 +1,3 @@
export const WorkingDayType = 0;
export const SaturdayType = 1;
export const SundayType = 2;

+ 19
- 0
src/helpers/GetTodaysWorkingHours.js View File

@@ -0,0 +1,19 @@
import {Saturday, Sunday}from '../constants/days'
import {WorkingDayType, SaturdayType,SundayType }from '../constants/workingHours'

export default function getHours(officeHours) {
var day = new Date().getDay();
if(officeHours === undefined && officeHours.length < 3 ){
return null;
}
else if(day === Saturday){
return officeHours[SaturdayType].hours;
}
else if(day === Sunday){
return officeHours[SundayType].hours;
}
else {
return officeHours[WorkingDayType].hours;
}
}

+ 1
- 1
src/main.scss View File

@@ -3,7 +3,7 @@
@import './assets/styles/functions';
@import './assets/styles/typography';
@import './assets/styles/base';
@import './assets/styles/reset';
//@import './assets/styles/reset';
@import './assets/styles/components/button';
@import './assets/styles/components/icon-button';
@import './assets/styles/components/app-button';

+ 3
- 1
src/pages/HomePage/HomePage.js View File

@@ -2,7 +2,6 @@ import React, { useEffect, useState } from 'react';
import CreateScrapeRequest from '../../components/CreateScrapeRequest/CreateScrapeRequest';
import ScrapeRequests from '../../components/ScrapeRequests/ScrapeRequests';
import { createScrappes, executeScrappes, getAllScrappes } from '../../request/scrappe';

const HomePage = () => {
const [scrappes, setScrappes] = useState([])

@@ -32,6 +31,9 @@ const HomePage = () => {

return (
<>
<h1 className="lead text-center" >Scrapper </h1>

<CreateScrapeRequest handleRequest={handleRequest} />
<ScrapeRequests scrappes={scrappes} handleExecute={handleExecute} />
</>

+ 14
- 7
src/pages/ScrapeResults/ScrapeResultsPage.js View File

@@ -1,17 +1,21 @@
import React, { useEffect, useState } from 'react';
import { getByIdScrappe } from '../../request/scrappe';
import { Link } from "react-router-dom";

import ScrappeDetails from '../../components/ScrappeDetails/ScrappeDetails'
//import ScrappeResult from '../../components/ScrappeResult/ScrappeResult'
import ScrappeResult from '../../components/ScrappeResult/ScrappeResult'
import PropTypes from 'prop-types';

const ScrapeResultsPage = ({ location }) => {

const [scrappeResults, setScrappeResults] = useState()
const [scrappeDetails, setScrappeDetails] = useState()
useEffect(() => {
getByIdScrappe(location.id)
.then(res => {
setScrappeDetails(res.data)
if(res.data.status==='done')
setScrappeResults(res.data.result)})
}, [setScrappeResults])
@@ -20,14 +24,17 @@ const ScrapeResultsPage = ({ location }) => {
return (
<>
{/* ScrappeDetail */}
{console.log(scrappeDetails)}
<Link to="/" className="navbar-brand">
<span className="brand-text font-weight-light">Back</span>
</Link>
<ScrappeDetails details = {scrappeDetails} />
{/* {(scrappeResults !==undefined)
? scrappeResults.map((result, i) => <ScrappeResult key={i} result = {result} />)
:''
*/}
<div className ='content' >
{(scrappeResults !== undefined) ?
scrappeResults.map((result, i) => <ScrappeResult key={i} index={i} type ={scrappeDetails.filters.find(el => el.name="type")} result = {result} />)
:''
}
</div>
</>
);
};

+ 1079
- 22
yarn.lock
File diff suppressed because it is too large
View File


Loading…
Cancel
Save