Skip to content

Commit

Permalink
commit
Browse files Browse the repository at this point in the history
  • Loading branch information
ayushpandey830 committed Nov 28, 2021
1 parent e179269 commit 9e2286e
Show file tree
Hide file tree
Showing 18 changed files with 2,203 additions and 90 deletions.
4 changes: 4 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"presets":["next/babel"],
"plugins": []
}
Binary file added assets/images/house.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 20 additions & 0 deletions assets/images/noresult.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions components/Footer.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Box } from '@chakra-ui/layout';

const Footer = () => (
<Box textAlign='center' p='5' color='gray.600' borderTop='1px' borderColor='gray.100'>
© 2021 YourEstate, Inc.
</Box>
);

export default Footer;
48 changes: 48 additions & 0 deletions components/ImageScrollbar.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { useContext } from 'react';
import Image from 'next/image';
import { Box, Icon, Flex } from '@chakra-ui/react';
import { ScrollMenu, VisibilityContext } from 'react-horizontal-scrolling-menu';
import { FaArrowAltCircleLeft, FaArrowAltCircleRight } from 'react-icons/fa';

const LeftArrow = () => {
const { scrollPrev } = useContext(VisibilityContext);

return (
<Flex justifyContent='center' alignItems='center' marginRight='1'>
<Icon
as={FaArrowAltCircleLeft}
onClick={() => scrollPrev()}
fontSize='2xl'
cursor='pointer'
d={['none','none','none','block']}
/>
</Flex>
);
}

const RightArrow = () => {
const { scrollNext } = useContext(VisibilityContext);

return (
<Flex justifyContent='center' alignItems='center' marginLeft='1'>
<Icon
as={FaArrowAltCircleRight}
onClick={() => scrollNext()}
fontSize='2xl'
cursor='pointer'
d={['none','none','none','block']}
/>
</Flex>
);
}
export default function ImageSrollbar({ data }) {
return (
<ScrollMenu LeftArrow={LeftArrow} RightArrow={RightArrow} style={{ overflow: 'hidden' }} >
{data.map((item) => (
<Box width='910px' itemId={item.id} overflow='hidden' p='1'>
<Image placeholder="blur" blurDataURL={item.url} src={item.url} width={1000} height={500} sizes="(max-width: 500px) 100px, (max-width: 1023px) 400px, 1000px" />
</Box>
))}
</ScrollMenu>
);
}
24 changes: 24 additions & 0 deletions components/Layout.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import Head from 'next/head';
import { Box } from '@chakra-ui/react';

import Footer from './Footer';
import Navbar from './Navbar';

export default function Layout({ children }) {
return (
<>
<Head>
<title>Real Estate</title>
</Head>
<Box maxWidth='1280px' m='auto'>
<header>
<Navbar />
</header>
<main>{children}</main>
<footer>
<Footer />
</footer>
</Box>
</>
);
}
35 changes: 35 additions & 0 deletions components/Navbar.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import Link from 'next/link';
import { Menu, MenuButton, MenuList, MenuItem, IconButton, Flex, Box, Spacer } from '@chakra-ui/react';
import { FcMenu, FcHome, FcAbout } from 'react-icons/fc';
import { BsSearch } from 'react-icons/bs';
import { FiKey } from 'react-icons/fi';

const Navbar = () => (
<Flex p='2' borderBottom='1px' borderColor='gray.100'>
<Box fontSize='3xl' color='blue.400' fontWeight='bold'>
<Link href='/' paddingLeft='2'>YourEstate</Link>
</Box>
<Spacer />
<Box>
<Menu>
<MenuButton as={IconButton} icon={<FcMenu />} variant='outline' color='red.400' />
<MenuList>
<Link href='/' passHref>
<MenuItem icon={<FcHome />}>Home</MenuItem>
</Link>
<Link href='/search' passHref>
<MenuItem icon={<BsSearch />}>Search</MenuItem>
</Link>
<Link href='/search?purpose=for-sale' passHref>
<MenuItem icon={<FcAbout />}>Buy Property</MenuItem>
</Link>
<Link href='/search?purpose=for-rent' passHref>
<MenuItem icon={<FiKey />}>Rent Property</MenuItem>
</Link>
</MenuList>
</Menu>
</Box>
</Flex>
);

export default Navbar;
40 changes: 40 additions & 0 deletions components/Property.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import Link from 'next/link';
import Image from 'next/image';
import { Box, Flex, Text } from '@chakra-ui/layout';
import { Avatar } from '@chakra-ui/avatar';
import { FaBed, FaBath } from 'react-icons/fa';
import { BsGridFill } from 'react-icons/bs';
import { GoVerified } from 'react-icons/go';
import millify from 'millify';

import DefaultImage from '../assets/images/house.jpg';

const Property = ({ property: { coverPhoto, price, rentFrequency, rooms, title, baths, area, agency, isVerified, externalID } }) => (
<Link href={`/property/${externalID}`} passHref>
<Flex flexWrap='wrap' w='420px' p='5' paddingTop='0px' justifyContent='flex-start' cursor='pointer' >
<Box>
<Image src={coverPhoto ? coverPhoto.url : DefaultImage} width={400} height={260} />
</Box>
<Box w='full'>
<Flex paddingTop='2' alignItems='center' justifyContent='space-between'>
<Flex alignItems='center'>
<Box paddingRight='3' color='green.400'>{isVerified && <GoVerified />}</Box>
<Text fontWeight='bold' fontSize='lg'>AED {millify(price)}{rentFrequency && `/${rentFrequency}`}</Text>
</Flex>
<Box>
<Avatar size='sm' src={agency?.logo?.url}></Avatar>
</Box>
</Flex>
<Flex alignItems='center' p='1' justifyContent='space-between' w='250px' color='blue.400'>
{rooms}
<FaBed /> | {baths} <FaBath /> | {millify(area)} sqft <BsGridFill />
</Flex>
<Text fontSize='lg'>
{title.length > 30 ? title.substring(0, 30) + '...' : title}
</Text>
</Box>
</Flex>
</Link>
);

export default Property;
116 changes: 116 additions & 0 deletions components/SearchFilters.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import { useEffect, useState } from 'react';
import { Flex, Select, Box, Text, Input, Spinner, Icon, Button } from '@chakra-ui/react';
import { useRouter } from 'next/router';
import { MdCancel } from 'react-icons/md';
import Image from 'next/image';

import { filterData, getFilterValues } from '../utils/filterData';
import { baseUrl, fetchApi } from '../utils/fetchApi';
import noresult from '../assets/images/noresult.svg';

export default function SearchFilters() {
const [filters] = useState(filterData);
const [searchTerm, setSearchTerm] = useState('');
const [locationData, setLocationData] = useState();
const [showLocations, setShowLocations] = useState(false);
const [loading, setLoading] = useState(false);
const router = useRouter();

const searchProperties = (filterValues) => {
const path = router.pathname;
const { query } = router;

const values = getFilterValues(filterValues)

values.forEach((item) => {
if(item.value && filterValues?.[item.name]) {
query[item.name] = item.value
}
})

router.push({ pathname: path, query: query });
};

useEffect(() => {
if (searchTerm !== '') {
const fetchData = async () => {
setLoading(true);
const data = await fetchApi(`${baseUrl}/auto-complete?query=${searchTerm}`);
setLoading(false);
setLocationData(data?.hits);
};

fetchData();
}
}, [searchTerm]);

return (
<Flex bg='gray.100' p='4' justifyContent='center' flexWrap='wrap'>
{filters?.map((filter) => (
<Box key={filter.queryName}>
<Select onChange={(e) => searchProperties({ [filter.queryName]: e.target.value })} placeholder={filter.placeholder} w='fit-content' p='2' >
{filter?.items?.map((item) => (
<option value={item.value} key={item.value}>
{item.name}
</option>
))}
</Select>
</Box>
))}
<Flex flexDir='column'>
<Button onClick={() => setShowLocations(!showLocations)} border='1px' borderColor='gray.200' marginTop='2' >
Search Location
</Button>
{showLocations && (
<Flex flexDir='column' pos='relative' paddingTop='2'>
<Input
placeholder='Type Here'
value={searchTerm}
w='300px'
focusBorderColor='gray.300'
onChange={(e) => setSearchTerm(e.target.value)}
/>
{searchTerm !== '' && (
<Icon
as={MdCancel}
pos='absolute'
cursor='pointer'
right='5'
top='5'
zIndex='100'
onClick={() => setSearchTerm('')}
/>
)}
{loading && <Spinner margin='auto' marginTop='3' />}
{showLocations && (
<Box height='300px' overflow='auto'>
{locationData?.map((location) => (
<Box
key={location.id}
onClick={() => {
searchProperties({ locationExternalIDs: location.externalID });
setShowLocations(false);
setSearchTerm(location.name);
}}
>
<Text cursor='pointer' bg='gray.200' p='2' borderBottom='1px' borderColor='gray.100' >
{location.name}
</Text>
</Box>
))}
{!loading && !locationData?.length && (
<Flex justifyContent='center' alignItems='center' flexDir='column' marginTop='5' marginBottom='5' >
<Image src={noresult} />
<Text fontSize='xl' marginTop='3'>
Waiting to search!
</Text>
</Flex>
)}
</Box>
)}
</Flex>
)}
</Flex>
</Flex>
);
}
5 changes: 4 additions & 1 deletion next.config.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
module.exports = {
reactStrictMode: true,
}
images: {
domains: ["bayut-production.s3.eu-central-1.amazonaws.com"],
},
};
Loading

0 comments on commit 9e2286e

Please sign in to comment.