Compare commits
5 Commits
b424376656
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
| afed3aed53 | |||
| ead8f23379 | |||
| 4d31f9f71a | |||
| 880df2c2ac | |||
| c40302aa93 |
@@ -6,8 +6,9 @@ import Error404Page from '../main/404/Error404Page';
|
||||
import navigationPagesConfigs from '../main/navigationPages/navigationPagesConfig';
|
||||
import authPagesConfigs from '../main/authPages/authPagesConfigs';
|
||||
import HomeConfig from '../main/home/HomeConfig';
|
||||
import RentAndBuyConfig from '../main/rentAndBuy/RentAndBuyConfig';
|
||||
|
||||
const routeConfigs = [...navigationPagesConfigs, ...authPagesConfigs, HomeConfig];
|
||||
const routeConfigs = [...navigationPagesConfigs, ...authPagesConfigs, HomeConfig, RentAndBuyConfig];
|
||||
|
||||
const routes = [
|
||||
...FuseUtils.generateRoutesFromConfigs(routeConfigs, settingsConfig.defaultAuth),
|
||||
|
||||
@@ -26,7 +26,7 @@ function AboutUs({ t }) {
|
||||
</div>
|
||||
<Link
|
||||
className="w-[220px] py-[17px] text-center text-base text-primary-light font-semibold tracking-widest uppercase rounded-2xl bg-secondary-light shadow hover:shadow-hover hover:shadow-secondary-light ease-in-out duration-300"
|
||||
to="/rent-and-buy"
|
||||
to="/rent-and-buy/search"
|
||||
>
|
||||
{t('research_btn')}
|
||||
</Link>
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { memo, useState } from 'react';
|
||||
import { withTranslation } from 'react-i18next';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import SearchInput from '../../shared-components/SearchInput';
|
||||
|
||||
function Welcome({ t }) {
|
||||
const [query, setQuery] = useState('');
|
||||
const navigate = useNavigate();
|
||||
|
||||
const onInputType = (event) => {
|
||||
const { target } = event;
|
||||
@@ -12,7 +14,12 @@ function Welcome({ t }) {
|
||||
};
|
||||
|
||||
const onSearch = () => {
|
||||
// query
|
||||
const trimmedQuery = query.trim();
|
||||
if (!trimmedQuery) {
|
||||
return;
|
||||
}
|
||||
|
||||
navigate(`/rent-and-buy/search?query=${trimmedQuery}`);
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
16
src/app/main/rentAndBuy/RentAndBuy.js
Normal file
16
src/app/main/rentAndBuy/RentAndBuy.js
Normal file
@@ -0,0 +1,16 @@
|
||||
import Typography from '@mui/material/Typography';
|
||||
import { withTranslation } from 'react-i18next';
|
||||
import { Outlet } from 'react-router-dom';
|
||||
|
||||
function RentAndBuy({ t }) {
|
||||
return (
|
||||
<div className="flex flex-col max-w-8xl w-full px-10 py-32 mx-auto">
|
||||
<Typography variant="h1" className="mb-44 text-4xl text-common-layout font-medium">
|
||||
{t('title')}
|
||||
</Typography>
|
||||
<Outlet />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default withTranslation('rentAndBuyPage')(RentAndBuy);
|
||||
38
src/app/main/rentAndBuy/RentAndBuyConfig.js
Normal file
38
src/app/main/rentAndBuy/RentAndBuyConfig.js
Normal file
@@ -0,0 +1,38 @@
|
||||
import { lazy } from 'react';
|
||||
import i18next from 'i18next';
|
||||
|
||||
import RentAndBuy from './RentAndBuy';
|
||||
import en from './i18n/en';
|
||||
|
||||
i18next.addResourceBundle('en', 'rentAndBuyPage', en);
|
||||
|
||||
const SearchAddress = lazy(() => import('./components/SearchAddress/SearchAddress'));
|
||||
const PropertyPreview = lazy(() => import('./components/PropertyPreview/PropertyPreview'));
|
||||
|
||||
const RentAndBuyConfig = {
|
||||
settings: {
|
||||
layout: {
|
||||
config: {},
|
||||
style: 'layout2',
|
||||
},
|
||||
},
|
||||
auth: null,
|
||||
routes: [
|
||||
{
|
||||
path: '/rent-and-buy',
|
||||
element: <RentAndBuy />,
|
||||
children: [
|
||||
{
|
||||
path: 'search',
|
||||
element: <SearchAddress />,
|
||||
},
|
||||
{
|
||||
path: 'preview',
|
||||
element: <PropertyPreview />,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default RentAndBuyConfig;
|
||||
@@ -0,0 +1,32 @@
|
||||
import Button from '@mui/material/Button';
|
||||
import { useState } from 'react';
|
||||
import { withTranslation } from 'react-i18next';
|
||||
import RegistrationPopup from 'src/app/main/shared-components/popups/RegistrationPopup';
|
||||
|
||||
function PropertyPreview({ t }) {
|
||||
const [isPopupOpen, setIsPopupOpen] = useState(false);
|
||||
|
||||
const openPopup = () => setIsPopupOpen(true);
|
||||
const closePopup = () => setIsPopupOpen(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="flex flex-col items-center">
|
||||
<Button
|
||||
variant="contained"
|
||||
color="secondary"
|
||||
className="w-384 p-20 text-2xl leading-none rounded-lg"
|
||||
aria-label={t('see_more_btn')}
|
||||
type="button"
|
||||
size="large"
|
||||
onClick={openPopup}
|
||||
>
|
||||
{t('see_more_btn')}
|
||||
</Button>
|
||||
</div>
|
||||
<RegistrationPopup open={isPopupOpen} onClose={closePopup} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default withTranslation('rentAndBuyPage')(PropertyPreview);
|
||||
@@ -0,0 +1,18 @@
|
||||
import { withTranslation } from 'react-i18next';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
function SearchAddress({ t }) {
|
||||
return (
|
||||
<div className="flex flex-col items-center gap-68">
|
||||
<span>How are you?</span>
|
||||
<Link
|
||||
to="/rent-and-buy/preview"
|
||||
className="inline-block w-[182px] py-[17px] text-center text-base text-primary-light font-semibold tracking-widest uppercase rounded-lg bg-secondary-light shadow hover:shadow-hover hover:shadow-secondary-light ease-in-out duration-300"
|
||||
>
|
||||
{t('show_btn')}
|
||||
</Link>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default withTranslation('rentAndBuyPage')(SearchAddress);
|
||||
8
src/app/main/rentAndBuy/i18n/en.js
Normal file
8
src/app/main/rentAndBuy/i18n/en.js
Normal file
@@ -0,0 +1,8 @@
|
||||
const locale = {
|
||||
title: 'Rent&Buy Analysis',
|
||||
show_btn: 'show',
|
||||
see_more_btn: 'See more',
|
||||
view: 'View the Calculation',
|
||||
};
|
||||
|
||||
export default locale;
|
||||
11
src/app/main/shared-components/PropertyAnalysisHeader.js
Normal file
11
src/app/main/shared-components/PropertyAnalysisHeader.js
Normal file
@@ -0,0 +1,11 @@
|
||||
import Paper from '@mui/material/Paper';
|
||||
|
||||
function PropertyAnalysisHeader() {
|
||||
return (
|
||||
<Paper>
|
||||
<div></div>
|
||||
</Paper>
|
||||
);
|
||||
}
|
||||
|
||||
export default PropertyAnalysisHeader;
|
||||
@@ -1,5 +1,7 @@
|
||||
import AuthService from './authService';
|
||||
import FirebaseService from './firebaseService';
|
||||
import PropertyService from './propertyService';
|
||||
|
||||
// TODO: change to firebase secrets or to use firebase functions
|
||||
const firebaseConfig = {
|
||||
apiKey: 'AIzaSyBqMGmOF0-DkYDpnsmZwpf5S8w5cL3fBb8',
|
||||
@@ -12,7 +14,15 @@ const firebaseConfig = {
|
||||
measurementId: 'G-JW7J8ZQ9FJ',
|
||||
};
|
||||
|
||||
// TopHap
|
||||
const propertyConfig = {
|
||||
dataBaseURL: process.env.REACT_APP_PROPERTY_DATA_BASE_URL,
|
||||
widgetBaseURL: process.env.REACT_APP_PROPERTY_WIDGET_BASE_URL,
|
||||
apiKey: process.env.REACT_APP_PROPERTY_API_KEY,
|
||||
};
|
||||
|
||||
const firebase = new FirebaseService(firebaseConfig);
|
||||
const authService = new AuthService();
|
||||
const propertyService = new PropertyService(propertyConfig);
|
||||
|
||||
export { authService, firebase };
|
||||
export { authService, firebase, propertyService };
|
||||
|
||||
57
src/app/services/propertyService.js
Normal file
57
src/app/services/propertyService.js
Normal file
@@ -0,0 +1,57 @@
|
||||
import axios from 'axios';
|
||||
|
||||
const widgets = {
|
||||
absorptionRate: 'absorption-rate',
|
||||
crime: 'crime',
|
||||
hazards: 'hazards',
|
||||
mapPreview: 'map-preview',
|
||||
marketTrends: 'market-trends',
|
||||
noise: 'noise',
|
||||
population: 'population',
|
||||
propertyTypes: 'property-types',
|
||||
rentEstimate: 'rent-estimate',
|
||||
thEstimate: 'th-estimate',
|
||||
turnover: 'turnover',
|
||||
walkability: 'walkability',
|
||||
zipCodeMap: 'zip-code-map',
|
||||
};
|
||||
|
||||
export default class PropertyService {
|
||||
#dataApi;
|
||||
|
||||
#widgetApi;
|
||||
|
||||
constructor(config) {
|
||||
const { dataBaseURL, widgetBaseURL, apiKey } = config;
|
||||
this.#dataApi = axios.create({
|
||||
baseURL: dataBaseURL,
|
||||
headers: { 'X-API-Key': apiKey },
|
||||
});
|
||||
this.#widgetApi = axios.create({
|
||||
baseURL: widgetBaseURL,
|
||||
params: {
|
||||
sid: apiKey,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
fetchProperty(params) {
|
||||
return this.#dataApi.get('/property', { params });
|
||||
}
|
||||
|
||||
search(body) {
|
||||
return this.#dataApi.post('/search', body);
|
||||
}
|
||||
|
||||
fetchComparables(params) {
|
||||
return this.#dataApi.get('/comparables', { params });
|
||||
}
|
||||
|
||||
fetchWidgetByPropertyId(widget, propertyId, params) {
|
||||
return this.#widgetApi.get(`${widget}/${propertyId}`, { params });
|
||||
}
|
||||
|
||||
fetchWidgetByAddress(widget, params) {
|
||||
return this.#widgetApi.get(`${widget}/address`, { params });
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ function NavLinks({ className }) {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Link className={className} to="/rent-and-buy">
|
||||
<Link className={className} to="/rent-and-buy/search">
|
||||
{t('rent_and_buy')}
|
||||
</Link>
|
||||
<Link className={className} to={{ hash: 'about-us' }}>
|
||||
|
||||
Reference in New Issue
Block a user