diff --git a/client/package.json b/client/package.json index da2dbf9..1a91585 100644 --- a/client/package.json +++ b/client/package.json @@ -6,10 +6,12 @@ "dependencies": { "@emotion/react": "^11.5.0", "@emotion/styled": "^11.3.0", + "@mui/icons-material": "^5.0.5", "@mui/material": "^5.0.4", "@mui/styles": "^5.0.2", "axios": "^0.23.0", "eslint-config-react-app": "^6.0.0", + "prop-types": "^15.7.2", "react": "^17.0.2", "react-dom": "^17.0.2", "react-icons": "^4.3.1", diff --git a/client/src/App.js b/client/src/App.js index c88ef45..446adac 100644 --- a/client/src/App.js +++ b/client/src/App.js @@ -1,12 +1,23 @@ -import { Footer } from './components'; +import { BrowserRouter as Router } from 'react-router-dom'; +// import PropertyCard from './components/PropertyCard'; +// import NavBar from './components/Navbar'; +// import { Footer } from './components'; +import Estate from './pages/Estate'; function App() { return (
-
); } - export default App; diff --git a/client/src/assets/background.png b/client/src/assets/background.png new file mode 100644 index 0000000..83624e3 Binary files /dev/null and b/client/src/assets/background.png differ diff --git a/client/src/assets/bath.png b/client/src/assets/bath.png new file mode 100644 index 0000000..b0fba3c Binary files /dev/null and b/client/src/assets/bath.png differ diff --git a/client/src/assets/beds.png b/client/src/assets/beds.png new file mode 100644 index 0000000..22c6f0f Binary files /dev/null and b/client/src/assets/beds.png differ diff --git a/client/src/assets/profile-picture.jpg b/client/src/assets/profile-picture.jpg new file mode 100644 index 0000000..fdc5ea5 Binary files /dev/null and b/client/src/assets/profile-picture.jpg differ diff --git a/client/src/assets/rooms.png b/client/src/assets/rooms.png new file mode 100644 index 0000000..90e56b2 Binary files /dev/null and b/client/src/assets/rooms.png differ diff --git a/client/src/assets/space.png b/client/src/assets/space.png new file mode 100644 index 0000000..69f59ca Binary files /dev/null and b/client/src/assets/space.png differ diff --git a/client/src/asstes/avatar.png b/client/src/asstes/avatar.png new file mode 100644 index 0000000..57ac67e Binary files /dev/null and b/client/src/asstes/avatar.png differ diff --git a/client/src/asstes/logo.png b/client/src/asstes/logo.png new file mode 100644 index 0000000..b00a296 Binary files /dev/null and b/client/src/asstes/logo.png differ diff --git a/client/src/components/ImageSection/imageSection.css b/client/src/components/ImageSection/imageSection.css new file mode 100644 index 0000000..2d81802 --- /dev/null +++ b/client/src/components/ImageSection/imageSection.css @@ -0,0 +1,31 @@ +.main{ + display: flex; + width: 80%; + height: 60vh; + margin-top: 5rem; +} +.bigImage{ + width: 70%; +} +.bigImage img{ + min-width: 100%; + max-height: 100% +} +.anotherImage{ + display: flex; + flex-direction:column; + width: 30%; + justify-content: space-between + +} +.anotherImage img{ + min-width: 100%; + min-height: 30%; + margin-left:2rem; + margin-bottom: 6px; + +} + +img:nth-child(3){ + margin-bottom: 0px; +} \ No newline at end of file diff --git a/client/src/components/ImageSection/index.js b/client/src/components/ImageSection/index.js new file mode 100644 index 0000000..e2e0793 --- /dev/null +++ b/client/src/components/ImageSection/index.js @@ -0,0 +1,33 @@ +import PropTypes from 'prop-types'; +import './imageSection.css'; + +function ImageSection({ images }) { + let imagesarr = Object.values(images); + const mainImage = imagesarr[0]; + console.log(imagesarr); + imagesarr = imagesarr.slice(1); + return ( +
+
+ home +
+
+ {imagesarr.map((item) => ( + home + ))} +
+
+ ); +} +ImageSection.propTypes = { + images: PropTypes.arrayOf(PropTypes.string).isRequired, +}; +export default ImageSection; diff --git a/client/src/components/Navbar/index.js b/client/src/components/Navbar/index.js new file mode 100644 index 0000000..4d2c5ca --- /dev/null +++ b/client/src/components/Navbar/index.js @@ -0,0 +1,75 @@ +/* eslint-disable no-unused-vars */ +import React, { useState } from 'react'; +import { Link } from 'react-router-dom'; +import { + ListItem, ListItemText, Button, Avatar, Container, List, +} from '@mui/material'; +import './style.css'; + +import Logo from '../../asstes/logo.png'; +import PresonImg from '../../asstes/avatar.png'; + +function NavBar() { + const [logged, setLogged] = useState(true); + return ( + + + + + ); +} +export default NavBar; diff --git a/client/src/components/Navbar/style.css b/client/src/components/Navbar/style.css new file mode 100644 index 0000000..63b5d4a --- /dev/null +++ b/client/src/components/Navbar/style.css @@ -0,0 +1,18 @@ +.container { + display: flex; + flex-direction: row; + justify-content: space-around; +} +.img-logo { + width: 90px; + height: 80px; +} +.list { + display: flex; + align-self: center; +} +.agent { + display: flex; + flex-direction: row; + align-self: center; +} diff --git a/client/src/components/PropertyCard/PropertyCard.css b/client/src/components/PropertyCard/PropertyCard.css new file mode 100644 index 0000000..78db7f6 --- /dev/null +++ b/client/src/components/PropertyCard/PropertyCard.css @@ -0,0 +1,37 @@ +.row{ + display: flex; + flex-wrap: wrap; +} +.rectangle{ + width: 50%; + background-color:#26B919; + clip-path: polygon(0 -134%, 91% 75%, 91% 100%, 0% 100%); + border-radius: 6px; + display: flex; + justify-content: flex-start; + align-items: center; + padding: 10px; + + +} +.loveicon{ + text-align: end; +} +.price{ + font-size: 1.9rem; + width: 100%; + text-align: center; + margin-top: 5px; +} +.bathroom,.rooms,.beds,.sqft{ + width: 45%; + background-color:#3781CB; + padding: 10px; + margin:0 0 10px 10px; + border-radius: 6px; + display: flex; + justify-content: space-around; + align-items: center; + box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); + +} \ No newline at end of file diff --git a/client/src/components/PropertyCard/index.js b/client/src/components/PropertyCard/index.js new file mode 100644 index 0000000..9edaea2 --- /dev/null +++ b/client/src/components/PropertyCard/index.js @@ -0,0 +1,103 @@ +import { + Card, + CardContent, +} from '@mui/material'; +import PropTypes from 'prop-types'; + +import FavoriteBorderIcon from '@mui/icons-material/FavoriteBorder'; +import { makeStyles } from '@mui/styles'; +import Space from '../../assets/space.png'; +import Bath from '../../assets/bath.png'; +import Rooms from '../../assets/rooms.png'; +import Bed from '../../assets/beds.png'; +import './PropertyCard.css'; + +const useStyles = makeStyles({ + card: { + backgroundColor: '#F1F1F1', + maxWidth: 345, + display: 'flex', + flexDirection: 'column', + }, + icons: { + display: 'flex', + flexDirection: 'row', + flexWrap: 'wrap', + + }, +}); +function PropertyCard({ + data: { + type, price, beds, baths, rooms, space, + }, +}) { + const classes = useStyles(); + + return ( + + +
+ {type} +
+
+ +
+
+ {price} + {' '} + $ +
+
+ + +
+ space + {baths} + {' '} + Bathrooms +
+
+ space + {rooms} + {' '} + Rooms +
+
+ space + {beds} + {' '} + Beds +
+
+ space + {space} + Sqft +
+
+
+ ); +} +PropertyCard.propTypes = { + data: PropTypes.shape({ + type: PropTypes.string, + price: PropTypes.string, + beds: PropTypes.string, + baths: PropTypes.string, + rooms: PropTypes.string, + space: PropTypes.string, + }).isRequired, +}; + +export default PropertyCard; diff --git a/client/src/components/UserContacatCard/index.js b/client/src/components/UserContacatCard/index.js new file mode 100644 index 0000000..4e3b769 --- /dev/null +++ b/client/src/components/UserContacatCard/index.js @@ -0,0 +1,89 @@ +import { + Card, + CardContent, + Typography, + Avatar, + colors, + +} from '@mui/material'; +import MdPhone from '@mui/icons-material/Phone'; +import LocationOnIcon from '@mui/icons-material/LocationOn'; +import EmailIcon from '@mui/icons-material/Email'; +import { makeStyles } from '@mui/styles'; +import PropTypes from 'prop-types'; + +const useStyles = makeStyles({ + card: { + backgroundColor: 'secondary', + maxWidth: 345, + display: 'flex', + flexDirection: 'column', + justifyContent: 'center', + alignItems: 'center', + padding: '10px', + width: '24rem', + height: '30rem', + }, + icon: { + marginRight: '0.5rem', + }, +}); +const contentStyles = { display: 'flex', marginBottom: '15px', alignItems: 'center' }; + +function UserContactCard({ + data: { + name, phone, image, location, email, + }, +}) { + const classes = useStyles(); + + return ( + + + + + + {name} + + + Building Owner + + + Contact Info: + + + + + {location} + + + + + {phone} + + + + + {email} + + + + + ); +} + +UserContactCard.propTypes = { + data: PropTypes.shape({ + image: PropTypes.string, + name: PropTypes.string, + location: PropTypes.string, + phone: PropTypes.string, + email: PropTypes.string, + }).isRequired, +}; + +export default UserContactCard; diff --git a/client/src/pages/Estate/estate.css b/client/src/pages/Estate/estate.css new file mode 100644 index 0000000..6c014eb --- /dev/null +++ b/client/src/pages/Estate/estate.css @@ -0,0 +1,24 @@ +.background{ + width: 100%; + height: 74vh; +} + +.PropertyCard{ + position: absolute; + top: 36rem; + left: 82.4rem; +} + +.description{ + width: 50%; +} +.UserContactCard{ + + width: 50%; +} +.description-container{ + display: flex; + flex-wrap: wrap; + justify-content: space-between; + padding-top: 5rem; +} \ No newline at end of file diff --git a/client/src/pages/Estate/index.js b/client/src/pages/Estate/index.js new file mode 100644 index 0000000..412deac --- /dev/null +++ b/client/src/pages/Estate/index.js @@ -0,0 +1,70 @@ +import Typography from '@mui/material/Typography'; +import Container from '@mui/material/Container'; +import Navbar from '../../components/Navbar'; +import PropertyCard from '../../components/PropertyCard'; +import UserContactCard from '../../components/UserContacatCard'; +import ImageSection from '../../components/ImageSection'; + +// import { Footer } from '../../components'; +import backgroundImage from '../../assets/background.png'; +import './estate.css'; + +function Estate() { + return ( +
+ + + background + +
+ +
+ + This is a simple hero unit, a simple jumbotron-style + +
+
+ + DESCRIPTION + + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. + In bibendum elit magna, ut placerat nunc tempus vel. + Donec vitae dictum ligula. + Phasellus congue maximus eleifend. + Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae + Suspendisse potenti. + Suspendisse sollicitudin posuere nunc et vehicula. + Interdum et malesuada fames ac ante ipsum primis in faucibus. + Maecenas aliquam vitae quam at sodales. + +
+ + +
+ +
+ {/*
+ + ); +} + +export default Estate; diff --git a/server/controllers/estates/getEstate.js b/server/controllers/estates/getEstate.js new file mode 100644 index 0000000..e52564e --- /dev/null +++ b/server/controllers/estates/getEstate.js @@ -0,0 +1,24 @@ +const { getEstateQuery, getImagesQuery } = require('../../database/quieres'); + +module.exports = async (req, res, next) => { + const { estateId } = req.params; + if (!(estateId > 0)) { + return res.status(400).json({ + message: 'Invalid estate id', + }); + } + try { + const { rowCount, rows: estateData } = await getEstateQuery(estateId); + const { rows: imagesData } = await getImagesQuery(estateId); + if (rowCount > 0) { + return res.json({ + data: { ...estateData, images: [...imagesData] }, + }); + } + return res.status(400).json({ + message: 'Estate not found', + }); + } catch (err) { + return next(err); + } +}; diff --git a/server/controllers/estates/index.js b/server/controllers/estates/index.js index 0275996..8d02528 100644 --- a/server/controllers/estates/index.js +++ b/server/controllers/estates/index.js @@ -1,7 +1,9 @@ const editEstate = require('./editEstate'); const deleteEstate = require('./deleteEstate'); +const getEstate = require('./getEstate'); module.exports = { editEstate, deleteEstate, + getEstate, }; diff --git a/server/controllers/index.js b/server/controllers/index.js index 1debce4..2ae366d 100644 --- a/server/controllers/index.js +++ b/server/controllers/index.js @@ -1,11 +1,18 @@ const { userEstateshandler, putAgent, getAllUsers, login, } = require('./users'); -const { deleteEstate, editEstate } = require('./estates'); +const { deleteEstate, editEstate, getEstate } = require('./estates'); const logout = require('./logout'); const { adminLogin } = require('./admins'); module.exports = { - getAllUsers, userEstateshandler, logout, login, deleteEstate, editEstate, putAgent,adminLogin - + getAllUsers, + userEstateshandler, + logout, + login, + deleteEstate, + editEstate, + putAgent, + adminLogin, + getEstate, }; diff --git a/server/controllers/users/userEstates.js b/server/controllers/users/userEstates.js index 5f7a1ae..72a1c5f 100644 --- a/server/controllers/users/userEstates.js +++ b/server/controllers/users/userEstates.js @@ -1,13 +1,15 @@ -const { userEstatesQuery } = require('../../database/quieres/index'); +const { userEstatesQuery, agentQuery } = require('../../database/quieres/index'); const userEstateshandler = async (req, res) => { const { userId } = req.params; try { if (userId > 0) { - const { rows } = await userEstatesQuery(userId); + const { rows: agentData } = await agentQuery(userId); + const { rows: estateData } = await userEstatesQuery(userId); return res.json({ - data: rows, + agentData, + estateData, }); } return res.status(404).json({ diff --git a/server/database/quieres/agentQuery.js b/server/database/quieres/agentQuery.js new file mode 100644 index 0000000..d01f8ba --- /dev/null +++ b/server/database/quieres/agentQuery.js @@ -0,0 +1,3 @@ +const connection = require('../config/connection'); + +module.exports = (userId) => connection.query('SELECT agents.id, agents.name,agents.email,agents.phone,agents.avater FROM agents WHERE agents.id = ($1) ', [userId]); diff --git a/server/database/quieres/getEstateQuery.js b/server/database/quieres/getEstateQuery.js new file mode 100644 index 0000000..69dc62a --- /dev/null +++ b/server/database/quieres/getEstateQuery.js @@ -0,0 +1,3 @@ +const connection = require('../config/connection'); + +module.exports = (estateId) => connection.query('SELECT * FROM estates where estates.id = $1;', [estateId]); diff --git a/server/database/quieres/getImagesQuery.js b/server/database/quieres/getImagesQuery.js new file mode 100644 index 0000000..d81deee --- /dev/null +++ b/server/database/quieres/getImagesQuery.js @@ -0,0 +1,3 @@ +const connection = require('../config/connection'); + +module.exports = (estateId) => connection.query('SELECT image FROM images where estate_id = $1;', [estateId]); diff --git a/server/database/quieres/index.js b/server/database/quieres/index.js index 56839d0..c549e84 100644 --- a/server/database/quieres/index.js +++ b/server/database/quieres/index.js @@ -7,6 +7,9 @@ const checkEmailQuery = require('./checkEmailQuery'); const editEstateQuery = require('./editEstatesQuery'); const deleteEstateQuery = require('./deleteEstateQuery'); const signUpAdminQuery = require('./signUpAdminQuery'); +const agentQuery = require('./agentQuery'); +const getImagesQuery = require('./getImagesQuery'); +const getEstateQuery = require('./getEstateQuery'); module.exports = { getAllUsersQuery, @@ -18,4 +21,7 @@ module.exports = { editEstateQuery, deleteEstateQuery, signUpAdminQuery, + agentQuery, + getImagesQuery, + getEstateQuery, }; diff --git a/server/database/quieres/userEstatesQuiery.js b/server/database/quieres/userEstatesQuiery.js index f1b86ed..8b94ced 100644 --- a/server/database/quieres/userEstatesQuiery.js +++ b/server/database/quieres/userEstatesQuiery.js @@ -1,3 +1,3 @@ const connection = require('../config/connection'); -module.exports = (userId) => connection.query('SELECT * FROM estates WHERE agent_id = $1', [userId]); +module.exports = (userId) => connection.query('SELECT estates.id, estates.title ,estates.description , estates.type,estates.category FROM estates WHERE estates.id = ($1) ', [userId]); diff --git a/server/routes/estate.js b/server/routes/estate.js index 47d4f75..7db0577 100644 --- a/server/routes/estate.js +++ b/server/routes/estate.js @@ -1,7 +1,9 @@ const router = require('express').Router(); const { isAuth } = require('../middleware'); -const { editEstate, deleteEstate } = require('../controllers'); +const { editEstate, deleteEstate, getEstate } = require('../controllers'); router.put('/:estateId', editEstate); +router.get('/:estateId', getEstate); + router.delete('/:estateId', isAuth, deleteEstate); module.exports = router; diff --git a/test.js b/test.js new file mode 100644 index 0000000..e69de29