├── .firebaserc ├── public ├── robots.txt ├── favicon.ico ├── logo192.png ├── logo512.png ├── manifest.json ├── reviews.json ├── index.html ├── pricing.json ├── properties.json ├── review.json ├── projects.json ├── engineers.json ├── card.json └── Blog.json ├── src ├── Pages │ ├── Homepage │ │ ├── Banner │ │ │ ├── note.js │ │ │ └── Banner.js │ │ ├── AddReview │ │ │ └── AddReview.css │ │ ├── projects │ │ │ ├── Project.css │ │ │ ├── Project.js │ │ │ └── Projects.js │ │ ├── Engineers │ │ │ ├── Engineers.css │ │ │ └── Engineers.js │ │ ├── Testimonials │ │ │ ├── Review.js │ │ │ └── Testimonials.js │ │ ├── Notice │ │ │ └── Notice.js │ │ ├── Home │ │ │ └── Home.js │ │ ├── Cards │ │ │ └── Cards.js │ │ ├── Card │ │ │ └── Card.js │ │ ├── Guide │ │ │ └── Guide.js │ │ ├── Pricing │ │ │ ├── PricingCard.js │ │ │ ├── PremiumPay.js │ │ │ └── PricingPay.js │ │ ├── Guides │ │ │ └── Guides.js │ │ ├── NewsLetter │ │ │ └── NewsLetter.js │ │ ├── AboutUs │ │ │ └── AboutUs.js │ │ ├── Engineer │ │ │ ├── Engineer.js │ │ │ └── Engineer.css │ │ ├── Reviews │ │ │ └── Reviews.js │ │ └── BookReview │ │ │ └── BookReview.js │ ├── ResumeBuilder │ │ ├── InputControl │ │ │ ├── InputControl.js │ │ │ └── InputControl.module.css │ │ ├── Header │ │ │ ├── Header.module.css │ │ │ └── Header.js │ │ ├── Body │ │ │ ├── Body.module.css │ │ │ └── Body.js │ │ ├── Editor │ │ │ └── Editor.module.css │ │ └── Resume │ │ │ └── Resume.module.css │ ├── Properties │ │ ├── PropertiesPage.js │ │ ├── Property.js │ │ ├── Properties.js │ │ └── PropertySearchBar.js │ ├── SearchRoute │ │ ├── Searches.css │ │ ├── Search.js │ │ └── Searches.js │ ├── Profile │ │ └── Profile.js │ ├── ServiceDetails │ │ ├── WorkerRow.js │ │ ├── EngineerRow.js │ │ ├── WorkersTable.js │ │ ├── EngineersTable.js │ │ └── ServiceDetails.js │ ├── Dashboardpage │ │ ├── Constructors │ │ │ ├── UpdateModal.js │ │ │ ├── Constructor.js │ │ │ └── Constructors.js │ │ ├── orders │ │ │ ├── Orders.js │ │ │ └── OrderRow.js │ │ └── myOrders │ │ │ ├── BookingPayment.js │ │ │ ├── MyOrderRow.js │ │ │ ├── CheckoutForm.js │ │ │ └── forEngineer │ │ │ ├── AcceptModal.js │ │ │ └── MyHiringRow.js │ └── Payment │ │ └── Payment.js ├── Assest │ ├── Contact.gif │ ├── virustotal-svgrepo-com.svg │ ├── facebook.svg │ ├── google.svg │ ├── construction-dashbord.svg │ ├── book-svgrepo-com.svg │ ├── engineer-dashbord.svg │ ├── user-dashbord.svg │ ├── download-svgrepo-com.svg │ ├── images │ │ └── orders-icon.svg │ ├── user-profile-svgrepo-com.svg │ └── review-dashbord.svg ├── redux │ ├── actions │ │ └── index.js │ ├── store.js │ └── reducers │ │ ├── index.js │ │ └── upDown.js ├── setupTests.js ├── Shared │ └── Loading │ │ ├── SmallLoading.js │ │ ├── Loading.js │ │ └── Loading.css ├── App.test.js ├── components │ ├── Navbar │ │ ├── Navbar.css │ │ └── Notification │ │ │ ├── Notificaton.js │ │ │ └── NotificationModal.js │ └── NotFound │ │ └── NotFound.css ├── hooks │ ├── useProjects.js │ ├── useServices.js │ ├── useWorker.js │ ├── useBooking.js │ ├── useServiceDetails.js │ ├── useWorkers.js │ ├── useEngineer.js │ ├── useToken.js │ ├── useRole.js │ ├── useAuthEngineer.js │ └── useEngineers.js ├── reportWebVitals.js ├── App.css ├── index.css ├── firebase.init.js ├── index.js ├── Auth │ ├── RequireAuth.js │ └── RequireAdmin.js └── logo.svg ├── firebase.json ├── .gitignore ├── tailwind.config.js ├── .vscode └── settings.json ├── package.json ├── README.md └── .firebase └── hosting.YnVpbGQ.cache /.firebaserc: -------------------------------------------------------------------------------- 1 | { 2 | "projects": { 3 | "default": "neighbour-home" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /src/Pages/Homepage/Banner/note.js: -------------------------------------------------------------------------------- 1 | // color combination 2 | // font size responsiveness 3 | // -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khanshorif331/neighbour-home/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khanshorif331/neighbour-home/HEAD/public/logo192.png -------------------------------------------------------------------------------- /public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khanshorif331/neighbour-home/HEAD/public/logo512.png -------------------------------------------------------------------------------- /src/Assest/Contact.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khanshorif331/neighbour-home/HEAD/src/Assest/Contact.gif -------------------------------------------------------------------------------- /src/Pages/Homepage/AddReview/AddReview.css: -------------------------------------------------------------------------------- 1 | button { 2 | /* background-color: transparent; */ 3 | /* border: none; */ 4 | /* outline: none; */ 5 | cursor: pointer; 6 | } 7 | .on { 8 | color: rgb(255, 209, 5); 9 | } 10 | .off { 11 | color: #ccc; 12 | } 13 | -------------------------------------------------------------------------------- /src/redux/actions/index.js: -------------------------------------------------------------------------------- 1 | export const incNumber = num => { 2 | return { 3 | type: 'INCREMENT', 4 | payload: num, 5 | } 6 | } 7 | export const decNumber = num => { 8 | return { 9 | type: 'DECREMENT', 10 | payload: num, 11 | } 12 | } 13 | // actions 14 | -------------------------------------------------------------------------------- /src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /src/Shared/Loading/SmallLoading.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import './Loading.css'; 3 | 4 | const SmallLoading = () => { 5 | return ( 6 |
7 |
8 | ); 9 | }; 10 | 11 | export default SmallLoading; -------------------------------------------------------------------------------- /src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react' 2 | import App from './App' 3 | 4 | test('renders learn react link', () => { 5 | render() 6 | const linkElement = screen.getByText(/learn react/i) 7 | expect(linkElement).toBeInTheDocument() 8 | }) 9 | -------------------------------------------------------------------------------- /firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "hosting": { 3 | "public": "build", 4 | "ignore": [ 5 | "firebase.json", 6 | "**/.*", 7 | "**/node_modules/**" 8 | ], 9 | "rewrites": [ 10 | { 11 | "source": "**", 12 | "destination": "/index.html" 13 | } 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/redux/store.js: -------------------------------------------------------------------------------- 1 | import rootReducer from './reducers/index' 2 | import { createStore } from 'redux' 3 | 4 | // the second paremeter is only for redux devtools 5 | const store = createStore( 6 | rootReducer, 7 | window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__() 8 | ) 9 | 10 | export default store 11 | -------------------------------------------------------------------------------- /src/Assest/virustotal-svgrepo-com.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/components/Navbar/Navbar.css: -------------------------------------------------------------------------------- 1 | #menu-toggle:checked+#menu { 2 | display: block; 3 | } 4 | 5 | #dropdown-toggle:checked+#dropdown { 6 | display: block; 7 | } 8 | nav li a:hover{ 9 | color: rgb(0, 238, 255); 10 | } 11 | 12 | .mobile-manu a{ 13 | margin: 7px auto; 14 | } 15 | .mobile-manu a:hover{ 16 | color: rgb(15, 131, 139); 17 | 18 | } -------------------------------------------------------------------------------- /src/redux/reducers/index.js: -------------------------------------------------------------------------------- 1 | import changeTheNumber from './upDown' 2 | 3 | import { combineReducers } from 'redux' 4 | 5 | const rootReducer = combineReducers({ 6 | // all the reducers will be here in this object 7 | // changeTheNumber : changeTheNumber, ; same thing ,,we can write any 8 | changeTheNumber, 9 | }) 10 | 11 | export default rootReducer 12 | -------------------------------------------------------------------------------- /src/redux/reducers/upDown.js: -------------------------------------------------------------------------------- 1 | const initialState = 0 2 | const changeTheNumber = (state = initialState, action) => { 3 | switch (action.type) { 4 | case 'INCREMENT': 5 | return state + action.payload 6 | case 'DECREMENT': 7 | return state - action.payload 8 | default: 9 | return state 10 | } 11 | } 12 | 13 | export default changeTheNumber 14 | -------------------------------------------------------------------------------- /src/Shared/Loading/Loading.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import './Loading.css' 3 | 4 | const Loading = () => { 5 | return ( 6 |
7 |
8 |
9 | ); 10 | }; 11 | 12 | export default Loading; -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /src/Pages/ResumeBuilder/InputControl/InputControl.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import styles from "./InputControl.module.css"; 4 | 5 | function InputControl({ label, ...props }) { 6 | return ( 7 |
8 | {label && } 9 | 10 |
11 | ); 12 | } 13 | 14 | export default InputControl; 15 | -------------------------------------------------------------------------------- /src/hooks/useProjects.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react" 2 | 3 | const useProjects = () =>{ 4 | const [projects, setProjects] = useState([]); 5 | useEffect( () =>{ 6 | fetch('projects.json') 7 | .then(res => res.json()) 8 | .then(data => setProjects(data)); 9 | 10 | },[projects, setProjects]); 11 | return [projects, setProjects]; 12 | } 13 | export default useProjects; -------------------------------------------------------------------------------- /src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /src/hooks/useServices.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react' 2 | 3 | const useServices = () => { 4 | const [services, setServices] = useState([]) 5 | useEffect(() => { 6 | fetch('https://neighbour-home-backend.onrender.com/constructor') 7 | .then(res => res.json()) 8 | .then(data => setServices(data)) 9 | }, [services, setServices]) 10 | return [services, setServices] 11 | } 12 | export default useServices 13 | -------------------------------------------------------------------------------- /src/hooks/useWorker.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react' 2 | 3 | const useWorker = workerId => { 4 | const [worker, setWorker] = useState({}) 5 | useEffect(() => { 6 | fetch(`https://neighbour-home-backend.onrender.com/user/${workerId}`) 7 | .then(res => res.json()) 8 | .then(data => setWorker(data)) 9 | }, [worker, workerId, setWorker]) 10 | return [worker, setWorker] 11 | } 12 | export default useWorker 13 | -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | 2 | .App { 3 | text-align: center; 4 | } 5 | 6 | .dark-theme{ 7 | background: rgb(25, 34, 60); 8 | /* color: #297bbe; */ 9 | } 10 | 11 | /* scrollbar design here */ 12 | html::-webkit-scrollbar{ 13 | width:1.4rem; 14 | } 15 | 16 | html::-webkit-scrollbar-track{ 17 | background:rgba(159, 159, 159, 0.187); 18 | } 19 | 20 | html::-webkit-scrollbar-thumb{ 21 | background:#225d50; 22 | border-radius: 10px; 23 | border: 3px outset #0d9488; 24 | } -------------------------------------------------------------------------------- /src/hooks/useBooking.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react' 2 | 3 | const useBooking = engineerId => { 4 | const [booking, setBooking] = useState({}) 5 | useEffect(() => { 6 | fetch( 7 | `https://neighbour-home-backend.onrender.com/engineer/${engineerId}` 8 | ) 9 | .then(res => res.json()) 10 | .then(data => setBooking(data)) 11 | }, [booking, engineerId, setBooking]) 12 | return [booking, setBooking] 13 | } 14 | export default useBooking 15 | -------------------------------------------------------------------------------- /src/hooks/useServiceDetails.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react' 2 | 3 | const useServiceDetails = serviceId => { 4 | const [service, setService] = useState({}) 5 | useEffect(() => { 6 | const url = `https://neighbour-home-backend.onrender.com/constructor/${serviceId}` 7 | fetch(url) 8 | .then(res => res.json()) 9 | .then(data => setService(data)) 10 | }, [service, serviceId]) 11 | return [service, setService] 12 | } 13 | 14 | export default useServiceDetails 15 | -------------------------------------------------------------------------------- /src/Pages/Homepage/projects/Project.css: -------------------------------------------------------------------------------- 1 | .project-image::before { 2 | content: ""; 3 | border: 1px solid #FFF; 4 | position: absolute; 5 | top: 10px; 6 | left: 10px; 7 | bottom: 10px; 8 | right: 10px; 9 | z-index: 1; 10 | } 11 | .project-overley { 12 | transition: all .4s; 13 | } 14 | .project-overley-body:hover .project-overley { 15 | width: 100%; 16 | height: 100%; 17 | } 18 | .project-overley:hover .project-content { 19 | opacity: 1; 20 | } -------------------------------------------------------------------------------- /src/Pages/ResumeBuilder/InputControl/InputControl.module.css: -------------------------------------------------------------------------------- 1 | .container { 2 | display: flex; 3 | flex-direction: column; 4 | gap: 5px; 5 | } 6 | 7 | label { 8 | font-weight: 500; 9 | font-size: 1rem; 10 | } 11 | 12 | .inputControlCss { 13 | border: 1px solid #cccccc; 14 | outline: none; 15 | padding: 10px 12px; 16 | font-size: 1rem; 17 | border-radius: 5px; 18 | } 19 | 20 | .inputControlCss:hover { 21 | border: 1px solid #adadad; 22 | } 23 | 24 | .inputControlCss:focus { 25 | border: 1px solid #239ce2; 26 | } -------------------------------------------------------------------------------- /src/hooks/useWorkers.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react' 2 | 3 | const useWorkers = () => { 4 | const [workers, setWorkers] = useState([]) 5 | const [loading, setLoading] = useState(true) 6 | useEffect(() => { 7 | fetch('https://neighbour-home-backend.onrender.com/getUserByRole/Worker') 8 | .then(res => res.json()) 9 | .then(data => { 10 | setWorkers(data) 11 | setLoading(false) 12 | }) 13 | }, [workers, loading, setWorkers]) 14 | return [workers, setWorkers] 15 | } 16 | export default useWorkers 17 | -------------------------------------------------------------------------------- /src/Assest/facebook.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: [ 4 | "./src/**/*.{js,jsx,ts,tsx}", 5 | ], 6 | daisyui: { 7 | themes: [ 8 | { 9 | mytheme: { 10 | "primary": "#225d50", 11 | "secondary": "rgb(51, 51, 51)", 12 | "accent": "#37CDBE", 13 | "neutral": "#3D4451", 14 | "base-100": "#FFFFFF", 15 | "info": "#3ABFF8", 16 | "success": "#36D399", 17 | "warning": "#FBBD23", 18 | "error": "#F87272", 19 | }, 20 | }, 21 | ], 22 | }, 23 | plugins: [require("daisyui")], 24 | } -------------------------------------------------------------------------------- /src/hooks/useEngineer.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react' 2 | 3 | const useEngineer = engineerId => { 4 | const [engineer, setEngineer] = useState({}) 5 | const [enLoading, setEnLoading] = useState(true) 6 | useEffect(() => { 7 | fetch(`https://neighbour-home-backend.onrender.com/user/${engineerId}`) 8 | .then(res => res.json()) 9 | .then(data => { 10 | setEngineer(data) 11 | setEnLoading(false) 12 | }) 13 | }, [engineer, engineerId, enLoading, setEngineer]) 14 | return [engineer, setEngineer] 15 | } 16 | export default useEngineer 17 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Merriweather:wght@300;400;700;900&family=Open+Sans:wght@400;500;600;700;800&family=Oswald:wght@300;400;500;600;700&family=Poly&family=Poppins:wght@200;300;400;500;600;700;800;900&family=Rajdhani:wght@400;500;600;700&family=Raleway:wght@300;400;500;600;700;800&family=Roboto+Slab:wght@200;400;500;600;700;800;900&family=Roboto:wght@300;400;500;700;900&display=swap"); 2 | 3 | @tailwind base; 4 | @tailwind components; 5 | @tailwind utilities; 6 | 7 | body { 8 | font-family: "Raleway", sans-serif; 9 | } 10 | 11 | 12 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /src/Pages/Homepage/Engineers/Engineers.css: -------------------------------------------------------------------------------- 1 | #app { height: 100% } 2 | html, 3 | body { 4 | position: relative; 5 | height: 100%; 6 | } 7 | 8 | body { 9 | background: #eee; 10 | font-family: Helvetica Neue, Helvetica, Arial, sans-serif; 11 | font-size: 14px; 12 | color: #000; 13 | margin: 0; 14 | padding: 0; 15 | } 16 | 17 | .swiper { 18 | width: 100%; 19 | padding-top: 50px; 20 | padding-bottom: 50px; 21 | } 22 | 23 | .swiper-slide { 24 | background-position: center; 25 | background-size: cover; 26 | width: 300px; 27 | height: 300px; 28 | } 29 | 30 | .swiper-slide img { 31 | display: block; 32 | width: 100%; 33 | } -------------------------------------------------------------------------------- /src/Pages/ResumeBuilder/Header/Header.module.css: -------------------------------------------------------------------------------- 1 | .container { 2 | padding: 50px 30px; 3 | text-align: center; 4 | width: 100%; 5 | display: flex; 6 | align-items: center; 7 | justify-content: space-evenly; 8 | gap: 30px; 9 | background-color: rgb(238, 252, 255); 10 | min-height: 85vh; 11 | } 12 | 13 | .heading { 14 | margin: 0 auto; 15 | max-width: 500px; 16 | color: #000; 17 | font-size: 3.1rem; 18 | line-height: 4.1rem; 19 | font-weight: bold; 20 | letter-spacing: 1px; 21 | } 22 | 23 | .heading span { 24 | background-clip: text; 25 | background-image: linear-gradient(to right, #239ce2, #1369b9); 26 | color: transparent; 27 | } 28 | 29 | .right img { 30 | width: 400px; 31 | } 32 | -------------------------------------------------------------------------------- /src/Pages/ResumeBuilder/Header/Header.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import resumeSvg from "../../assets/resume.svg"; 4 | 5 | import styles from "./Header.module.css"; 6 | 7 | function Header() { 8 | return ( 9 |
10 |
11 |

12 | A Resume that stands out! 13 |

14 |

15 | Make your own resume. It's free 16 |

17 |
18 |
19 | Resume 20 |
21 |
22 | ); 23 | } 24 | 25 | export default Header; 26 | -------------------------------------------------------------------------------- /src/Pages/Homepage/Testimonials/Review.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Review = ({review}) => { 4 | 5 | return ( 6 |
7 | {review.comment} 8 |
9 | 10 |
11 |

{review.name}

12 |
{review.position}
13 |
14 |
15 |
16 | ); 17 | }; 18 | 19 | export default Review; -------------------------------------------------------------------------------- /src/Pages/Properties/PropertiesPage.js: -------------------------------------------------------------------------------- 1 | import { useQuery } from '@tanstack/react-query' 2 | import React from 'react' 3 | import Properties from './Properties' 4 | import PropertySearchBar from './PropertySearchBar' 5 | 6 | const PropertiesPage = () => { 7 | const { 8 | isLoading, 9 | error, 10 | data: properties, 11 | refetch, 12 | } = useQuery(['properties'], () => 13 | fetch('https://neighbour-home-backend.onrender.com/sellPost').then(res => 14 | res.json() 15 | ) 16 | ) 17 | return ( 18 |
22 | 27 |
28 | ) 29 | } 30 | 31 | export default PropertiesPage 32 | -------------------------------------------------------------------------------- /src/firebase.init.js: -------------------------------------------------------------------------------- 1 | // Import the functions you need from the SDKs you need 2 | import { initializeApp } from "firebase/app"; 3 | import { getAuth } from 'firebase/auth' 4 | // TODO: Add SDKs for Firebase products that you want to use 5 | // https://firebase.google.com/docs/web/setup#available-libraries 6 | 7 | // Your web app's Firebase configuration 8 | const firebaseConfig = { 9 | apiKey: process.env.REACT_APP_API_KEY, 10 | authDomain: process.env.REACT_APP_AUTH_DOMAIN, 11 | projectId: process.env.REACT_APP_PROTECT_ID, 12 | storageBucket: process.env.REACT_APP_STORAGE_BUCKET, 13 | messagingSenderId: process.env.REACT_APP_MESSAGING_SENDER_ID, 14 | appId: process.env.REACT_APP_APP_ID 15 | }; 16 | 17 | // Initialize Firebase 18 | const app = initializeApp(firebaseConfig); 19 | 20 | const auth = getAuth(app) 21 | 22 | export default auth -------------------------------------------------------------------------------- /src/hooks/useToken.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react' 2 | 3 | const useToken = user => { 4 | const [token, setToken] = useState('') 5 | useEffect(() => { 6 | const email = user?.user?.email 7 | const currentUser = { email: email } 8 | if (email) { 9 | fetch(`https://neighbour-home-backend.onrender.com/user`, { 10 | method: 'POST', 11 | headers: { 12 | 'content-type': 'application/json', 13 | }, 14 | body: JSON.stringify(currentUser), 15 | }) 16 | .then(res => res.json()) 17 | .then(data => { 18 | console.log('data inside useToken', data) 19 | // const accessToken = data.token 20 | // localStorage.setItem('accessToken', accessToken) 21 | // setToken(accessToken) 22 | setToken(data) 23 | }) 24 | } 25 | }, [user]) 26 | return [token] 27 | } 28 | 29 | export default useToken 30 | -------------------------------------------------------------------------------- /src/hooks/useRole.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | import { useEffect, useState } from 'react' 3 | import { useAuthState } from 'react-firebase-hooks/auth' 4 | import auth from '../firebase.init' 5 | import Loading from '../Shared/Loading/Loading' 6 | 7 | const useRole = e => { 8 | const [role, setrole] = useState('') 9 | const [roleLoading, setRoleLoading] = useState(true) 10 | let [user, loading] = useAuthState(auth) 11 | useEffect(() => { 12 | if (user) { 13 | axios 14 | .get( 15 | `https://neighbour-home-backend.onrender.com/singleUserByEmail/${user?.email}` 16 | ) 17 | .then(data => { 18 | // console.log(data.data); 19 | setrole(data?.data?.role) 20 | setRoleLoading(false) 21 | }) 22 | } else { 23 | setRoleLoading(true) 24 | } 25 | }, [user]) 26 | 27 | return [role, roleLoading] 28 | } 29 | export default useRole 30 | -------------------------------------------------------------------------------- /public/reviews.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "Christoper Luis", 4 | "img": "https://htmldemo.net/oxybuild/oxybuild/assets/images/testimonial/avatar/1-1-46x46.png", 5 | "comment": "Publishing packages and web page now use Lorem Ipsum as their mel text, and a search for lorem more than one articel a is very important which can be help us for building a beauiful construction", 6 | "position": "CEO, Octafact Group" 7 | }, 8 | { 9 | "name": "Rayana Begum", 10 | "img": "https://htmldemo.net/oxybuild/oxybuild/assets/images/testimonial/avatar/1-2-46x46.png", 11 | "comment": "Publishing packages and web page now use Lorem Ipsum as their mel text, and a search for lorem more than one articel a is very important which can be help us for building a beauiful construction", 12 | "position": "CEO, Xerox Ltd. Group" 13 | } 14 | ] -------------------------------------------------------------------------------- /src/hooks/useAuthEngineer.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react' 2 | 3 | const useAuthEngineer = user => { 4 | const [authEngineer, setAuthEngineer] = useState(false) 5 | const [engineerLoading, setEngineerLoading] = useState(true) 6 | useEffect(() => { 7 | const email = user?.email 8 | if (email) { 9 | fetch( 10 | `https://neighbour-home-backend.onrender.com/authEngineer/${email}`, 11 | { 12 | method: 'GET', 13 | headers: { 14 | 'content-type': 'application/json', 15 | // authorization: `Bearer ${localStorage.getItem('accessToken')}` 16 | }, 17 | } 18 | ) 19 | .then(res => res.json()) 20 | .then(data => { 21 | setAuthEngineer(data.authEngineer) 22 | setEngineerLoading(false) 23 | }) 24 | } 25 | }, [user]) 26 | return [authEngineer, engineerLoading] 27 | } 28 | 29 | export default useAuthEngineer 30 | -------------------------------------------------------------------------------- /src/Pages/Homepage/Engineers/Engineers.js: -------------------------------------------------------------------------------- 1 | import React, { useContext } from "react"; 2 | import { DarkModeContext } from "../../../App"; 3 | import Engineer from "../Engineer/Engineer"; 4 | 5 | const Engineers = () => { 6 | const [darkMode, setDarkMode] = useContext(DarkModeContext) 7 | 8 | return ( 9 |
10 |

11 | Our Engineers and Architecture's 12 |

13 |
14 |
15 |
16 |
17 |
18 | 19 |
20 | ); 21 | }; 22 | 23 | export default Engineers; 24 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import './index.css' 4 | import App from './App' 5 | import reportWebVitals from './reportWebVitals' 6 | import { BrowserRouter } from 'react-router-dom' 7 | import store from './redux/store' 8 | import { Provider } from 'react-redux' 9 | 10 | store.subscribe(() => { 11 | console.log(store.getState()) 12 | }) 13 | 14 | const root = ReactDOM.createRoot(document.getElementById('root')) 15 | root.render( 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | ) 24 | 25 | // If you want to start measuring performance in your app, pass a function 26 | // to log results (for example: reportWebVitals(console.log)) 27 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 28 | reportWebVitals() 29 | -------------------------------------------------------------------------------- /src/Auth/RequireAuth.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { useAuthState } from 'react-firebase-hooks/auth'; 3 | import { Navigate, useLocation } from 'react-router-dom'; 4 | import auth from '../firebase.init'; 5 | import Loading from '../Shared/Loading/Loading'; 6 | 7 | const RequireAuth = ({children}) => { 8 | let location = useLocation(); 9 | let [user, loading, error] = useAuthState(auth) 10 | // console.log(user); 11 | if (loading) return 12 | if (!user) { 13 | // Redirect them to the /login page, but save the current location they were 14 | // trying to go to when they were redirected. This allows us to send them 15 | // along to that page after they login, which is a nicer user experience 16 | // than dropping them off on the home page. 17 | return ; 18 | } 19 | 20 | return children; 21 | }; 22 | 23 | export default RequireAuth; -------------------------------------------------------------------------------- /src/Pages/SearchRoute/Searches.css: -------------------------------------------------------------------------------- 1 | /* From uiverse.io by @alexruix */ 2 | .group-1 { 3 | display: flex; 4 | line-height: 28px; 5 | align-items: center; 6 | position: relative; 7 | width: 80%; 8 | margin: 0 auto; 9 | } 10 | 11 | .input-1 { 12 | width: 100%; 13 | height: 40px; 14 | line-height: 28px; 15 | padding: 0 1rem; 16 | padding-left: 2.5rem; 17 | border: 2px solid transparent; 18 | border-radius: 8px; 19 | outline: none; 20 | background-color: #f3f3f4; 21 | color: #0d0c22; 22 | transition: .3s ease; 23 | } 24 | 25 | .input-1::placeholder { 26 | color: #9e9ea7; 27 | } 28 | 29 | .input-1:focus, 30 | .input-1:hover { 31 | outline: none; 32 | border-color: rgba(234, 76, 137, 0.4); 33 | background-color: #fff; 34 | box-shadow: 0 0 0 4px rgb(234 76 137 / 10%); 35 | } 36 | 37 | .icon-1 { 38 | position: absolute; 39 | left: 1rem; 40 | fill: #9e9ea7; 41 | width: 1rem; 42 | height: 1rem; 43 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "cSpell.words": ["noopener"] 3 | } // { 4 | // "workbench.colorCustomizations": { 5 | // "activityBar.activeBackground": "#93e6fc", 6 | // "activityBar.activeBorder": "#fa45d4", 7 | // "activityBar.background": "#93e6fc", 8 | // "activityBar.foreground": "#15202b", 9 | // "activityBar.inactiveForeground": "#15202b99", 10 | // "activityBarBadge.background": "#fa45d4", 11 | // "activityBarBadge.foreground": "#15202b", 12 | // "sash.hoverBorder": "#93e6fc", 13 | // "statusBar.background": "#61dafb", 14 | // "statusBar.foreground": "#15202b", 15 | // "statusBarItem.hoverBackground": "#2fcefa", 16 | // "statusBarItem.remoteBackground": "#61dafb", 17 | // "statusBarItem.remoteForeground": "#15202b", 18 | // "titleBar.activeBackground": "#61dafb", 19 | // "titleBar.activeForeground": "#15202b", 20 | // "titleBar.inactiveBackground": "#61dafb99", 21 | // "titleBar.inactiveForeground": "#15202b99" 22 | // }, 23 | // "peacock.color": "#61dafb" 24 | // } 25 | -------------------------------------------------------------------------------- /src/Assest/google.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/Pages/Homepage/Notice/Notice.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Marquee from "react-fast-marquee"; 3 | 4 | const Notice = () => { 5 | return ( 6 |
7 |

11 | Notice : 12 |

13 | 14 | {" "} 15 |
19 | Construction notices are one of the most underrated tools in the 20 | industry. Communication is, unfortunately, a big problem on 21 | construction projects; and notices are a great way to start fixing it. 22 |
23 |
24 |
25 | ); 26 | }; 27 | 28 | export default Notice; 29 | -------------------------------------------------------------------------------- /src/Pages/Homepage/Home/Home.js: -------------------------------------------------------------------------------- 1 | import React, { useContext } from "react"; 2 | import Banner from "../Banner/Banner"; 3 | import Cards from "../Cards/Cards"; 4 | import Contact from "../Contact/Contact"; 5 | import Engineers from "../Engineers/Engineers"; 6 | import Notice from "../Notice/Notice"; 7 | import Guide from "../Guide/Guide"; 8 | import Testimonials from "../Testimonials/Testimonials"; 9 | import NewsLetter from "../NewsLetter/NewsLetter"; 10 | import Reviews from "../Reviews/Reviews"; 11 | import AboutUs from "../AboutUs/AboutUs"; 12 | import Statistics from "../Statistics/Statistics"; 13 | import Pricing from "../Pricing/Pricing"; 14 | import Projects from "../projects/Projects"; 15 | 16 | const Home = () => { 17 | return ( 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
32 | ); 33 | }; 34 | 35 | export default Home; 36 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 14 | Neighbour Home 15 | 16 | 17 | 18 |
19 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/Auth/RequireAdmin.js: -------------------------------------------------------------------------------- 1 | import { signOut } from 'firebase/auth' 2 | import React from 'react' 3 | import { Loader } from 'react-feather' 4 | import { useAuthState } from 'react-firebase-hooks/auth' 5 | import toast from 'react-hot-toast' 6 | import { Navigate, useLocation } from 'react-router-dom' 7 | import auth from '../firebase.init' 8 | import useRole from '../hooks/useRole' 9 | import Loading from '../Shared/Loading/Loading' 10 | 11 | const RequireAuth = ({ children }) => { 12 | let [user, loading, error] = useAuthState(auth) 13 | let [role, roleLoading] = useRole(user) 14 | 15 | if (loading || roleLoading) { 16 | return ; 17 | } 18 | if (!user || role !== 'admin') { 19 | // Redirect them to the /login page, but save the current location they were 20 | // trying to go to when they were redirected. This allows us to send them 21 | // along to that page after they login, which is a nicer user experience 22 | // than dropping them off on the home page. 23 | toast.error('This is Protected for only Admin', { id: 'requireAdmin' }) 24 | signOut(auth) 25 | return 26 | } 27 | return children 28 | } 29 | 30 | export default RequireAuth 31 | -------------------------------------------------------------------------------- /src/Pages/Profile/Profile.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Link, Outlet } from 'react-router-dom'; 3 | 4 | const Profile = () => { 5 | return ( 6 |
7 |
8 |
9 |
    10 |
  • My Profile
  • 11 |
  • Address
  • 12 |
  • Education
  • 13 |
  • Important Links
  • 14 |
15 |
16 |
17 | 18 |
19 |
20 |
21 | ); 22 | }; 23 | 24 | export default Profile; -------------------------------------------------------------------------------- /src/Pages/Homepage/Cards/Cards.js: -------------------------------------------------------------------------------- 1 | import React, { useContext, useEffect, useState } from 'react' 2 | import useServices from '../../../hooks/useServices' 3 | import Card from '../Card/Card' 4 | import { DarkModeContext } from '../../../App' 5 | 6 | const Cards = () => { 7 | const [services] = useServices([]) 8 | const [darkMode, setDarkMode] = useContext(DarkModeContext) 9 | return ( 10 |
11 |

17 | Our Services 18 |

19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | {services.map(service => ( 27 | 28 | ))} 29 |
30 |
31 |
32 | ) 33 | } 34 | 35 | export default Cards 36 | -------------------------------------------------------------------------------- /src/Pages/ResumeBuilder/Body/Body.module.css: -------------------------------------------------------------------------------- 1 | .container { 2 | padding: 30px; 3 | display: flex; 4 | flex-direction: column; 5 | align-items: center; 6 | gap: 30px; 7 | padding-top: 0; 8 | } 9 | 10 | .heading { 11 | font-weight: 500; 12 | font-size: 2.1rem; 13 | } 14 | 15 | .toolbar { 16 | width: 100%; 17 | display: flex; 18 | gap: 40px; 19 | justify-content: space-between; 20 | align-items: center; 21 | } 22 | 23 | .colors { 24 | display: flex; 25 | gap: 20px; 26 | padding: 0 30px; 27 | } 28 | 29 | .colors .color { 30 | height: 36px; 31 | width: 36px; 32 | border-radius: 50%; 33 | background-color: #239ce2; 34 | } 35 | .colors .active { 36 | border: 2px solid #000; 37 | } 38 | 39 | .toolbar button { 40 | padding: 8px 16px; 41 | border-radius: 5px; 42 | background-color: #239ce2; 43 | color: #fff; 44 | outline: none; 45 | border: none; 46 | font-weight: 500; 47 | font-size: 1rem; 48 | letter-spacing: 1px; 49 | display: flex; 50 | gap: 5px; 51 | align-items: center; 52 | cursor: pointer; 53 | } 54 | 55 | .toolbar button svg { 56 | height: 20px; 57 | width: 20px; 58 | } 59 | 60 | .main { 61 | display: flex; 62 | flex-direction: column; 63 | gap: 30px; 64 | width: 100%; 65 | } 66 | -------------------------------------------------------------------------------- /src/Pages/ServiceDetails/WorkerRow.js: -------------------------------------------------------------------------------- 1 | import React, { useContext, useState } from "react"; 2 | import { Link } from "react-router-dom"; 3 | import { DarkModeContext } from "../../App"; 4 | 5 | const WorkerRow = ({ index, worker }) => { 6 | const [darkMode, setDarkMode] = useContext(DarkModeContext); 7 | const { name, photo, _id, email, address, country, nid, phone, role, userName, zip } = worker; 8 | return ( 9 | 10 | {index + 1} 11 | 12 |
13 |
14 | {name} 15 |
16 |
17 | 18 | {name} 19 | {userName} 20 | 21 | 22 | 23 | 24 | 25 | 26 | ); 27 | }; 28 | 29 | export default WorkerRow; 30 | -------------------------------------------------------------------------------- /src/Assest/construction-dashbord.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/Pages/ServiceDetails/EngineerRow.js: -------------------------------------------------------------------------------- 1 | import React, { useContext, useState } from "react"; 2 | import { Link } from "react-router-dom"; 3 | import { DarkModeContext } from "../../App"; 4 | 5 | const EngineerRow = ({ index, engineer }) => { 6 | const [darkMode, setDarkMode] = useContext(DarkModeContext); 7 | const { name, photo, _id, email, address, country, nid, phone, role, userName, zip } = engineer; 8 | return ( 9 | 10 | {index + 1} 11 | 12 |
13 |
14 | {name} 15 |
16 |
17 | 18 | {name} 19 | {name} 20 | 21 | 22 | 23 | 24 | 25 | 26 | ); 27 | }; 28 | 29 | export default EngineerRow; 30 | -------------------------------------------------------------------------------- /src/components/Navbar/Notification/Notificaton.js: -------------------------------------------------------------------------------- 1 | import moment from 'moment'; 2 | import React from 'react'; 3 | import { MdCircleNotifications } from 'react-icons/md'; 4 | 5 | const Notificaton = ({ notification }) => { 6 | let today = moment().format(); 7 | var now = moment(today);//now 8 | var date = moment(notification.date); 9 | let time_ago = "0 Minute Ago"; 10 | 11 | const minutes = now.diff(date, 'minutes') 12 | const hours = now.diff(date, 'hours') 13 | const days = now.diff(date, 'days') 14 | const weeks = now.diff(date, 'weeks') 15 | if (minutes <= 60) { 16 | time_ago = `${minutes} Minutes Ago`; 17 | } 18 | else if (hours <= 24) { 19 | time_ago = `${hours} Hours Ago`; 20 | } 21 | else if (days <= 7) { 22 | time_ago = `${days} Days Ago`; 23 | } 24 | else { 25 | time_ago = `${weeks} Weeks Ago`; 26 | } 27 | // console.log(time_ago); 28 | 29 | return ( 30 |
31 | 32 |
33 |

{notification.heading}

34 |

{time_ago}

35 |
36 |
37 | ); 38 | }; 39 | 40 | export default Notificaton; -------------------------------------------------------------------------------- /src/Assest/book-svgrepo-com.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /src/Pages/Homepage/projects/Project.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | // import Loading from './../../../Shared/Loading'; 3 | import './Project.css' 4 | 5 | const Project = ({ project }) => { 6 | // if (!project.length) { 7 | // 8 | // } 9 | const { title, subtitle, image } = project; 10 | 11 | return ( 12 |
15 |
16 |
17 |
18 |
19 | 20 |

{title}

21 |
22 |

{subtitle}

23 |
24 |
25 |
26 |
27 |
28 | ); 29 | }; 30 | 31 | export default Project; -------------------------------------------------------------------------------- /src/Pages/SearchRoute/Search.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Search = ({ search }) => { 4 | 5 | console.log(search) 6 | const { body, email, name } = search 7 | 8 | return ( 9 | <> 10 |
11 |
12 | 13 |
14 |
15 |

16 | {body} 17 |

18 |
19 |
20 |
21 | Sarah Dayan 22 |
23 |
24 | Staff Engineer, Algolia 25 |
26 |
27 |
28 |
29 |
30 | 31 | ); 32 | }; 33 | 34 | export default Search; -------------------------------------------------------------------------------- /src/Pages/Homepage/projects/Projects.js: -------------------------------------------------------------------------------- 1 | import React, { useContext } from 'react'; 2 | import { DarkModeContext } from '../../../App'; 3 | import useProjects from '../../../hooks/useProjects'; 4 | import Project from './Project'; 5 | 6 | const Projects = () => { 7 | const [projects] = useProjects(); 8 | const [darkMode, setDarkMode] = useContext(DarkModeContext) 9 | return ( 10 |
11 |
12 |

our LATEST PROJECT

16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | { 24 | projects.map(project => ) 28 | } 29 |
30 |
31 | ); 32 | }; 33 | 34 | export default Projects; -------------------------------------------------------------------------------- /src/components/Navbar/Notification/NotificationModal.js: -------------------------------------------------------------------------------- 1 | import {IoMdNotificationsOff} from 'react-icons/io'; 2 | import {AiOutlineCloseCircle} from 'react-icons/ai'; 3 | import React from 'react' 4 | import Notificaton from './Notificaton'; 5 | const NotificationModal = ({setNotificationModal, notifications}) => { 6 | 7 | return ( 8 |
9 |
13 | 20 |
21 | { 22 | notifications.length === 0? 23 |
24 | 25 |
No Notification For You
26 |
27 | : 28 | notifications.map(notification => ).reverse() 32 | 33 | } 34 |
35 |
36 |
37 | ) 38 | } 39 | 40 | export default NotificationModal 41 | -------------------------------------------------------------------------------- /src/Shared/Loading/Loading.css: -------------------------------------------------------------------------------- 1 | .spinner-container { 2 | width: 100%; 3 | height: 100%; 4 | z-index: 99999; 5 | text-align: center; 6 | background-color: rgb(227, 28, 28); 7 | } 8 | 9 | .spinner { 10 | margin: auto; 11 | border: 2px solid #eee; 12 | /* 13 | change to dotted for something cool. 14 | change width to 1px for tapered bar 15 | */ 16 | width: 32px; 17 | height: 32px; 18 | display: inline-block; 19 | position: absolute; 20 | top: 45%; 21 | border-radius: 50%; 22 | border-right: 3px solid #018df7; 23 | text-align: center; 24 | animation-name: spin; 25 | animation-duration: 700ms; 26 | animation-iteration-count: infinite; 27 | animation-timing-function: linear; 28 | } 29 | 30 | @-webkit-keyframes spin { 31 | 0% { 32 | -webkit-transform: rotate(0deg); 33 | } 34 | 35 | 100% { 36 | -webkit-transform: rotate(360deg); 37 | } 38 | } 39 | 40 | @keyframes spin { 41 | 0% { 42 | transform: rotate(0deg); 43 | } 44 | 45 | 100% { 46 | transform: rotate(360deg); 47 | } 48 | } 49 | 50 | .smallLoading { 51 | width: 35px; 52 | margin: 15px 0; 53 | aspect-ratio: 1; 54 | --_c: radial-gradient(farthest-side, rgb(13, 148, 136) 92%, rgba(20, 97, 212, 0)); 55 | background: 56 | var(--_c) top, 57 | var(--_c) left, 58 | var(--_c) right, 59 | var(--_c) bottom; 60 | background-size: 12px 12px; 61 | background-repeat: no-repeat; 62 | animation: s7 1s infinite; 63 | } 64 | 65 | @keyframes s7 { 66 | to { 67 | transform: rotate(.5turn) 68 | } 69 | } -------------------------------------------------------------------------------- /src/Assest/engineer-dashbord.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 10 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/Assest/user-dashbord.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 10 | 12 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /public/pricing.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "_id": "623853bf61ad5aba311fdd1", 4 | "tag": "Beginner", 5 | "price": "Free", 6 | "period": "lifetime", 7 | "description": "This package is for small business. If you want to growth your company quickly please upgrade your package.", 8 | "benefit": { 9 | "one": "contact with engineers", 10 | "two": "Buy properties", 11 | "three": "Manage your works", 12 | "four": "Get 5% discount all orders", 13 | "five": "And more updated features" 14 | } 15 | }, 16 | { 17 | "_id": "623853bh614ad5aba11fdd1", 18 | "tag": "Pro", 19 | "price": "199", 20 | "period": "Yearly", 21 | "description": "This package is use for mid-level business company. For large scale company you can go our 'Business' package.", 22 | "benefit": { 23 | "one": "Contact with engineers", 24 | "two": "Buy and sell properties", 25 | "three": "Manage your works", 26 | "four": "Get 10% discount all orders", 27 | "five": "And more updated features" 28 | } 29 | }, 30 | { 31 | "_id": "623853b214ad5abb311fdd1", 32 | "tag": "Business", 33 | "price": "372", 34 | "period": "Yearly", 35 | "description": "This package is for Large scale company who can only get our fully premium package.", 36 | "benefit": { 37 | "one": "Contact with engineers", 38 | "two": "Buy and sell properties", 39 | "three": "Manage your works", 40 | "four": "Get 20% discount all orders", 41 | "five": "And more updated features", 42 | "six": "New premium features" 43 | } 44 | } 45 | ] 46 | -------------------------------------------------------------------------------- /src/Pages/Homepage/Card/Card.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Link } from 'react-router-dom'; 3 | import { useContext } from "react"; 4 | import { DarkModeContext } from "../../../App"; 5 | const Card = ({ service }) => { 6 | const { title, picture, _id, description } = service; 7 | const [darkMode, setDarkMode] = useContext(DarkModeContext) 8 | return ( 9 |
10 |
11 |
12 | Colors 13 | {/*

14 | {price} 15 |

*/} 16 | {/*

17 | {discount} 18 |

*/} 19 |
20 |

21 | {title} 22 |

23 |

24 | {description} 25 |

26 |
27 | 28 | 29 | 30 |
31 |
32 |
33 | ); 34 | }; 35 | 36 | export default Card; -------------------------------------------------------------------------------- /src/Pages/Dashboardpage/Constructors/UpdateModal.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Swal from 'sweetalert2' 3 | import FormConstructor from './FormConstructor' 4 | 5 | const UpdateModal = ({ id, constructor, refetch }) => { 6 | const updateInfo = data => { 7 | fetch(`https://neighbour-home-backend.onrender.com/constructor/${id}`, { 8 | method: 'PUT', 9 | headers: { 10 | 'Content-Type': 'application/json', 11 | }, 12 | body: JSON.stringify(data), 13 | }) 14 | .then(res => res.json()) 15 | .then(data => { 16 | if (data.message === 'Constructor data was updated successfully') { 17 | Swal.fire({ 18 | position: 'center', 19 | icon: 'success', 20 | title: 'Your Data has been updated successfully!', 21 | showConfirmButton: false, 22 | timer: 1500, 23 | }) 24 | refetch() 25 | } else { 26 | Swal.fire({ 27 | icon: 'error', 28 | title: 'Oops...', 29 | text: 'Something went wrong!', 30 | }) 31 | } 32 | }) 33 | } 34 | 35 | return ( 36 |
37 | {/* */} 38 | 39 |
40 |
41 | 47 |

48 | Editing Information with the id of {id} 49 |

50 | 54 |
55 |
56 |
57 | ) 58 | } 59 | 60 | export default UpdateModal 61 | -------------------------------------------------------------------------------- /src/Pages/Homepage/Guide/Guide.js: -------------------------------------------------------------------------------- 1 | import React, { useContext } from "react"; 2 | import { Fade } from "react-reveal"; 3 | import { Link } from "react-router-dom"; 4 | import { DarkModeContext } from "../../../App"; 5 | 6 | const Guide = () => { 7 | const [darkMode, setDarkMode] = useContext(DarkModeContext); 8 | 9 | return ( 10 |
11 | 12 |
13 | 18 |
19 |
20 | 21 |
22 |

23 | Overcome top challenges faced by capital program managers and owners 24 | with 25 |

26 |

30 | The Ultimate Construction Management Guide Collection. 31 |

32 | 33 | 41 | 42 |
43 |
44 |
45 | ); 46 | }; 47 | 48 | export default Guide; 49 | -------------------------------------------------------------------------------- /src/Assest/download-svgrepo-com.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 8 | 12 | 15 | 17 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /src/Pages/SearchRoute/Searches.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Loading from '../../Shared/Loading/Loading'; 3 | import Search from './Search'; 4 | import './Searches.css' 5 | 6 | const Searches = () => { 7 | 8 | const [searchText, setSearchText] = React.useState('') 9 | const [searchResult, setSearchResult] = React.useState([]) 10 | const [loading, setLoading] = React.useState(false) 11 | 12 | 13 | 14 | const handleSearch = data => { 15 | setSearchText(data.target.value) 16 | } 17 | 18 | React.useEffect(() => { 19 | setLoading(true) 20 | 21 | fetch(`https://jsonplaceholder.typicode.com/comments?postId=${searchText}`) 22 | .then(res => res.json()) 23 | .then(data => { 24 | setSearchResult(data) 25 | }) 26 | setLoading(false) 27 | 28 | }, [searchText]) 29 | 30 | if (loading) { 31 | return 32 | } 33 | 34 | // console.log(searchResult); 35 | 36 | return ( 37 |
38 |

Search To Find Your User

39 |
40 | 41 | 42 |
43 | { 44 | searchResult.map(s => ) 48 | } 49 |
50 | ); 51 | }; 52 | 53 | export default Searches; -------------------------------------------------------------------------------- /src/Pages/Dashboardpage/orders/Orders.js: -------------------------------------------------------------------------------- 1 | import React, { useContext } from 'react' 2 | import { useQuery } from '@tanstack/react-query' 3 | import Loading from '../../../Shared/Loading/Loading' 4 | import OrderRow from './OrderRow' 5 | import { DarkModeContext } from '../../../App' 6 | 7 | const Orders = () => { 8 | const [darkMode, setDarkMode] = useContext(DarkModeContext) 9 | const { isLoading, error, data, refetch } = useQuery(['allOrders'], () => 10 | fetch('https://neighbour-home-backend.onrender.com/booking').then(res => 11 | res.json() 12 | ) 13 | ) 14 | 15 | if (isLoading) return 16 | 17 | if (error) return 'An error has occurred: ' + error.message 18 | return ( 19 |
20 |

23 | All Hiring List: {data?.length} 24 |

25 |
26 | 31 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 53 | {data?.map((d, index) => ( 54 | 60 | ))} 61 | 62 |
customerEmailPhoneProfessionemailPhoneAction
63 |
64 |
65 | ) 66 | } 67 | 68 | export default Orders 69 | -------------------------------------------------------------------------------- /src/Assest/images/orders-icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/Pages/Dashboardpage/myOrders/BookingPayment.js: -------------------------------------------------------------------------------- 1 | import { Elements } from '@stripe/react-stripe-js' 2 | import { loadStripe } from '@stripe/stripe-js' 3 | import React from 'react' 4 | import { useParams } from 'react-router-dom' 5 | // import Loading from '../../../Shared/Loading'; 6 | import CheckoutForm from './CheckoutForm' 7 | import { useQuery } from '@tanstack/react-query' 8 | import Loading from '../../../Shared/Loading/Loading' 9 | 10 | const stripePromise = loadStripe( 11 | 'pk_test_51L36HPDSwcecuX813VvXAEHIEcEaDJFFSepUyBw0E6BoJXV7awyaIBzaddJCZL3bLGEnkuiKJkOCdrZPp5xdgAzJ00rSmMzm0q' 12 | ) 13 | 14 | const BookingPayment = () => { 15 | const { id } = useParams() 16 | console.log(id) 17 | const url = `https://neighbour-home-backend.onrender.com/booking/${id}` 18 | 19 | const { 20 | data: booking, 21 | isLoading, 22 | refetch, 23 | } = useQuery(['booking', id], () => 24 | fetch(url, { 25 | method: 'GET', 26 | headers: { 27 | authorization: `Bearer ${localStorage.getItem('accessToken')}`, 28 | }, 29 | }).then(res => res.json()) 30 | ) 31 | if (isLoading) { 32 | return 33 | } 34 | return ( 35 |
36 |
37 |
38 |

39 | Hello, {booking?.data?.customerName} 40 |

41 |

42 | Please Pay for {booking?.engineer?.name} 43 |

44 |

45 | Please Pay:{' '} 46 | ${booking?.price} For 47 | Hiring this Engineer 48 |

49 |
50 |
51 |
52 |
53 | 54 | 55 | 56 |
57 |
58 |
59 | ) 60 | } 61 | 62 | export default BookingPayment 63 | -------------------------------------------------------------------------------- /public/properties.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "propertyName": "RS Home Center", 4 | "propertyType": "Residential", 5 | "sellerName": "RS Home Center", 6 | "images": " IMG Link", 7 | "propertyPrice": 100000, 8 | "rating": 4.5, 9 | "width": "2.5", 10 | "length": "2.5", 11 | "location": "Kathmandu", 12 | "totalarea": "2.5", 13 | "selingarea": "2.5" 14 | }, 15 | { 16 | "propertyName": "Basundhara", 17 | "propertyType": "Residential", 18 | "sellerName": "RS Home Center", 19 | "images": " IMG Link", 20 | "propertyPrice": 100000, 21 | "rating": 5, 22 | "width": "2.5", 23 | "length": "2.5", 24 | "location": "Kathmandu", 25 | "totalarea": "2.5", 26 | "selingarea": "2.5" 27 | }, 28 | { 29 | "propertyName": " land hour", 30 | "propertyType": "Residential", 31 | "sellerName": "RS Home Center", 32 | "images": " IMG Link", 33 | "propertyPrice": 100000, 34 | "rating": 4, 35 | "width": "2.5", 36 | "length": "2.5", 37 | "location": "Kathmandu", 38 | "totalarea": "2.5", 39 | "selingarea": "2.5" 40 | }, 41 | { 42 | "propertyName": "vive land", 43 | "propertyType": "Residential", 44 | "sellerName": "RS Home Center", 45 | "images": " IMG Link", 46 | "propertyPrice": 100000, 47 | "rating": 3, 48 | "width": "2.5", 49 | "length": "2.5", 50 | "location": "Kathmandu", 51 | "totalarea": "2.5", 52 | "selingarea": "2.5" 53 | }, 54 | { 55 | "propertyName": " BTS Home", 56 | "propertyType": "Residential", 57 | "sellerName": "RS Home Center", 58 | "images": " IMG Link", 59 | "propertyPrice": 100000, 60 | "rating": 4.5, 61 | "width": "2.5", 62 | "length": "2.5", 63 | "location": "Kathmandu", 64 | "totalarea": "2.5", 65 | "selingarea": "2.5" 66 | } 67 | ] -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "western-lab-university", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@emailjs/browser": "^3.6.2", 7 | "@fortawesome/fontawesome-svg-core": "^6.1.2", 8 | "@fortawesome/free-solid-svg-icons": "^6.1.1", 9 | "@fortawesome/react-fontawesome": "^0.1.18", 10 | "@stripe/react-stripe-js": "^1.10.0", 11 | "@stripe/stripe-js": "^1.35.0", 12 | "@tanstack/react-query": "^4.0.10", 13 | "@testing-library/jest-dom": "^5.16.4", 14 | "@testing-library/react": "^13.3.0", 15 | "@testing-library/user-event": "^13.5.0", 16 | "axios": "^0.27.2", 17 | "daisyui": "^2.20.0", 18 | "firebase": "^9.9.0", 19 | "imgbb-uploader": "^1.5.0", 20 | "moment": "^2.29.4", 21 | "react": "^18.2.0", 22 | "react-countup": "^6.3.0", 23 | "react-dom": "^18.2.0", 24 | "react-fast-marquee": "^1.3.2", 25 | "react-feather": "^2.0.10", 26 | "react-firebase-hooks": "^5.0.3", 27 | "react-hook-form": "^7.34.0", 28 | "react-hot-toast": "^2.3.0", 29 | "react-icons": "^4.4.0", 30 | "react-messenger-customer-chat": "^0.8.0", 31 | "react-query": "^4.0.0", 32 | "react-rating": "^2.0.5", 33 | "react-redux": "^8.0.2", 34 | "react-reveal": "^1.2.2", 35 | "react-router-dom": "^6.3.0", 36 | "react-scripts": "5.0.1", 37 | "react-spinners": "^0.13.4", 38 | "react-to-print": "^2.14.7", 39 | "redux": "^4.2.0", 40 | "sweetalert": "^2.1.2", 41 | "sweetalert2": "^11.4.24", 42 | "swiper": "^8.3.1", 43 | "web-vitals": "^2.1.4" 44 | }, 45 | "scripts": { 46 | "start": "react-scripts start", 47 | "build": "react-scripts build", 48 | "test": "react-scripts test", 49 | "eject": "react-scripts eject" 50 | }, 51 | "eslintConfig": { 52 | "extends": [ 53 | "react-app", 54 | "react-app/jest" 55 | ] 56 | }, 57 | "browserslist": { 58 | "production": [ 59 | ">0.2%", 60 | "not dead", 61 | "not op_mini all" 62 | ], 63 | "development": [ 64 | "last 1 chrome version", 65 | "last 1 firefox version", 66 | "last 1 safari version" 67 | ] 68 | }, 69 | "devDependencies": { 70 | "tailwindcss": "^3.1.6" 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/Pages/ServiceDetails/WorkersTable.js: -------------------------------------------------------------------------------- 1 | import React, { useContext } from 'react'; 2 | import { Link } from 'react-router-dom'; 3 | import { DarkModeContext } from '../../App'; 4 | import useWorkers from '../../hooks/useWorkers'; 5 | import Loading from '../../Shared/Loading/Loading'; 6 | import WorkerRow from './WorkerRow'; 7 | 8 | 9 | const WorkersTable = () => { 10 | const [workers, setWorkers] = useWorkers([]); 11 | if(!workers.length){ 12 | 13 | } 14 | const [darkMode, setDarkMode] = useContext(DarkModeContext); 15 | return ( 16 |
17 |
18 | 19 |

All Workers: {workers?.length}

20 |
21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | { 34 | workers?.map((worker, index)=>) 40 | } 41 | 42 |
AvatarNameProfessionDetails
43 |
44 |
45 | ); 46 | }; 47 | 48 | export default WorkersTable; -------------------------------------------------------------------------------- /src/Pages/Properties/Property.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { MdLocationPin } from 'react-icons/md'; 3 | import { faStar } from '@fortawesome/free-solid-svg-icons' 4 | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; 5 | import Rating from 'react-rating'; 6 | import { useNavigate } from 'react-router-dom'; 7 | 8 | const Property = ({ property }) => { 9 | const navigate = useNavigate() 10 | const { _id, images, length, location, propertyName, propertyPrice, propertyType, rating, selingarea, sellerName, totalarea, width } = property; 11 | return ( 12 |
13 | {images} 14 | 15 |
16 |
17 | {location} 18 |
19 |

{propertyName}

20 |

Seller: {sellerName}

21 |

type: {propertyType}

22 |

Seling Area: {selingarea}

23 |

Total Area: {totalarea}

24 |

Width: {width}

25 |
26 | } 29 | fullSymbol={} 30 | readonly 31 | > 32 |
33 |
34 | 38 |

{propertyPrice}

39 |
40 |
41 | 42 |
43 | ); 44 | }; 45 | 46 | export default Property; -------------------------------------------------------------------------------- /src/Pages/ServiceDetails/EngineersTable.js: -------------------------------------------------------------------------------- 1 | import React, { useContext } from 'react'; 2 | import { Link } from 'react-router-dom'; 3 | import { DarkModeContext } from '../../App'; 4 | import useEngineers from '../../hooks/useEngineers'; 5 | import Loading from '../../Shared/Loading/Loading'; 6 | import EngineerRow from './EngineerRow'; 7 | 8 | const EngineersTable = () => { 9 | const [engineers, setEngineers] = useEngineers([]); 10 | if(!engineers.length){ 11 | 12 | } 13 | const [darkMode, setDarkMode] = useContext(DarkModeContext); 14 | return ( 15 |
16 |
17 | 18 |

All Engineers: {engineers?.length}

19 |
20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | { 33 | engineers?.map((engineer, index)=>) 39 | } 40 | 41 |
AvatarNameProfessionDetails
42 |
43 |
44 | ); 45 | }; 46 | 47 | export default EngineersTable; -------------------------------------------------------------------------------- /src/Pages/Homepage/Pricing/PricingCard.js: -------------------------------------------------------------------------------- 1 | import React, { useContext } from "react"; 2 | import { Link } from "react-router-dom"; 3 | import { DarkModeContext } from "../../../App"; 4 | 5 | const PricingCard = ({ pricings }) => { 6 | const { tag, price, period, description, benefit, _id } = pricings; 7 | const [darkMode] = useContext(DarkModeContext); 8 | return ( 9 |
10 |
15 |
16 |

{tag}

17 | 18 | ${price} 19 | /{period} 20 | 21 |
22 |

{description}

23 |
    24 | {Object.values(benefit).map((value, key) => ( 25 |
  • 26 | 32 | 37 | 38 | {value} 39 |
  • 40 | ))} 41 |
42 | 49 | 50 | 51 |
52 |
53 | ); 54 | }; 55 | 56 | export default PricingCard; 57 | -------------------------------------------------------------------------------- /src/Pages/Payment/Payment.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react' 2 | import { useParams } from 'react-router-dom' 3 | import { loadStripe } from '@stripe/stripe-js' 4 | import { 5 | CardElement, 6 | Elements, 7 | useStripe, 8 | useElements, 9 | } from '@stripe/react-stripe-js' 10 | // import CheckoutForm from './CheckoutForm'; 11 | import axios from 'axios' 12 | import Loading from '../../Shared/Loading/Loading' 13 | import CheckoutForm from './CheckoutForm' 14 | 15 | const stripePromise = loadStripe( 16 | 'pk_test_51L1nmKGPq7AV2lfodr5gcy3EzSOHKwBEH2emqXejNfRM0LSaua89mPiSH0YGJW9hBL86KKbfRlFQyItk4guugH3t00uj3H1Hs8' 17 | ) 18 | const Payment = () => { 19 | const [property, setProperty] = useState({}) 20 | const [propertyLoading, setPropertyLoading] = useState(true) 21 | const { id } = useParams() 22 | useEffect(() => { 23 | const url = `https://neighbour-home-backend.onrender.com/sellPost/${id}` 24 | axios.get(url).then(data => { 25 | setProperty(data.data) 26 | setPropertyLoading(false) 27 | }) 28 | }, [id]) 29 | 30 | const { 31 | _id, 32 | images, 33 | length, 34 | location, 35 | propertyName, 36 | propertyPrice, 37 | propertyType, 38 | rating, 39 | selingarea, 40 | sellerName, 41 | totalarea, 42 | width, 43 | } = property 44 | if (propertyLoading) { 45 | return 46 | } 47 | return ( 48 |
52 |
53 |
54 |
55 |

{propertyName}

56 | 61 |

Order Length : {length}

62 |

Price : {propertyPrice}

63 |
64 | 65 | 66 | 67 | 68 |
69 |
70 |
71 | ) 72 | } 73 | 74 | export default Payment 75 | -------------------------------------------------------------------------------- /src/components/NotFound/NotFound.css: -------------------------------------------------------------------------------- 1 | @keyframes pop-up{ 2 | 0% {transform: translateY(80%); opacity:0;} 3 | 60% {transform: translateY(-10px);opacity: 1;} 4 | 80% {transform: translateY(5px)} 5 | 100% {transform: translateY(0);} 6 | } 7 | 8 | @keyframes blink{ 9 | 20% {transform: scaleY(1);} 10 | 25% {transform: scaleY(0.1);} 11 | 30% {transform: scaleY(1);} 12 | } 13 | 14 | @keyframes blink-fancy{ 15 | 0%, 25%, 28.33%, 45%, 48.33%, 51.67%, 93.33%, 96.67%{transform: scaleY(1);} 16 | 26.67%, 46.67%, 50%, 95% {transform: scaleY(0.1);} 17 | } 18 | 19 | @keyframes looky-loo{ 20 | 0%, 42.31%, 50%, 69.23%, 100% {transform: translate3d(0,0,0);} 21 | 7.69%, 23.08% {transform: translate3d(-5px,0,0);} 22 | 26.92%, 38.46% {transform: translate3d(5px, 0,0);} 23 | 53.85%, 65.38%{transform: translate3d(0, -10px,0);} 24 | } 25 | 26 | @keyframes looky-loo-ears{ 27 | 0%, 42.31%, 50%, 69.23%, 100% {transform: translate3d(0,0,0);} 28 | 7.69%, 23.08% {transform: translate3d(3px,0,0);} 29 | 26.92%, 38.46% {transform: translate3d(-3px, 0,0);} 30 | 53.85%, 65.38%{transform: translate3d(0, 5px,0);} 31 | } 32 | 33 | @keyframes looky-loo-beard{ 34 | 50%, 69.23%, 100% {transform: translate3d(0,0,0);} 35 | 53.85%, 65.38%{transform: translate3d(0, -10px, 0);} 36 | } 37 | 38 | @keyframes cloud-right{ 39 | 50% {transform: translateX(10px);} 40 | 100% {transform: translateX(0);} 41 | } 42 | 43 | @keyframes cloud-left{ 44 | 50% {transform: translateX(-8px);} 45 | 100% {transform: translateX(0);} 46 | } 47 | 48 | circle.blinking-eyes{ 49 | animation: blink-fancy 6s linear infinite; 50 | } 51 | 52 | #Dave{ 53 | animation: pop-up 1s ease-in-out 1; 54 | } 55 | #Eyes, #unibrow, #moustache, #Blush {animation: looky-loo 13s ease-in-out infinite; animation-delay: 2s;} 56 | 57 | #Ears {animation: looky-loo-ears 13s ease-in-out infinite; animation-delay: 2s} 58 | 59 | #beard-lower, #beard-innershadow, #Neck-Innershadow{ 60 | animation: looky-loo-beard 13s ease-in-out infinite; 61 | animation-delay: 2s; 62 | } 63 | 64 | #cloud-right{animation: cloud-right 5s ease-in-out infinite;} 65 | #cloud-left{animation: cloud-left 5s ease-in-out infinite; animation-delay:1s} 66 | 67 | #easter-egg{ 68 | opacity:0; 69 | transition: all 0.1s ease-in-out; 70 | } 71 | svg:hover #easter-egg{ 72 | opacity: 1; 73 | transition: all 0.1s ease-in-out; 74 | } -------------------------------------------------------------------------------- /public/review.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "_id": "623853b2614ad5aba311fdd1", 4 | "name": "Jhon Doe", 5 | "picture": "http://static.dezeen.com/uploads/2014/01/FAT-Sean-Griffiths_dezeen_sq.jpg", 6 | "date": "2 days ago", 7 | "stars": "4.5", 8 | "reviewTxt": "It is very good marketplace. Recommended for you" 9 | }, 10 | { 11 | "_id": "623853b2578e9e6ad1ae0dd5", 12 | "name": "Tom Cruise", 13 | "picture": "https://www.pinkvilla.com/imageresize/tom_mission_impossible.jpg?width=752&format=webp&t=pvorg", 14 | "date": "2 days ago", 15 | "stars": "4.5", 16 | "reviewTxt": "It is very good marketplace. Recommended for you" 17 | }, 18 | { 19 | "_id": "623853b21fb149d2ee7b76c7", 20 | "name": "Tom Holland", 21 | "picture": "https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/gettyimages-1237227890.jpg?crop=1xw:0.8080985915492958xh;center,top&resize=640:*", 22 | "date": "2 days ago", 23 | "stars": "4.5", 24 | "reviewTxt": "It is very good marketplace. Recommended for you" 25 | }, 26 | { 27 | "_id": "623853b2e91c8de578c9245e", 28 | "name": "Jack Mate", 29 | "picture": "https://blog-pixomatic.s3.appcnt.com/image/22/01/26/61f166e1377d4/_orig/pixomatic_1572877223091.png", 30 | "date": "2 days ago", 31 | "stars": "4.5", 32 | "reviewTxt": "It is very good marketplace. Recommended for you" 33 | }, 34 | { 35 | "_id": "623853b2239582e48409ccc6", 36 | "name": "Emma Jone", 37 | "picture": "https://media.istockphoto.com/photos/close-up-portrait-of-brunette-woman-picture-id1154642632?k=20&m=1154642632&s=612x612&w=0&h=dQPjQCt_WOKhD0ysSJG6gIsu7xW65vH8Wf_SaqetIqY=", 38 | "date": "2 days ago", 39 | "stars": "4.5", 40 | "reviewTxt": "It is very good marketplace. Recommended for you" 41 | }, 42 | { 43 | "_id": "623853b2cdda0d5bc294f791", 44 | "name": "Ananto the Zolil", 45 | "picture": "http://mzamin.com/news_image/246469_jolil.jpg", 46 | "date": "2 days ago", 47 | "stars": "4.5", 48 | "reviewTxt": "It is very good marketplace. Recommended for you" 49 | }, 50 | { 51 | "_id": "623853b2736f19fd4eb8d44a", 52 | "name": "Borsha Apa", 53 | "picture": "https://2.bp.blogspot.com/-cx_VN2jeLOQ/UVfW4ZpnmOI/AAAAAAAAMII/ul8ZLaAZcaI/s1600/bangladeshi+model+and+actress+borsha+%252810%2529.jpg", 54 | "date": "2 days ago", 55 | "stars": "4.5", 56 | "reviewTxt": "It is very good marketplace. Recommended for you" 57 | } 58 | ] 59 | -------------------------------------------------------------------------------- /src/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/projects.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "_id": "01", 4 | "title": "Interior Design", 5 | "subtitle": "Builder, Repairman", 6 | "image": "http://malikhassan.com/html/construction/images/portfolio.jpg" 7 | }, 8 | { 9 | "_id": "02", 10 | "title": "Home", 11 | "subtitle": "Builder, Repairman", 12 | "image": "http://malikhassan.com/html/construction/images/portfolio2.jpg" 13 | }, 14 | { 15 | "_id": "03", 16 | "title": "Green House", 17 | "subtitle": "Builder, Repairman", 18 | "image": "http://malikhassan.com/html/construction/images/portfolio3.jpg" 19 | }, 20 | { 21 | "_id": "04", 22 | "title": "Home", 23 | "subtitle": "Builder, Repairman", 24 | "image": "http://malikhassan.com/html/construction/images/portfolio4.jpg" 25 | }, 26 | { 27 | "_id": "05", 28 | "title": "Interior Design", 29 | "subtitle": "Builder, Repairman", 30 | "image": "http://malikhassan.com/html/construction/images/portfolio5.jpg" 31 | }, 32 | { 33 | "_id": "06", 34 | "title": "Home", 35 | "subtitle": "Builder, Repairman", 36 | "image": "http://malikhassan.com/html/construction/images/portfolio6.jpg" 37 | }, 38 | { 39 | "_id": "07", 40 | "title": "Home", 41 | "subtitle": "Builder, Repairman", 42 | "image": "http://malikhassan.com/html/construction/images/portfolio7.jpg" 43 | }, 44 | { 45 | "_id": "08", 46 | "title": "Home", 47 | "subtitle": "Builder, Repairman", 48 | "image": "http://malikhassan.com/html/construction/images/portfolio8.jpg" 49 | }, 50 | { 51 | "_id": "09", 52 | "title": "Home", 53 | "subtitle": "Builder, Repairman", 54 | "image": "http://malikhassan.com/html/construction/images/portfolio9.jpg" 55 | }, 56 | { 57 | "_id": "10", 58 | "title": "Interior Design", 59 | "subtitle": "Builder, Repairman", 60 | "image": "http://malikhassan.com/html/construction/images/portfolio10.jpg" 61 | }, 62 | { 63 | "_id": "11", 64 | "title": "Home", 65 | "subtitle": "Builder, Repairman", 66 | "image": "http://malikhassan.com/html/construction/images/portfolio11.jpg" 67 | }, 68 | { 69 | "_id": "12", 70 | "title": "Home", 71 | "subtitle": "Builder, Repairman", 72 | "image": "http://malikhassan.com/html/construction/images/portfolio12.jpg" 73 | } 74 | ] -------------------------------------------------------------------------------- /src/hooks/useEngineers.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react' 2 | 3 | const useEngineers = () => { 4 | const [engineers, setEngineers] = useState([]) 5 | const [engLoading, setEngLoading] = useState(true) 6 | useEffect(() => { 7 | fetch( 8 | 'https://neighbour-home-backend.onrender.com/getUserByRole/Engineer' 9 | ) 10 | .then(res => res.json()) 11 | .then(data => { 12 | setEngineers(data) 13 | setEngLoading(false) 14 | }) 15 | }, [engineers, engLoading, setEngineers]) 16 | return [engineers, setEngineers] 17 | } 18 | export default useEngineers 19 | 20 | // const useEngineers = () =>{ 21 | // const [engineers, setEngineers] = useState([]); 22 | // const [user, setUser] = useState(); 23 | // useEffect( () =>{ 24 | // fetch('https://neighbour-home-backend.onrender.com/user').then( 25 | // res => res.json() 26 | // ).then(data => setUser(data)) 27 | // // console.log(user && user); 28 | // { 29 | // const engineers = user?.filter(engineer => engineer.role === "Engineer"); 30 | // // console.log(engineers && engineers); 31 | // setEngineers(engineers) 32 | // } 33 | // },[engineers, user, setUser, setEngineers]); 34 | 35 | // return [engineers, setEngineers]; 36 | // } 37 | // export default useEngineers; 38 | 39 | // const useEngineers = () =>{ 40 | // const [engineers, setEngineers] = useState([]); 41 | // const [workers, setWorkers] = useState([]); 42 | // const [admin, setAdmin] = useState([]); 43 | // const [guestUser, setGuestUser] = useState([]); 44 | // const [user, setUser] = useState(); 45 | // useEffect( () =>{ 46 | // fetch('https://neighbour-home-backend.onrender.com/user').then( 47 | // res => res.json() 48 | // ).then(data => setUser(data)) 49 | // // console.log(user && user); 50 | // { 51 | // const engineers = user?.filter(u => u.role === "Engineer"); 52 | // // console.log(engineers && engineers); 53 | // setEngineers(engineers) 54 | // } 55 | // { 56 | // const workers = user?.filter(u => u.role === "Workers"); 57 | // // console.log(engineers && engineers); 58 | // setWorkers(workers) 59 | // } 60 | // { 61 | // const admin = user?.filter(u => u.role === "Admin"); 62 | // // console.log(engineers && engineers); 63 | // setAdmin(admin) 64 | // } 65 | // { 66 | // const guestUser = user?.filter(u => u.role === "GuestUser"); 67 | // // console.log(engineers && engineers); 68 | // setGuestUser(guestUser) 69 | // } 70 | // },[engineers, user, setUser, setEngineers]); 71 | 72 | // return [engineers, setEngineers]; 73 | // } 74 | // export default useEngineers; 75 | -------------------------------------------------------------------------------- /src/Pages/ResumeBuilder/Editor/Editor.module.css: -------------------------------------------------------------------------------- 1 | .container { 2 | min-width: 550px; 3 | min-height: 450px; 4 | max-width: 750px; 5 | display: flex; 6 | flex-direction: column; 7 | gap: 30px; 8 | box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.2); 9 | padding-top: 5px; 10 | height: fit-content; 11 | margin: 0 auto; 12 | } 13 | 14 | .header { 15 | display: flex; 16 | gap: 10px; 17 | overflow-x: auto; 18 | border-bottom: 1px solid rgba(0, 0, 0, 0.1); 19 | } 20 | 21 | .header::-webkit-scrollbar { 22 | height: 7px; 23 | } 24 | 25 | .header::-webkit-scrollbar-thumb { 26 | border-radius: 20px; 27 | background-color: #c7c7c7; 28 | } 29 | 30 | .header .section { 31 | padding: 10px; 32 | border-bottom: 2px solid transparent; 33 | font-weight: 500; 34 | font-size: 1rem; 35 | white-space: nowrap; 36 | cursor: pointer; 37 | } 38 | 39 | .header .active { 40 | border-bottom: 2px solid #239ce2; 41 | color: #239ce2; 42 | } 43 | 44 | .body { 45 | padding: 30px; 46 | display: flex; 47 | flex-direction: column; 48 | gap: 20px; 49 | padding-top: 0; 50 | } 51 | 52 | .detail { 53 | display: flex; 54 | flex-direction: column; 55 | gap: 15px; 56 | } 57 | 58 | .detail .row { 59 | display: flex; 60 | gap: 20px; 61 | } 62 | .detail .column { 63 | display: flex; 64 | flex-direction: column; 65 | gap: 10px; 66 | } 67 | .detail .row > div { 68 | flex: 1; 69 | } 70 | 71 | .chips { 72 | display: flex; 73 | flex-wrap: wrap; 74 | align-items: center; 75 | gap: 20px; 76 | } 77 | 78 | .chips .new { 79 | color: #239ce2; 80 | font-weight: bold; 81 | letter-spacing: 1px; 82 | cursor: pointer; 83 | } 84 | 85 | .chip { 86 | display: flex; 87 | gap: 5px; 88 | align-items: center; 89 | padding: 4px 8px; 90 | background-color: #808080; 91 | border-radius: 20px; 92 | cursor: default; 93 | } 94 | 95 | .chip p { 96 | font-weight: 500; 97 | line-height: 1.25rem; 98 | color: #fff; 99 | } 100 | .chip svg { 101 | color: #fff; 102 | height: 18px; 103 | width: 18px; 104 | cursor: pointer; 105 | } 106 | 107 | .chips .active { 108 | background-color: #239ce2; 109 | } 110 | 111 | .body button { 112 | width: fit-content; 113 | padding: 8px 16px; 114 | border-radius: 5px; 115 | background-color: #239ce2; 116 | color: #fff; 117 | outline: none; 118 | border: none; 119 | font-weight: 500; 120 | font-size: 1rem; 121 | letter-spacing: 1px; 122 | display: flex; 123 | gap: 5px; 124 | align-items: center; 125 | cursor: pointer; 126 | transition: 200ms; 127 | } 128 | 129 | .body button:active { 130 | transform: translateY(2px); 131 | } 132 | -------------------------------------------------------------------------------- /src/Pages/Dashboardpage/Constructors/Constructor.js: -------------------------------------------------------------------------------- 1 | import React, { useContext } from 'react' 2 | import Swal from 'sweetalert2' 3 | import { DarkModeContext } from '../../../App' 4 | // import './UpdateModal' 5 | import UpdateModal from './UpdateModal' 6 | 7 | const Constructor = ({ constructor, index, refetch }) => { 8 | const { title, type, price, picture, duration, discount, assignment, _id } = 9 | constructor 10 | const [darkMode] = useContext(DarkModeContext) 11 | 12 | const handleDelete = id => { 13 | swalWithBootstrapButtons 14 | .fire({ 15 | title: 'Are you sure?', 16 | text: "You won't be able to revert this!", 17 | icon: 'warning', 18 | showCancelButton: true, 19 | confirmButtonText: 'Yes, delete it!', 20 | cancelButtonText: 'No, cancel!', 21 | reverseButtons: false, 22 | }) 23 | .then(result => { 24 | if (result.isConfirmed) { 25 | fetch( 26 | `https://neighbour-home-backend.onrender.com/constructor/${id}`, 27 | { 28 | method: 'DELETE', 29 | headers: { 30 | 'Content-Type': 'application/json', 31 | }, 32 | } 33 | ) 34 | .then(res => res.json()) 35 | .then(data => { 36 | console.log(data) 37 | if (data.message) { 38 | swalWithBootstrapButtons.fire( 39 | 'Deleted!', 40 | 'Your file has been deleted.', 41 | 'success' 42 | ) 43 | refetch() 44 | } 45 | }) 46 | } else if ( 47 | /* Read more about handling dismissals below */ 48 | result.dismiss === Swal.DismissReason.cancel 49 | ) { 50 | swalWithBootstrapButtons.fire( 51 | 'Cancelled', 52 | 'Your imaginary file is safe :)', 53 | 'error' 54 | ) 55 | } 56 | }) 57 | } 58 | 59 | // from sweet alert2 60 | const swalWithBootstrapButtons = Swal.mixin({ 61 | customClass: { 62 | confirmButton: 'btn btn-success', 63 | cancelButton: 'btn btn-error', 64 | }, 65 | buttonsStyling: true, 66 | }) 67 | return ( 68 | 69 | {index + 1} 70 | {title} 71 | {type} 72 | {price} USD 73 | {duration} days 74 | {discount}% 75 | {assignment} projects 76 | 77 | {/* */} 78 | 81 | 87 | 88 | 93 | 94 | ) 95 | } 96 | 97 | export default Constructor 98 | -------------------------------------------------------------------------------- /src/Pages/Homepage/Testimonials/Testimonials.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import React, { useContext, useEffect, useState } from 'react'; 3 | import { Fade } from 'react-reveal'; 4 | import { Link } from 'react-router-dom'; 5 | import { DarkModeContext } from '../../../App'; 6 | import Review from './Review'; 7 | 8 | const Testimonials = () => { 9 | const [reviews, setReviews] = useState([]) 10 | const [darkMode] = useContext(DarkModeContext) 11 | 12 | useEffect(() => { 13 | 14 | axios.get(`reviews.json`) 15 | .then(data => { 16 | setReviews(data.data) 17 | }) 18 | 19 | }, []) 20 | // console.log(reviews.slice(0, 2)); 21 | 22 | return ( 23 |
26 |

27 | Testimonials 28 |

29 |
30 |
31 |
32 |
33 |
34 |
35 | 36 |
37 |

Reviews from happy client

38 |

Construction of itself, because it is pain some 39 | some proper style design occur in toil and pain we have expert team some master

40 | view more 41 |
42 |
43 | 44 | 45 |
46 | 47 | 48 | { 49 | reviews.slice(0, 2).map((review, i) => ) 53 | } 54 | 55 |
56 |
57 |
58 |
59 | ); 60 | }; 61 | 62 | export default Testimonials; -------------------------------------------------------------------------------- /src/Pages/ServiceDetails/ServiceDetails.js: -------------------------------------------------------------------------------- 1 | import React, { useContext, useState } from "react"; 2 | import { Fade } from "react-reveal"; 3 | import { Link, useParams } from "react-router-dom"; 4 | import { DarkModeContext } from "../../App"; 5 | import useServiceDetails from "../../hooks/useServiceDetails"; 6 | 7 | const ServiceDetails = () => { 8 | const [darkMode, setDarkMode] = useContext(DarkModeContext); 9 | const { serviceId } = useParams(); 10 | const [service] = useServiceDetails(serviceId); 11 | const { title, picture, _id, price, duration, discount, description } = 12 | service; 13 | 14 | 15 | return ( 16 |
17 |
20 |
21 | 22 |
23 | 28 |
29 |
30 | 31 |
32 |

{title}

33 |

34 | PRICE: ${price} 35 |

36 |

37 | DURATION: {duration} 38 |

39 |

40 | DISCOUNT: {discount} 41 |

42 |

{description}

43 |
44 | 45 | 48 | 49 | 50 | 53 | 54 |
55 |
56 |
57 |
58 |
59 |
60 | ); 61 | }; 62 | 63 | export default ServiceDetails; 64 | -------------------------------------------------------------------------------- /src/Pages/ResumeBuilder/Resume/Resume.module.css: -------------------------------------------------------------------------------- 1 | .container { 2 | --color: #239ce2; 3 | min-width: 700px; 4 | max-width: 850px; 5 | margin: 0 auto; 6 | flex: 1.2; 7 | height: fit-content; 8 | min-height: 900px; 9 | box-shadow: 1px 1px 3px 2px rgba(0, 0, 0, 0.1); 10 | display: flex; 11 | flex-direction: column; 12 | gap: 30px; 13 | padding: 30px; 14 | } 15 | 16 | .header { 17 | display: flex; 18 | flex-direction: column; 19 | } 20 | 21 | .header .heading { 22 | font-size: 2.7rem; 23 | font-weight: 500; 24 | text-transform: capitalize; 25 | } 26 | 27 | .header .subHeading { 28 | color: var(--color); 29 | font-weight: 500; 30 | font-size: 1.1rem; 31 | } 32 | 33 | .header .links { 34 | margin-top: 15px; 35 | display: flex; 36 | gap: 30px; 37 | flex-wrap: wrap; 38 | row-gap: 10px; 39 | } 40 | 41 | .header .link { 42 | font-size: 0.875rem; 43 | display: flex; 44 | align-items: center; 45 | gap: 5px; 46 | cursor: pointer; 47 | } 48 | 49 | .header .link svg { 50 | color: var(--color); 51 | height: 16px; 52 | width: 16px; 53 | } 54 | 55 | .main { 56 | display: flex; 57 | gap: 30px; 58 | } 59 | 60 | .col1 { 61 | flex: 1.3; 62 | display: flex; 63 | flex-direction: column; 64 | gap: 20px; 65 | } 66 | .col2 { 67 | flex: 1; 68 | display: flex; 69 | flex-direction: column; 70 | gap: 20px; 71 | } 72 | 73 | .section .sectionTitle { 74 | font-size: 1.4rem; 75 | font-weight: bold; 76 | width: 100%; 77 | border-bottom: 2px solid #000; 78 | } 79 | 80 | .section .content { 81 | display: flex; 82 | flex-direction: column; 83 | gap: 10px; 84 | padding: 10px 0; 85 | } 86 | .section .content .item { 87 | border-bottom: 1px dotted lightgray; 88 | display: flex; 89 | flex-direction: column; 90 | gap: 4px; 91 | padding-bottom: 10px; 92 | } 93 | .section .content .item:last-child { 94 | border-bottom: none; 95 | } 96 | 97 | .content .title { 98 | font-weight: 500; 99 | font-size: 1rem; 100 | line-height: 1.3rem; 101 | } 102 | 103 | .content .subTitle { 104 | font-weight: bold; 105 | color: var(--color); 106 | font-size: 1rem; 107 | } 108 | 109 | .content .overview { 110 | font-size: 0.875rem; 111 | } 112 | 113 | .content .link { 114 | display: flex; 115 | gap: 5px; 116 | font-size: 0.75rem; 117 | cursor: pointer; 118 | color: var(--color); 119 | } 120 | .content .link svg { 121 | height: 14px; 122 | width: 14px; 123 | color: var(--color); 124 | } 125 | 126 | .content .date { 127 | display: flex; 128 | gap: 5px; 129 | align-items: center; 130 | font-size: 0.875rem; 131 | } 132 | 133 | .content .date svg { 134 | height: 14px; 135 | width: 14px; 136 | } 137 | 138 | .content .points, 139 | .numbered { 140 | padding-left: 18px; 141 | font-size: 0.875rem; 142 | } 143 | 144 | .numbered li { 145 | list-style-type: decimal; 146 | } 147 | 148 | .hidden { 149 | display: none; 150 | } 151 | -------------------------------------------------------------------------------- /src/Pages/Homepage/Guides/Guides.js: -------------------------------------------------------------------------------- 1 | import React, { useContext, useEffect, useState } from 'react' 2 | import { Fade } from 'react-reveal' 3 | import { Link } from 'react-router-dom' 4 | import { DarkModeContext } from '../../../App' 5 | 6 | const Guides = () => { 7 | const [darkMode, setDarkMode] = useContext(DarkModeContext) 8 | const [books, setBooks] = useState([]) 9 | useEffect(() => { 10 | fetch('https://neighbour-home-backend.onrender.com/book') 11 | .then(res => res.json()) 12 | .then(data => setBooks(data)) 13 | }, []) 14 | return ( 15 |
16 |

20 | Learn more about Construction 21 |

22 |
23 |
24 |
25 |
26 |
27 | {books.map(book => { 28 | const { picture, name, description, _id } = book 29 | return ( 30 |
31 | 32 |
33 | 34 |
35 |
36 | 37 |
38 |

44 | {name} 45 |

46 |

51 | {description.slice(0, 200)} 52 |

53 | {/* */} 62 | 63 | 72 | 73 |
74 |
75 |
76 | ) 77 | })} 78 |
79 | ) 80 | } 81 | 82 | export default Guides 83 | -------------------------------------------------------------------------------- /src/Pages/Homepage/Pricing/PremiumPay.js: -------------------------------------------------------------------------------- 1 | import { CardElement, useStripe, useElements } from '@stripe/react-stripe-js' 2 | import React from 'react' 3 | import { useEffect } from 'react' 4 | import { useState } from 'react' 5 | import { AiFillWarning } from 'react-icons/ai' 6 | 7 | const PremiumPay = ({ price }) => { 8 | const stripe = useStripe() 9 | const elements = useElements() 10 | const [cardError, setCardError] = useState('') 11 | // const [clientSecret, setClientSecret] = useState(""); 12 | 13 | // useEffect(() => { 14 | // fetch( 15 | // "https://neighbour-home-backend.onrender.com/create-payment-intent", 16 | // { 17 | // method: "POST", 18 | // headers: { 19 | // "content-type": "application/json", 20 | // authorization: `Bearer ${localStorage.getItem("accessToken")}`, 21 | // }, 22 | // body: JSON.stringify({ price }), 23 | // } 24 | // ) 25 | // .then((res) => res.json()) 26 | // .then((data) => { 27 | // console.log(data); 28 | // if (data?.clientSecret) { 29 | // setClientSecret(data.clientSecret); 30 | // } 31 | // }); 32 | // }, [price]); 33 | 34 | const handleSubmit = async e => { 35 | e.preventDefault() 36 | 37 | if (!stripe || !elements) { 38 | return 39 | } 40 | 41 | const card = elements.getElement(CardElement) 42 | 43 | if (card == null) { 44 | return 45 | } 46 | 47 | // Use your card Element with other Stripe.js APIs 48 | const { error, paymentMethod } = await stripe.createPaymentMethod({ 49 | type: 'card', 50 | card, 51 | }) 52 | if (error) { 53 | setCardError(error.message) 54 | } else { 55 | setCardError('') 56 | } 57 | } 58 | return ( 59 |
60 |

Pay With Visa, Mastercard, DebitCard etc.

61 |
62 | 79 | 90 | 91 | {cardError && ( 92 |

93 | {' '} 94 | {cardError} !!! 95 |

96 | )} 97 |
98 | ) 99 | } 100 | 101 | export default PremiumPay 102 | -------------------------------------------------------------------------------- /src/Pages/Homepage/Banner/Banner.js: -------------------------------------------------------------------------------- 1 | import React, { useContext } from 'react' 2 | import { Link } from 'react-router-dom' 3 | import { DarkModeContext } from '../../../App' 4 | 5 | const Banner = () => { 6 | const [darkMode] = useContext(DarkModeContext) 7 | 8 | return ( 9 |
10 |
16 |
17 | 22 |
23 | 24 |
25 |
26 |

27 | Welcome to Building Contraction Innovative for a better 28 | Tomorrow 29 |

30 |

31 | Building construction means any physical activity on the 32 | site involved in the erection of a structure, cladding, 33 | external finish, formwork, fixture, fitting of service 34 | installation 35 |

36 | 41 | Buy Apartment 42 | 43 |
44 |
45 |
46 |
47 | // {/* */} 48 | 49 | //
50 | //
51 | //
52 | //

A Better life start with beutyfull smile

54 | //

Computer Village is one of the largest computer stores in Bangladesh offering bundle deals and discounted prices for the latest computer accessories

55 | // 56 | //
57 | //
58 | //
59 | ) 60 | } 61 | 62 | export default Banner 63 | -------------------------------------------------------------------------------- /public/engineers.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "_id": "623853b2614ad5aba311fdd1", 4 | "index": 0, 5 | "name": "Jhon Doe", 6 | "picture": "http://static.dezeen.com/uploads/2014/01/FAT-Sean-Griffiths_dezeen_sq.jpg", 7 | "gender": "male", 8 | "surname": "Architect Engineer", 9 | "bio": "Let's meet our Architect Engineer Jhon Doe. He is specialist on his profession. Talk with him with your project requirement" 10 | }, 11 | { 12 | "_id": "623853b2578e9e6ad1ae0dd5", 13 | "index": 1, 14 | "name": "Tom Cruise", 15 | "picture": "https://www.pinkvilla.com/imageresize/tom_mission_impossible.jpg?width=752&format=webp&t=pvorg", 16 | "gender": "male", 17 | "surname": "Construction Engineer", 18 | "bio": "Let's meet our Construction Engineer Tom Cruise. He is specialist on his profession. Talk with him with your project requirement" 19 | }, 20 | { 21 | "_id": "623853b21fb149d2ee7b76c7", 22 | "index": 2, 23 | "name": "Tom Holland", 24 | "picture": "https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/gettyimages-1237227890.jpg?crop=1xw:0.8080985915492958xh;center,top&resize=640:*", 25 | "gender": "male", 26 | "surname": "Civil Engineer", 27 | "bio": "Let's meet our Civil Engineer Tom Holland. He is specialist on his profession. Talk with him with your project requirement" 28 | }, 29 | { 30 | "_id": "623853b2e91c8de578c9245e", 31 | "index": 3, 32 | "name": "Jack Mate", 33 | "picture": "https://blog-pixomatic.s3.appcnt.com/image/22/01/26/61f166e1377d4/_orig/pixomatic_1572877223091.png", 34 | "gender": "male", 35 | "surname": "Electrical Engineer", 36 | "bio": "Let's meet our Electrical Engineer Jack Mate. He is specialist on his profession. Talk with him with your project requirement" 37 | }, 38 | { 39 | "_id": "623853b2239582e48409ccc6", 40 | "index": 4, 41 | "name": "Emma Jone", 42 | "picture": "https://media.istockphoto.com/photos/close-up-portrait-of-brunette-woman-picture-id1154642632?k=20&m=1154642632&s=612x612&w=0&h=dQPjQCt_WOKhD0ysSJG6gIsu7xW65vH8Wf_SaqetIqY=", 43 | "gender": "male", 44 | "surname": "Architect Engineer", 45 | "bio": "Let's meet our Architect Engineer Emma Jone. He is specialist on his profession. Talk with him with your project requirement" 46 | }, 47 | { 48 | "_id": "623853b2cdda0d5bc294f791", 49 | "index": 5, 50 | "name": "Ananto the Zolil", 51 | "picture": "http://mzamin.com/news_image/246469_jolil.jpg", 52 | "gender": "male", 53 | "surname": "VPX Engineer", 54 | "bio": "Let's meet our VPX Engineer Ananto the Zolil. He is specialist on his profession. Talk with him with your project requirement" 55 | }, 56 | { 57 | "_id": "623853b2736f19fd4eb8d44a", 58 | "index": 6, 59 | "name": "Borsha Apa", 60 | "picture": "https://2.bp.blogspot.com/-cx_VN2jeLOQ/UVfW4ZpnmOI/AAAAAAAAMII/ul8ZLaAZcaI/s1600/bangladeshi+model+and+actress+borsha+%252810%2529.jpg", 61 | "gender": "male", 62 | "surname": "Management Engineer", 63 | "bio": "Let's meet our Management Engineer Borsha Apa. He is specialist on his profession. Talk with him with your project requirement" 64 | } 65 | ] 66 | -------------------------------------------------------------------------------- /src/Assest/user-profile-svgrepo-com.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 11 | 13 | 17 | 19 | 20 | 26 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /src/Pages/Homepage/NewsLetter/NewsLetter.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Fade } from "react-reveal"; 3 | 4 | const NewsLetter = () => { 5 | const handleSubmit = (e) => { 6 | e.preventDefault(); 7 | // toast.success(`Successfully Subscibed`) 8 | e.target.value.reset(); 9 | }; 10 | return ( 11 |
12 | {/*

News Letter

*/} 13 |
21 |
22 | 23 |

24 | SPECIAL OFFER FOR 25 | SUBSCRIPTION 26 |

27 |

31 | GET INSTANT DISCOUNT FOR MEMBERSHIP 32 |

33 |

37 | Subscribe our newsletter and all latest news of our latest 38 | product, promotion and offers{" "} 39 |

40 |
41 | 42 |
46 | 54 | 64 |
65 |
66 |
67 |
68 |
69 | ); 70 | // return ( 71 | //
72 | //

Subscribe Our News Letter

73 | //
74 | // 75 | //
76 | //
77 | // ); 78 | }; 79 | 80 | export default NewsLetter; 81 | -------------------------------------------------------------------------------- /src/Pages/ResumeBuilder/Body/Body.js: -------------------------------------------------------------------------------- 1 | import React, { useRef, useState } from "react"; 2 | import ReactToPrint from "react-to-print"; 3 | import { ArrowDown } from "react-feather"; 4 | 5 | import Editor from "../Editor/Editor"; 6 | import Resume from "../Resume/Resume"; 7 | 8 | import styles from "./Body.module.css"; 9 | 10 | function Body() { 11 | const colors = ["#239ce2", "#48bb78", "#0bc5ea", "#a0aec0", "#ed8936"]; 12 | const sections = { 13 | basicInfo: "Basic Info", 14 | workExp: "Work Experience", 15 | project: "Projects", 16 | education: "Education", 17 | achievement: "Achievements", 18 | summary: "Summary", 19 | other: "Other", 20 | }; 21 | const resumeRef = useRef(); 22 | 23 | const [activeColor, setActiveColor] = useState(colors[0]); 24 | const [resumeInformation, setResumeInformation] = useState({ 25 | [sections.basicInfo]: { 26 | id: sections.basicInfo, 27 | sectionTitle: sections.basicInfo, 28 | detail: {}, 29 | }, 30 | [sections.workExp]: { 31 | id: sections.workExp, 32 | sectionTitle: sections.workExp, 33 | details: [], 34 | }, 35 | [sections.project]: { 36 | id: sections.project, 37 | sectionTitle: sections.project, 38 | details: [], 39 | }, 40 | [sections.education]: { 41 | id: sections.education, 42 | sectionTitle: sections.education, 43 | details: [], 44 | }, 45 | [sections.achievement]: { 46 | id: sections.achievement, 47 | sectionTitle: sections.achievement, 48 | points: [], 49 | }, 50 | [sections.summary]: { 51 | id: sections.summary, 52 | sectionTitle: sections.summary, 53 | detail: "", 54 | }, 55 | [sections.other]: { 56 | id: sections.other, 57 | sectionTitle: sections.other, 58 | detail: "", 59 | }, 60 | }); 61 | 62 | return ( 63 |
64 |
65 |

Resume Builder

66 |
67 |
68 | {colors.map((item) => ( 69 | setActiveColor(item)} 76 | /> 77 | ))} 78 |
79 | { 81 | return ( 82 | 85 | ); 86 | }} 87 | content={() => resumeRef.current} 88 | /> 89 |
90 |
91 | 96 | 102 |
103 |
104 |
105 | 106 | ); 107 | } 108 | 109 | export default Body; 110 | -------------------------------------------------------------------------------- /src/Pages/Homepage/Pricing/PricingPay.js: -------------------------------------------------------------------------------- 1 | import { Elements } from '@stripe/react-stripe-js' 2 | import { loadStripe } from '@stripe/stripe-js' 3 | import React, { useEffect, useState } from 'react' 4 | import { useParams } from 'react-router-dom' 5 | import Loading from '../../../Shared/Loading/Loading' 6 | import PremiumPay from './PremiumPay' 7 | 8 | const stripePromise = loadStripe( 9 | 'pk_test_51L1nmKGPq7AV2lfodr5gcy3EzSOHKwBEH2emqXejNfRM0LSaua89mPiSH0YGJW9hBL86KKbfRlFQyItk4guugH3t00uj3H1Hs8' 10 | ) 11 | const PricingPay = () => { 12 | const { _id } = useParams() 13 | const [pricing, setPricing] = useState({}) 14 | const [loading, setLoading] = useState(false) 15 | const { tag, price, period, description } = pricing 16 | 17 | useEffect(() => { 18 | fetch(`https://neighbour-home-backend.onrender.com/pricing/${_id}`) 19 | .then(res => res?.json()) 20 | .then(data => { 21 | if (!data && data.benefit === undefined) { 22 | setLoading(true) 23 | } else { 24 | setPricing(data) 25 | setLoading(false) 26 | } 27 | }) 28 | }, [_id]) 29 | if (loading) { 30 | return 31 | } 32 | 33 | return ( 34 |
35 |
36 |
37 |
38 |
41 |
42 |

{tag}

43 | 44 | ${price} 45 | 46 | /{period} 47 | 48 | 49 |
50 |

51 | {description} 52 |

53 |
    54 | {pricing.benefit === undefined 55 | ? setLoading(true) 56 | : Object.values(pricing.benefit).map( 57 | (value, key) => ( 58 |
  • 62 | 68 | 73 | 74 | {value} 75 |
  • 76 | ) 77 | )} 78 |
79 |
80 |
81 | 82 |
83 |

Get Premium Access

84 |

85 | One Subscription Unlimited Access Get Premium access to all 86 | our properties apps with one subscription. 87 |

88 | 89 | 90 | 91 |
92 |
93 |
94 |
95 | ) 96 | } 97 | 98 | export default PricingPay 99 | -------------------------------------------------------------------------------- /public/card.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "_id": "623853b2614a311d5abafdd1", 4 | "index": 0, 5 | "title": "Mega Mall Construction", 6 | "type": "New Trending", 7 | "picture": "https://nepirockcastle.com/wp-content/uploads/2019/03/nepi-MEGA-MALL-ROMANIA-1.jpg", 8 | "duration": "90 days", 9 | "assignment": "9 Assignment", 10 | "discount": "17% Discount", 11 | "price": "$32", 12 | "description": "We are providing big mall project for you. You can choose our designed projects or meet our engineers for custom build your project" 13 | }, 14 | { 15 | "_id": "623853b2578d1ae0de9e6ad5", 16 | "index": 1, 17 | "title": "Highway Repairing", 18 | "type": "New Trending", 19 | "picture": "https://simex.com.bd/wp-content/uploads/2021/05/Fugear-1Construction-%E2%80%93-SIMEX-Bangladesh-1200x720.jpg", 20 | "duration": "90 days", 21 | "assignment": "9 Assignment", 22 | "discount": "17% Discount", 23 | "price": "$32", 24 | "description": "We are providing repairing service for your old project. You can choose our designed projects or meet our engineers for custom build your project" 25 | }, 26 | { 27 | "_id": "623853b2d2ee71fb149b76c7", 28 | "index": 2, 29 | "title": "Building Engineering", 30 | "type": "New Trending", 31 | "picture": "https://simex.com.bd/wp-content/uploads/2020/10/SIMEX-Bangladesh-can-Provide-the-Ultimate-Guidelines-for-Building-Construction-1200x720.jpg", 32 | "duration": "90 days", 33 | "assignment": "9 Assignment", 34 | "discount": "17% Discount", 35 | "price": "$32", 36 | "description": "We do home building engineering project for you. You can choose our designed projects or meet our engineers for custom build your project" 37 | }, 38 | { 39 | "_id": "623853b2e91c88cde579245e", 40 | "index": 3, 41 | "title": "Building Architecture", 42 | "type": "New Trending", 43 | "picture": "https://media.istockphoto.com/photos/hand-sketching-a-designer-villa-with-pool-picture-id1063723682?k=20&m=1063723682&s=612x612&w=0&h=m4E1YDtdg8WhGwr1hBG_X_wGoN9jNRME1DXHJ9oqSl4=", 44 | "duration": "90 days", 45 | "assignment": "9 Assignment", 46 | "discount": "17% Discount", 47 | "price": "$32", 48 | "description": "We have lot of Architecture Engineers. You can Design your project from us. We providing lifetime support for every customer." 49 | }, 50 | { 51 | "_id": "623853bgf39582e48409ccc6", 52 | "index": 4, 53 | "title": "Construction Services", 54 | "type": "New Trending", 55 | "picture": "https://img.tradeford.com/pimages/l/7/941967.jpg", 56 | "duration": "90 days", 57 | "assignment": "9 Assignment", 58 | "discount": "17% Discount", 59 | "price": "$32", 60 | "description": "We are providing Construction Services project for you. You can choose our designed projects or meet our engineers for custom build your project" 61 | }, 62 | { 63 | "_id": "623853b2cddafgtbc294f791", 64 | "index": 5, 65 | "title": "Construction Management", 66 | "type": "New Trending", 67 | "picture": "https://readcivil.com/wp-content/uploads/2017/08/Construction.jpg", 68 | "duration": "90 days", 69 | "assignment": "9 Assignment", 70 | "discount": "17% Discount", 71 | "price": "$32", 72 | "description": "We are providing Construction Management project for you. You can choose our designed projects or meet our engineers for custom build your project" 73 | } 74 | ] 75 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NeighbourHome 2 | 3 | ### Developed By Team Explode-Legacy 4 | 5 | Members: 6 | 7 | - Shoriful islam 8 | - Saidul basar bappy 9 | - Tajul islam rakib 10 | - Nayeem Hasan 11 | - Sadik hasan 12 | - Fahim muntasir 13 | 14 | 15 | 16 | ## Live site 17 | 18 | 19 | ### Website link- https://neighbour-home.web.app/ 20 | 21 | ## Server Side Code 22 | * https://github.com/khanshorif331/neighbour-home-backend 23 | 24 | 25 | ### Credentials 26 | 27 | - AdminEmail: admin@gmail.com 28 | - Password: Admin123 29 | 30 | - EngineerEmail: ph@hnnn.com 31 | - Password: Abc123 32 | 33 | - WorkerEmail: sahed@hn.com 34 | - Password: Abc123 35 | 36 | 37 | Name: NeighborHome ( management portal type website ) 38 | 39 | Goal: 40 | 41 | Our most important target is E-builder. We want to provide a technology-based commercial system. Building Management Systems Play an important role in the current instructional system. The authorities nowadays are using this amazing Management System to manage and supply a better experience by a software system to both ( Buyers and sellers ) effectively. That's our goal. 42 | 43 | 44 | ### Features: 45 | 46 | * Home Model __:__ The model information can be found and can be bought by the seller. Admin can update those. 47 | * Feedback __:__ Buyer can give feedback about Home Model or any Engineers. 48 | * Authorization __:__ we decided to use JWT. We make sure the user who is sending requests to your server is the same user who logged in during authentication. This is usually done using Sessions, where a session ID is sent down to the browser's cookies and moved ahead to authorize the user. 49 | * Chatbot __:__ Implemented a chatbot with which Buyer can chat. Where they get some guidelines and how to contact us. 50 | * Email Bombing __:__ When the admin posts any new announcement, every user, seller, and buyer will receive an email if he was registered. 51 | * Dashboard __:__ Make a dashboard for different roles. Like buyers, sellers, and an admin who can organize this site and update information. Every user has their own access and they are showing only their permitted page. 52 | * Open Magazine __:__ There is an Open library from where students can read free pdf books. Besides they can be permitted to download some books. 53 | * Discount __:__ Another interesting feature implemented by which admin can find the top 10 buyers in a month and give them a special discount. 54 | * Admin __:__ Admin can manage all the users and sellers. He can update demos info and add a new Home Model. He can update the notice board. 55 | * Stay Dream Home __:__ An interesting feature implemented by which different people can register (few payments) and visit our home 2 days 1 night. 56 | * Blog __:__ There will be a blog section. In which sellers can post different blogs. 57 | * Payment method __:__ we decided to use stripe. It is easy to set up for recurring payments. Payment Gateway is always an important question for merchants. There are so many new breakthroughs in the payment industry that other has failed to catch up on. In addition, a new system, Stripe, is positioning itself as a top technology in the payment gateway system. 58 | 59 | Conclusion: 60 | 61 | Information and communications technology (ICT) refers to all the technology used to handle telecommunications, broadcast media, intelligent building management systems, audiovisual processing, and transmission systems, and network-based control and monitoring functions. Although ICT is often considered an extended synonym for information technology. 62 | 63 | -------------------------------------------------------------------------------- /src/Pages/Dashboardpage/myOrders/MyOrderRow.js: -------------------------------------------------------------------------------- 1 | import { faTrashCan } from '@fortawesome/free-solid-svg-icons' 2 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' 3 | import React, { useContext, useEffect, useState } from 'react' 4 | import toast from 'react-hot-toast' 5 | import { Link } from 'react-router-dom' 6 | import swal from 'sweetalert' 7 | import Swal from 'sweetalert2' 8 | import { DarkModeContext } from '../../../App' 9 | 10 | const MyOrderRow = ({ index, d, refetch }) => { 11 | const { customerEmail, customerPhone, customerName, customerAddress } = 12 | d?.data 13 | const { name, email, _id, picture, phone, role } = d.engineer 14 | const [darkMode] = useContext(DarkModeContext) 15 | const lastEmail = d?.engineer?.email.split('@') 16 | const handleDelete = id => { 17 | swal({ 18 | title: 'Are you sure?', 19 | text: 'Once deleted, you will not be able to recover this file!', 20 | icon: 'warning', 21 | buttons: true, 22 | dangerMode: true, 23 | }).then(willDelete => { 24 | if (willDelete) { 25 | fetch(`https://neighbour-home-backend.onrender.com/booking/${id}`, { 26 | method: 'DELETE', 27 | headers: { 28 | 'Content-Type': 'application/json', 29 | }, 30 | }) 31 | .then(res => res.json()) 32 | .then(data => { 33 | console.log(data) 34 | if (data.message) { 35 | swal('Your file has been deleted!', { 36 | icon: 'success', 37 | }) 38 | refetch() 39 | } 40 | }) 41 | } 42 | }) 43 | } 44 | 45 | return ( 46 | 47 | {index + 1} 48 | 49 | {customerName} 50 | {customerEmail} 51 | 52 | {role} 53 | 54 | {d?.status !== 'accept' ? ( 55 | email 56 | ) : ( 57 | <> 58 | {email.slice(0, 1)}****@{lastEmail[1]} 59 | 60 | )} 61 | 62 | 63 | {d?.status !== 'accept' ? ( 64 | phone 65 | ) : ( 66 | <> 67 | {String(phone).slice(0, 2)}*****{String(phone).slice(8, 10)} 68 | 69 | )} 70 | 71 | 72 | {d.status === 'accept' ? 'pending' : 'ready to hire'} 73 | 74 | 75 |
76 | 80 | 83 | 84 | handleDelete(d._id)} 86 | className={`text-red-500 ml-2 mt-1 align-middle ${ 87 | d?.status === 'complete' ? 'block' : 'hidden' 88 | }`} 89 | icon={faTrashCan} 90 | /> 91 |
92 | {d?.status === 'complete' ? ( 93 | 94 | 95 | 96 | ) : ( 97 | 103 | )} 104 | {/* */} 105 | 106 | 107 | ) 108 | } 109 | 110 | export default MyOrderRow 111 | -------------------------------------------------------------------------------- /src/Pages/Dashboardpage/myOrders/CheckoutForm.js: -------------------------------------------------------------------------------- 1 | import { CardElement, useElements, useStripe } from '@stripe/react-stripe-js' 2 | import React, { useEffect, useState } from 'react' 3 | 4 | const CheckoutForm = ({ booking }) => { 5 | const stripe = useStripe() 6 | const elements = useElements() 7 | const [cardError, setCardError] = useState('') 8 | const [success, setSuccess] = useState('') 9 | const [processing, setProcessing] = useState(false) 10 | const [transactionId, setTransactionId] = useState('') 11 | const [clientSecret, setClientSecret] = useState('') 12 | 13 | const { _id, price, name, customerName, description, customerEmail } = 14 | booking 15 | useEffect(() => { 16 | fetch( 17 | 'https://neighbour-home-backend.onrender.com/create-payment-intent', 18 | { 19 | method: 'POST', 20 | headers: { 21 | 'content-type': 'application/json', 22 | authorization: `Bearer ${localStorage.getItem('accessToken')}`, 23 | }, 24 | body: JSON.stringify({ price }), 25 | } 26 | ) 27 | .then(res => res.json()) 28 | .then(data => { 29 | if (data?.clientSecret) { 30 | setClientSecret(data?.clientSecret) 31 | } 32 | }) 33 | }, [price]) 34 | const handleSubmit = async event => { 35 | event.preventDefault() 36 | setProcessing(true) 37 | if (!stripe || !elements) { 38 | return 39 | } 40 | 41 | const card = elements.getElement(CardElement) 42 | if (card == null) { 43 | return 44 | } 45 | 46 | const { error, paymentMethod } = await stripe.createPaymentMethod({ 47 | type: 'card', 48 | card, 49 | }) 50 | if (error) { 51 | // console.log(error); 52 | setCardError(error.message) 53 | } else { 54 | setCardError('') 55 | } 56 | setSuccess('') 57 | // setProcessing(true); 58 | // confirm card payment 59 | const { paymentIntent, error: intentError } = 60 | await stripe?.confirmCardPayment(clientSecret, { 61 | payment_method: { 62 | card: card, 63 | billing_details: { 64 | name: customerName, 65 | email: customerEmail, 66 | }, 67 | }, 68 | }) 69 | if (intentError) { 70 | setCardError(intentError?.message) 71 | success('') 72 | setProcessing(false) 73 | } else { 74 | setCardError('') 75 | setTransactionId(paymentIntent.id) 76 | console.log(paymentIntent) 77 | setSuccess('Congratulation! your payment is completed.') 78 | event.target.reset() 79 | //store payment on database 80 | } 81 | } 82 | return ( 83 | <> 84 |
85 | 101 | 108 | 109 | {cardError &&

{cardError}

} 110 | {success && ( 111 |
112 |

{success}

113 |

114 | Your Transaction Id:{' '} 115 | 116 | {transactionId} 117 | 118 |

119 |
120 | )} 121 | 122 | ) 123 | } 124 | 125 | export default CheckoutForm 126 | -------------------------------------------------------------------------------- /src/Pages/Homepage/AboutUs/AboutUs.js: -------------------------------------------------------------------------------- 1 | import React, { useContext } from 'react'; 2 | import { GiCheckMark } from 'react-icons/gi'; 3 | import { DarkModeContext } from '../../../App'; 4 | 5 | const AboutUs = () => { 6 | const [darkMode] = useContext(DarkModeContext) 7 | 8 | return ( 9 |
10 |

11 | About Us 12 |

13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | 22 |
23 |

25

24 |

Years

25 |

Exprience

26 |
27 |
28 |
29 |
30 | {/*
About Us
*/} 31 |

We Have 25 Years of Experience With a big fame our and company

32 |

Lorem ipsum dolor sit amet consectetur, adipisicing elit. Deleniti aliquam aspernatur itaque corrupti iste repellendus architecto adipisci recusandae enim doloribus?

33 |
    34 |
  • Hight Quality Work
  • 35 |
  • Expert & Professional
  • 36 |
  • Client Managment
  • 37 |
  • 24+7 Emergency Service
  • 38 |
39 | 43 |
44 |
45 |
46 | ); 47 | }; 48 | 49 | export default AboutUs; -------------------------------------------------------------------------------- /src/Pages/Homepage/Engineer/Engineer.js: -------------------------------------------------------------------------------- 1 | import React, { useContext, useEffect, useState } from "react"; 2 | import { 3 | BsFacebook, 4 | BsTwitter, 5 | BsLinkedin, 6 | BsGithub, 7 | BsBehance, 8 | } from "react-icons/bs"; 9 | import { Autoplay, FreeMode, Pagination } from "swiper"; 10 | import { Swiper, SwiperSlide } from "swiper/react"; 11 | import "./Engineer.css"; 12 | 13 | // Import Swiper styles 14 | import "swiper/css"; 15 | import "swiper/css/effect-coverflow"; 16 | import "swiper/css/pagination"; 17 | import { DarkModeContext } from "../../../App"; 18 | import useEngineers from "../../../hooks/useEngineers"; 19 | 20 | const Engineer = () => { 21 | const [engineers] = useEngineers([]); 22 | const [darkMode] = useContext(DarkModeContext); 23 | // console.log(engineers); 24 | return ( 25 |
26 | 51 | {engineers?.map((engineer) => { 52 | const { photo, name, surname, _id } = engineer; 53 | return ( 54 | 55 |
56 |
57 | Person 58 |

{name}

59 |
60 | {/*
902 Post
61 | 62 |
1300 Likes
*/} 63 |

{surname}

64 |
65 | 87 |
88 | 94 | 100 |
101 |
102 |
103 |
104 | ); 105 | })} 106 |
107 |
108 | ); 109 | }; 110 | 111 | export default Engineer; 112 | -------------------------------------------------------------------------------- /src/Pages/Dashboardpage/myOrders/forEngineer/AcceptModal.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | import React, { useRef } from 'react' 3 | import { useForm } from 'react-hook-form' 4 | import emailjs from '@emailjs/browser' 5 | import toast from 'react-hot-toast' 6 | 7 | const AcceptModal = ({ booking, refetch, setBookingModal }) => { 8 | console.log(booking?._id) 9 | const { 10 | register, 11 | formState: { errors }, 12 | handleSubmit, 13 | reset, 14 | } = useForm() 15 | const form = useRef() 16 | 17 | // const sendEmail = (data) => { 18 | // console.log(data); 19 | // setBookingModal(false); 20 | // emailjs.sendForm('neighbourHome', 'template_2jdv676', form.current, 'fjfswEx9fDSDkZnui') 21 | // .then((res) => { 22 | // console.log(res) 23 | // if (res.status === 200) { 24 | // toast.success("Message sent successfully", { id: 'success' }) 25 | // reset() 26 | // } 27 | // }, (err) => { 28 | // toast.error("Message not sent", { id: 'error' }) 29 | // }) 30 | // }; 31 | const onSubmit = async data => { 32 | const updateStatus = { 33 | ...data, 34 | status: 'complete', 35 | } 36 | console.log(updateStatus) 37 | axios 38 | .put( 39 | `https://neighbour-home-backend.onrender.com/booking/${booking._id}`, 40 | updateStatus 41 | ) 42 | .then(data => { 43 | console.log(data.data) 44 | 45 | toast.success(`this hiring request has been Successfully accept`) 46 | refetch() 47 | }) 48 | .catch(error => { 49 | console.log(error.response.data) 50 | if (error.response.status === 403) { 51 | toast.error('You are Not Admin') 52 | } 53 | }) 54 | setBookingModal(false) 55 | reset() 56 | // console.log('update done'); 57 | } 58 | return ( 59 |
60 | 61 |
62 |
63 | 69 | {/*

Booking for: {name}

*/} 70 |
74 |

75 | Give a description and price for your Deal 76 |

77 | 90 | 103 | 109 |
110 |
111 |
112 |
113 | ) 114 | } 115 | 116 | export default AcceptModal 117 | -------------------------------------------------------------------------------- /.firebase/hosting.YnVpbGQ.cache: -------------------------------------------------------------------------------- 1 | Blog.json,1661507993062,b51faaf462a9873872d8474bf45d3d8d4e7788ad5fedcc10016f4f7aa2e10035 2 | books.json,1659379612498,77a058acf9744020aac512818a193af833e46b6270d37aff4b5cb8dee2bc7d4a 3 | card.json,1659379612511,c9300b201458e6a3aef794880d2206f19d900e7f130c93105602eaf1cfa38d3c 4 | engineers.json,1659379612512,5fb0156d008cd8bc715df9ab34d19757d8a1dc6c7dd16e58dcfc0fd5d47d1fcf 5 | favicon.ico,1658150891455,eae62e993eb980ec8a25058c39d5a51feab118bd2100c4deebb2a9c158ec11f9 6 | logo192.png,1658150895676,3ee59515172ee198f3be375979df15ac5345183e656720a381b8872b2a39dc8b 7 | logo512.png,1658150895808,ee7e2f3fdb8209c4b6fd7bef6ba50d1b9dba30a25bb5c3126df057e1cb6f5331 8 | manifest.json,1658150893914,aff3449bdc238776f5d6d967f19ec491b36aed5fb7f23ccff6500736fd58494a 9 | pricing.json,1661507993073,c91903abd79d0cc34f8540a3df760517abf1c65b5629f24683428b506919ad73 10 | projects.json,1660902768755,8b69b98d6ab35d9de100b5baf3d03293367aae8edf5d89da81b2b562801af35d 11 | properties.json,1660298831866,b80592ec21307176153da013c954631bf53b93c3ae4e81c1f2f356b3a698c7a4 12 | review.json,1659379612512,15f88fdf0d3c2c7041ae19a42849c2b566396a2e7ee1882d9c4b9f2a3310b9da 13 | reviews.json,1659379612512,316f256dfbc71b4e1f20e66df6cf58ff66b7da380bc51b63aa3853febf8c8a3e 14 | robots.txt,1658150896169,bfe106a3fb878dc83461c86818bf74fc1bdc7f28538ba613cd3e775516ce8b49 15 | asset-manifest.json,1662387465449,21e32bda19afce88638295b7e1663bd6f4e180f388b456396bff9c6f576f2e1e 16 | index.html,1662387465344,30b34740784d9ff0b0eaeb9942f146cfb9a56ca831934351601962316941f35e 17 | static/js/787.3ba11d1c.chunk.js,1662387465450,12c692388869ad9f14c585cebd0470b88f8fb09641a228e1ff8908b4de6094f6 18 | static/js/787.3ba11d1c.chunk.js.map,1662387465451,c6be07b664b44979ef8f6457043bad5038f21c180eb31d2944f0ce204a90c237 19 | static/js/main.d5c2f04b.js.LICENSE.txt,1662387465351,d8730a6d8814c8fd8a3cf2b55e10e563159de3273de8a341d344075ad8f912e8 20 | static/media/construction-dashbord.1a3050bded35f35ca19ed2a0b03857e3.svg,1662387465351,7d6050d9704c4a6fe2f6f8d44320295eb6f9ca79514887dbcd9fa75eb0d85c78 21 | static/media/book-svgrepo-com.b58dbb018b8d94b07ba7c4024fc7cecd.svg,1662387465351,b3b150451a5f31cac82dbad74e8e334f151d3b456c751423a2ee7b3d0aeeb29f 22 | static/media/download-svgrepo-com.b6ef6b6bccade43d302ea7ac9a5739ec.svg,1662387465351,1616ce4ac3035d61cb5f490f81c42c2c6775033323031c9da050cb42b309b70e 23 | static/media/engineer-dashbord.ae624e18472f276830a1c6d783a5a693.svg,1662387465351,689fe0855659242e9b51dcddc2f60334903d2ee7bc22033e07959f1ce7b51324 24 | static/media/facebook.6e748ec94bab876259c5996837e2cbd4.svg,1662387465351,b9d4b7f4c1a3b58c2c3c1770fbb5c35d53870cb5e0165d82f731d475cfaa2e8c 25 | static/media/google.a45b46e964c34094185e40d691917f1b.svg,1662387465351,b11b7a7c359abd7811d1cb8b80280c7d0f067b8661d7790cf6b42f2f27439478 26 | static/media/orders-icon.2fe5fc1abf47002aa50fd8bd3c0a81ce.svg,1662387465351,de1a6f6a0dda6925f962d5d5b6dc4e94dc54ca0cd7892f931df14d9b35a1d69d 27 | static/media/review-dashbord.77ff9840bd3878f9de29a81be17f3ced.svg,1662387465351,b6d3a7f9bf3d6b05acc75c4cc4d3d8badfcb4ad3603f357c8b3c79e9f226fbe0 28 | static/media/user-dashbord.408f2818b2b26eaceac93b9148731dd9.svg,1662387465351,ed47c5d2539f0b163a92e3941afb8da653028ea73e81b0ea5144260abe859926 29 | static/media/user-profile-svgrepo-com.202a56b1491dc10964249c7adb38fbd2.svg,1662387465351,e61a5509f57a9519fecbfa9234c47cb0d6ac530fc878d92340e32f43999aaa99 30 | static/media/virustotal-svgrepo-com.9c62cda26c5785447da603e2f540c792.svg,1662387465351,98b40ac30bdd4e7831fd4349e58166599bc887f3186de9b68f1d6419c0223138 31 | static/css/main.287db717.css.map,1662387465450,b57c938a9c59167301126662a052d151815b6f44230b8084279f3a6e1f96a434 32 | static/css/main.287db717.css,1662387465351,a63a28ea369180ceed7b0ab913bdebe2b49da19d05c7e6ccc9ea2199278c29d0 33 | static/media/Contact.6862975ba67ea422e9b7.gif,1662387465450,9c566281626fce7f13e00254867ab8f3e25ad20b074261f9a87490a16d3b7ea7 34 | static/js/main.d5c2f04b.js,1662387465353,6b8862d8cd4a1311c70ce378876314acae11b32e6fd5419719d9a5f47b67c330 35 | static/js/main.d5c2f04b.js.map,1662387465468,87c86c2a811fda59f0f172877808b6fdd0bbe8c1c5719996c15e623a09493b49 36 | -------------------------------------------------------------------------------- /src/Pages/Homepage/Engineer/Engineer.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Baloo+Paaji+2:wght@400;500&display=swap"); 2 | 3 | /* .container { 4 | display: grid; 5 | grid-template-columns: 300px 300px 300px; 6 | grid-gap: 50px; 7 | justify-content: center; 8 | align-items: center; 9 | height: 100vh; 10 | background-color: #f5f5f5; 11 | font-family: "Baloo Paaji 2", cursive; 12 | } 13 | */ 14 | .engCard { 15 | height: 27rem; 16 | border: 1px solid rgba(237, 237, 237, 0.843); 17 | border-radius: 5px; 18 | display: flex; 19 | flex-direction: column; 20 | align-items: center; 21 | /* box-shadow: 5px 5px 35px #acacac, -5px -5px 35px #ffffff; */ 22 | /* color: white; */ 23 | } 24 | 25 | .card__name { 26 | margin-top: 15px; 27 | font-size: 1.5em; 28 | } 29 | 30 | .card__image { 31 | height: 160px; 32 | width: 160px; 33 | border-radius: 50%; 34 | border: 5px solid #272133; 35 | margin-top: 20px; 36 | 37 | /* box-shadow: 0 10px 50px rgba(13, 148, 137, 0.672); */ 38 | } 39 | 40 | .draw-border { 41 | box-shadow: inset 0 0 0 4px #eeeeee; 42 | color: #58afd1; 43 | -webkit-transition: color 0.25s 0.0833333333s; 44 | transition: color 0.25s 0.0833333333s; 45 | position: relative; 46 | } 47 | 48 | .draw-border::before, 49 | .draw-border::after { 50 | border: 0 solid transparent; 51 | box-sizing: border-box; 52 | content: ""; 53 | pointer-events: none; 54 | position: absolute; 55 | width: 0rem; 56 | height: 0; 57 | bottom: 0; 58 | right: 0; 59 | } 60 | 61 | .draw-border::before { 62 | border-bottom-width: 4px; 63 | border-left-width: 4px; 64 | } 65 | 66 | .draw-border::after { 67 | border-top-width: 4px; 68 | border-right-width: 4px; 69 | } 70 | 71 | .draw-border:hover::before, 72 | .draw-border:hover::after { 73 | border-color: #0d9488; 74 | -webkit-transition: border-color 0s, width 0.25s, height 0.25s; 75 | transition: border-color 0s, width 0.25s, height 0.25s; 76 | width: 100%; 77 | height: 100%; 78 | } 79 | 80 | .draw-border:hover::before { 81 | -webkit-transition-delay: 0s, 0s, 0.25s; 82 | transition-delay: 0s, 0s, 0.25s; 83 | } 84 | 85 | .draw-border:hover::after { 86 | -webkit-transition-delay: 0s, 0.25s, 0s; 87 | transition-delay: 0s, 0.25s, 0s; 88 | } 89 | 90 | .engBtn { 91 | /* background: white; */ 92 | border: none; 93 | cursor: pointer; 94 | font: 500 1.2rem; 95 | padding: 0.24em 1em; 96 | margin: 1em; 97 | width: 7rem; 98 | } 99 | .engBtn:hover { 100 | background: transparent; 101 | } 102 | 103 | .engBtn:focus { 104 | outline: 2px dotted #55d7dc; 105 | } 106 | 107 | .social-icons { 108 | padding: 0; 109 | list-style: none; 110 | margin: 1em; 111 | } 112 | 113 | .social-icons li { 114 | display: inline-block; 115 | margin: 0.15em; 116 | position: relative; 117 | font-size: 1em; 118 | } 119 | 120 | .social-icons i { 121 | /* color: #fff; */ 122 | position: absolute; 123 | top: 0.95em; 124 | left: 0.96em; 125 | transition: all 265ms ease-out; 126 | } 127 | 128 | .social-icons a svg { 129 | position: absolute; 130 | top: 14px; 131 | left: 14px; 132 | font-size: 18px; 133 | color: white; 134 | } 135 | .social-icons a:before { 136 | transform: scale(1); 137 | -ms-transform: scale(1); 138 | -webkit-transform: scale(1); 139 | content: " "; 140 | width: 45px; 141 | height: 45px; 142 | border-radius: 100%; 143 | display: block; 144 | background: linear-gradient(45deg, #0fbbac, #0d9488); 145 | transition: all 265ms ease-out; 146 | } 147 | 148 | .social-icons a:hover:before { 149 | transform: scale(0); 150 | transition: all 265ms ease-in; 151 | } 152 | 153 | .social-icons a:hover svg { 154 | transform: scale(2.2); 155 | -ms-transform: scale(2.2); 156 | -webkit-transform: scale(2.2); 157 | color: #0d9488; 158 | background: -webkit-linear-gradient(45deg, #ff003c, #c648c8); 159 | -webkit-background-clip: text; 160 | -webkit-text-fill-color: transparent; 161 | transition: all 265ms ease-in; 162 | } 163 | 164 | .grid-container { 165 | display: grid; 166 | grid-template-columns: 1fr 1fr; 167 | grid-gap: 20px; 168 | font-size: 1.2em; 169 | } 170 | -------------------------------------------------------------------------------- /src/Pages/Dashboardpage/myOrders/forEngineer/MyHiringRow.js: -------------------------------------------------------------------------------- 1 | import React, { useContext, useRef } from 'react' 2 | import { DarkModeContext } from '../../../../App' 3 | import { useForm } from 'react-hook-form' 4 | import toast from 'react-hot-toast' 5 | import emailjs from '@emailjs/browser' 6 | import swal from 'sweetalert' 7 | import axios from 'axios' 8 | import { Link } from 'react-router-dom' 9 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' 10 | import { faTrashCan } from '@fortawesome/free-solid-svg-icons' 11 | import AcceptModal from './AcceptModal' 12 | import { useState } from 'react' 13 | 14 | const MyHiringRow = ({ index, d, refetch }) => { 15 | // console.log(d?.data?.customerEmail); 16 | const { customerEmail, customerPhone, customerName } = d?.data 17 | const { name, email, _id, phone } = d?.engineer 18 | let { status } = d 19 | const [bookingModal, setBookingModal] = useState(true) 20 | const [darkMode] = useContext(DarkModeContext) 21 | const { 22 | register, 23 | formState: { errors }, 24 | handleSubmit, 25 | reset, 26 | } = useForm() 27 | const form = useRef() 28 | const lastEmail = d?.engineer?.email.split('@') 29 | 30 | // const sendEmail = (data) => { 31 | // emailjs 32 | // .sendForm( 33 | // "neighbourHome", 34 | // "template_2jdv676", 35 | // form.current, 36 | // "fjfswEx9fDSDkZnui" 37 | // ) 38 | // .then( 39 | // (res) => { 40 | // console.log(res); 41 | // if (res.status === 200) { 42 | // toast.success("Message sent successfully", { id: "success" }); 43 | // reset(); 44 | // } 45 | // }, 46 | // (err) => { 47 | // toast.error("Message not sent", { id: "error" }); 48 | // } 49 | // ); 50 | // }; 51 | 52 | const handleDelete = id => { 53 | swal({ 54 | title: 'Are you sure?', 55 | text: 'Once deleted, you will not be able to recover this file!', 56 | icon: 'warning', 57 | buttons: true, 58 | dangerMode: true, 59 | }).then(willDelete => { 60 | if (willDelete) { 61 | fetch(`https://neighbour-home-backend.onrender.com/booking/${id}`, { 62 | method: 'DELETE', 63 | headers: { 64 | 'Content-Type': 'application/json', 65 | }, 66 | }) 67 | .then(res => res.json()) 68 | .then(data => { 69 | console.log(data) 70 | if (data.message) { 71 | swal('Your file has been deleted!', { 72 | icon: 'success', 73 | }) 74 | refetch() 75 | } 76 | }) 77 | } 78 | }) 79 | } 80 | return ( 81 | 82 | {index + 1} 83 | 84 | {customerName} 85 | {customerEmail} 86 | 87 | {name} 88 | {email} 89 | {phone} 90 | 91 | {d.status === 'processing' ? 'pending' : 'processing'} 92 | 93 | 94 |
95 | 96 | 99 | 100 | handleDelete(d._id)} 102 | className="text-red-500 ml-2 mt-1 inline-block align-middle" 103 | icon={faTrashCan} 104 | /> 105 |
106 |
107 |
108 | 115 |
116 | {bookingModal && ( 117 | 122 | )} 123 |
124 | 125 | 126 | ) 127 | } 128 | 129 | export default MyHiringRow 130 | -------------------------------------------------------------------------------- /public/Blog.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "title": "Changes Influencing Garage Space.", 4 | "type": "Business", 5 | "url": "https://magazine.realtor/sites/default/files/styles/asset_image_full_content/public/assets/images/2208_HD_GarageTrends.png?itok=J0zuezKh", 6 | "date": "12", 7 | "month": "Jan", 8 | "body": "During the pandemic, many people took up outdoor hobbies, says Laurel Vernazza, home design expert at The Plan Collection. As a result, space to store outdoor gear such as kayaks, paddleboards, golf clubs and bicycles tops the list of garage needs.The pandemic also fueled requests for more quiet spaces away from the main part of the home, and garages sometimes served as a retreat, a home office or a gym.Though it may not rank as high as the desire for an updated kitchen or owner’s bathroom, having a finished garage with flexible space has moved up on many buyers’ wish lists." 9 | }, 10 | { 11 | "title": "Add a Touch of Lush With a Staircase Garden", 12 | "type": "Business", 13 | "url": "https://magazine.realtor/sites/default/files/styles/asset_image_full_content/public/assets/images/2208_HD_StaircaseGardens.png?itok=maZW3ygz", 14 | "date": "19", 15 | "month": "May", 16 | "body": "Staircases serve an important function both in and out of homes, but their ability to add aesthetic value to a space often goes unrealized. As the desire to bring nature into the home has increased in recent years, homeowners have found a new purpose for these transitional features: staircase gardens. Evoking whimsy, staircases adorned with potted plants or trailing vines add a pop of vibrancy and life to an otherwise overlooked space.According to Pinterest’s trending searches, interest in staircase gardens is on the rise. Gardening and interest in houseplants, especially by millennials, have both experienced a boom during the pandemic as people have spent more time at home. All that time at home has also allowed people to look at spaces that don’t get used beyond their function, including staircases, but people are bringing them back into the fold using plants. “I think that they may be looking again at their spaces because they've been spending more time in their home environments,” says Mary Barensfeld, a Pittsburgh-based architect. “I think there's something that draws people toward nature, whether that's going for spending time outdoors or bringing nature into the home and working amongst nature.”" 17 | }, 18 | { 19 | "title": "How the Pandemic Triggered Vacation House Changes", 20 | "type": "Business", 21 | "url": "https://magazine.realtor/sites/default/files/styles/asset_image_full_content/public/assets/images/2208_HD_VacationHomes.png?itok=VDR6PScI", 22 | "date": "02", 23 | "month": "Nov", 24 | "body": "During the second half of 2020 and through 2021, vacation home sales skyrocketed, according to a report from the National Association of REALTORS®. Today, vacation houses provide important stress relief to the woes of post-pandemic life. As COVID-19 transmission continues to ebb and flow, these homes offer a mental and physical escape as well as a way for extended families and sometimes groups of friends to gather safely, particularly those whose primary homes are in dense urban areas.Some buyers also view their vacation house as an investment opportunity for rental income. Since vacation homes are typically used for short spurts of time, short-term rental services like Airbnb and VRBO provide opportunities to generate income when the house isn’t in use by the owner.”" 25 | }, 26 | { 27 | "title": "I Have to Pay for That?", 28 | "type": "Classic", 29 | "url": "https://magazine.realtor/sites/default/files/styles/asset_image_full_content/public/assets/images/2106_DNG_youngadults.jpg?itok=E3L_JIwA", 30 | "date": "22", 31 | "month": "Aug", 32 | "body": "When they experience their first leaky faucet, cold blast of air, or foundation crack, many first-time home buyers panic. Help ward off regret by connecting them with specialists and giving them a rundown of important maintenance checks. HVAC system. It should be cleaned and tested at the start of a season—furnace in the fall and central air (or units) in the spring. Shrubbery should be kept from the AC’s outside condenser unit, says contractor Michael Kozas. Boilers should also be cleaned and hot water heaters inspected, he says. Homeowners should change filters regularly.”" 33 | } 34 | 35 | ] -------------------------------------------------------------------------------- /src/Pages/Homepage/Reviews/Reviews.js: -------------------------------------------------------------------------------- 1 | import React, { useContext, useEffect, useState } from 'react' 2 | import { BsFacebook, BsTwitter, BsLinkedin, BsGithub } from 'react-icons/bs' 3 | import { AiOutlineStar } from 'react-icons/ai' 4 | import { Autoplay, FreeMode, Pagination } from 'swiper' 5 | import { Swiper, SwiperSlide } from 'swiper/react' 6 | import { DarkModeContext } from '../../../App' 7 | import { Link } from 'react-router-dom' 8 | 9 | const Reviews = () => { 10 | const [reviews, setReviews] = useState([]) 11 | const [darkMode] = useContext(DarkModeContext) 12 | 13 | useEffect(() => { 14 | fetch('https://neighbour-home-backend.onrender.com/review') 15 | .then(res => res.json()) 16 | .then(data => setReviews(data)) 17 | }, []) 18 | return ( 19 |
20 |

26 | Review 27 |

28 |
29 |
30 |
31 |
32 |
33 |
34 | 59 | {reviews.map(review => { 60 | const { picture, name, date, stars, reviewTxt, _id } = review 61 | return ( 62 | 63 |
68 |
69 |
70 |
71 | 76 |
77 |
78 |

{name}

79 |
80 |
81 |
82 | 87 | 88 | 89 | 90 | {stars} 91 | 92 |
93 |
94 |
95 | {reviewTxt.slice(0, 90)}...{' '} 96 |
97 |
98 |
99 | ) 100 | })} 101 |
102 |
103 |
104 | 105 | 115 | 116 |
117 |
118 | ) 119 | } 120 | 121 | export default Reviews 122 | -------------------------------------------------------------------------------- /src/Pages/Dashboardpage/orders/OrderRow.js: -------------------------------------------------------------------------------- 1 | import React, { useContext, useRef, useState } from 'react' 2 | import { Link } from 'react-router-dom' 3 | import emailjs from '@emailjs/browser' 4 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' 5 | import { faTrash, faTrashCan } from '@fortawesome/free-solid-svg-icons' 6 | import { DarkModeContext } from '../../../App' 7 | import { useForm } from 'react-hook-form' 8 | import toast from 'react-hot-toast' 9 | import axios from 'axios' 10 | import swal from 'sweetalert' 11 | 12 | const OrderRow = ({ index, d, refetch }) => { 13 | // console.log(d?.data?.customerEmail); 14 | const { customerEmail, customerPhone, customerName } = d?.data 15 | const { name, email, _id, phone } = d?.engineer 16 | let { status } = d 17 | const [darkMode] = useContext(DarkModeContext) 18 | const { 19 | register, 20 | formState: { errors }, 21 | handleSubmit, 22 | reset, 23 | } = useForm() 24 | const form = useRef() 25 | 26 | const sendEmail = data => { 27 | emailjs 28 | .sendForm( 29 | 'neighbourHome', 30 | 'template_2jdv676', 31 | form.current, 32 | 'fjfswEx9fDSDkZnui' 33 | ) 34 | .then( 35 | res => { 36 | console.log(res) 37 | if (res.status === 200) { 38 | toast.success('Message sent successfully', { id: 'success' }) 39 | reset() 40 | } 41 | }, 42 | err => { 43 | toast.error('Message not sent', { id: 'error' }) 44 | } 45 | ) 46 | } 47 | 48 | const handleStatus = id => { 49 | const updatedStatus = { 50 | status: 'processing', 51 | // price: ' ', 52 | // description: ' ' 53 | } 54 | axios 55 | .put( 56 | `https://neighbour-home-backend.onrender.com/booking/${id}`, 57 | updatedStatus 58 | ) 59 | .then(data => { 60 | console.log(data.data) 61 | 62 | toast.success(`this hiring request has been Successfully accept`) 63 | refetch() 64 | }) 65 | .catch(error => { 66 | console.log(error.response.data) 67 | if (error.response.status === 403) { 68 | toast.error('You are Not Admin') 69 | } 70 | }) 71 | } 72 | 73 | const handleDelete = id => { 74 | swal({ 75 | title: 'Are you sure?', 76 | text: 'Once deleted, you will not be able to recover this file!', 77 | icon: 'warning', 78 | buttons: true, 79 | dangerMode: true, 80 | }).then(willDelete => { 81 | if (willDelete) { 82 | fetch(`https://neighbour-home-backend.onrender.com/booking/${id}`, { 83 | method: 'DELETE', 84 | headers: { 85 | 'Content-Type': 'application/json', 86 | }, 87 | }) 88 | .then(res => res.json()) 89 | .then(data => { 90 | console.log(data) 91 | if (data.message) { 92 | swal('Your file has been deleted!', { 93 | icon: 'success', 94 | }) 95 | refetch() 96 | } 97 | }) 98 | } 99 | }) 100 | } 101 | return ( 102 | 103 | {index + 1} 104 | 105 | {customerName} 106 | {customerEmail} 107 | {customerPhone} 108 | 109 | {name} 110 | {email} 111 | {phone} 112 | 113 |
114 | 115 | 118 | 119 | handleDelete(d._id)} 121 | className="text-red-500 ml-2 mt-1 inline-block align-middle" 122 | icon={faTrashCan} 123 | /> 124 |
125 |
126 |
127 | 133 | 139 | 145 | 152 |
153 |
154 | 155 | 156 | ) 157 | } 158 | 159 | export default OrderRow 160 | -------------------------------------------------------------------------------- /src/Pages/Properties/Properties.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import { User } from 'react-feather'; 3 | import useRole from '../../hooks/useRole'; 4 | import Loading from '../../Shared/Loading/Loading'; 5 | import Property from './Property'; 6 | import SellPostModal from './SellPostModal'; 7 | 8 | const Properties = ({ refetch, isLoading, properties }) => { 9 | const [manageSellPostModal, setManageSellPostModal] = useState(false) 10 | const [role, roleLoading] = useRole(User) 11 | if (isLoading || roleLoading) return 12 | console.log(role); 13 | return ( 14 |
15 |
16 | { 17 | role === "Seller" && 18 | <> 19 | 26 | 27 | { 28 | manageSellPostModal && 29 | 34 | } 35 | 36 | } 37 | 38 |
39 | {/* */} 40 | 64 | {/* */} 65 | 81 |
82 | 83 |
84 |
85 | { 86 | properties?.map(property => ) 90 | } 91 |
92 |
93 | 94 | ); 95 | }; 96 | 97 | export default Properties; -------------------------------------------------------------------------------- /src/Assest/review-dashbord.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 24 | 26 | 28 | 29 | 30 | 45 | 47 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /src/Pages/Dashboardpage/Constructors/Constructors.js: -------------------------------------------------------------------------------- 1 | import React, { useContext, useState, useEffect } from 'react' 2 | import { useQuery } from '@tanstack/react-query' 3 | import Constructor from './Constructor' 4 | import { DarkModeContext } from '../../../App' 5 | import { useForm } from 'react-hook-form' 6 | import Loading from '../../../Shared/Loading/Loading' 7 | import Swal from 'sweetalert2' 8 | import FormConstructor from './FormConstructor' 9 | 10 | const Constructors = () => { 11 | const [darkMode] = useContext(DarkModeContext) 12 | const [loading, setLoading] = useState(false) 13 | const { 14 | register, 15 | formState: { errors }, 16 | handleSubmit, 17 | reset, 18 | } = useForm() 19 | const { isLoading, error, data, refetch } = useQuery(['constructor'], () => 20 | fetch('https://neighbour-home-backend.onrender.com/constructor').then( 21 | res => res.json() 22 | ) 23 | ) 24 | const imgStorageKey = '75bc4682c9291f359647ab98df5f76de' 25 | 26 | const getData = data => { 27 | const image = data?.photo[0] 28 | const formData = new FormData() 29 | formData.append('image', image) 30 | const url = `https://api.imgbb.com/1/upload?key=${imgStorageKey}` 31 | 32 | // posting image to imgbb for getting hosted link 33 | fetch(url, { 34 | method: 'POST', 35 | body: formData, 36 | }) 37 | .then(res => res.json()) 38 | .then(result => { 39 | if (result.success) { 40 | const photo = result.data.display_url 41 | const constructor = { 42 | picture: photo, 43 | title: data.title, 44 | type: data.type, 45 | duration: data.duration, 46 | assignment: data.assignment, 47 | discount: data.discount, 48 | price: data.price, 49 | description: data.description, 50 | } 51 | fetch( 52 | 'https://neighbour-home-backend.onrender.com/constructor', 53 | { 54 | method: 'POST', 55 | headers: { 56 | 'Content-Type': 'application/json', 57 | }, 58 | body: JSON.stringify(constructor), 59 | } 60 | ) 61 | .then(res => res.json()) 62 | .then(data => { 63 | if (data.message === 'Constructor created successfully') { 64 | // e.target.reset() 65 | // reset() 66 | Swal.fire({ 67 | position: 'center', 68 | icon: 'success', 69 | title: 'Your Data has been saved', 70 | showConfirmButton: false, 71 | timer: 1500, 72 | }) 73 | 74 | refetch() 75 | } else { 76 | Swal.fire({ 77 | icon: 'error', 78 | title: 'Oops...', 79 | text: 'Something went wrong!', 80 | }) 81 | } 82 | }) 83 | } 84 | }) 85 | } 86 | 87 | if (isLoading) return 88 | 89 | if (error) return 'An error has occurred: ' + error.message 90 | 91 | return ( 92 |
93 | {/* Add new button for adding constructor */} 94 |
95 | {/* */} 96 | 97 | {/* */} 98 | 104 |
105 | 106 | {/* */} 107 | 108 |
109 |
110 | 116 |

117 | Please provide the following information! 118 |

119 | {/* form */} 120 | 127 |
128 |
129 | 130 |
131 | 136 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 157 | {data.map((constructor, index) => ( 158 | 164 | ))} 165 | 166 |
Sl.TitleTypePriceDurationDiscountProjectsAction
167 |
168 |
169 | ) 170 | } 171 | 172 | export default Constructors 173 | -------------------------------------------------------------------------------- /src/Pages/Properties/PropertySearchBar.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import SellPostModal from './SellPostModal'; 3 | 4 | const PropertySearchBar = ({ refetch }) => { 5 | const [manageSellPostModal, setManageSellPostModal] = useState(false) 6 | return ( 7 |
8 |
9 |
10 |
11 | 12 |
13 |
14 | 21 | 22 | { 23 | manageSellPostModal && 24 | 29 | } 30 | 31 |
32 | {/* */} 33 | 57 | {/* */} 58 | 74 |
75 | 76 |
77 |
78 |
79 |
80 | ); 81 | }; 82 | 83 | export default PropertySearchBar; -------------------------------------------------------------------------------- /src/Pages/Homepage/BookReview/BookReview.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react' 2 | import { useParams } from 'react-router-dom' 3 | 4 | const BookReview = () => { 5 | const { _id } = useParams() 6 | 7 | const [book, setBook] = useState([]) 8 | const { picture, description, name, pdf } = book 9 | useEffect(() => { 10 | fetch(`https://neighbour-home-backend.onrender.com/book/${_id}`) 11 | .then(res => res.json()) 12 | .then(data => setBook(data)) 13 | }, []) 14 | return ( 15 |
16 |
17 |
18 |
19 | bookImage 24 |
25 |

26 | New 27 |

28 |

29 | {name} 30 |

31 |
32 | 33 | 42 | 43 | 44 | 53 | 54 | 55 | 64 | 65 | 66 | 75 | 76 | 77 | 86 | 87 | 88 | 4 Reviews 89 | 90 |
91 |

{description}

92 | {/*
93 |
94 | Color 95 | 96 | 97 | 98 |
99 | 100 |
*/} 101 |
102 | 103 | Free 104 | 105 | 111 | Download 112 | 113 | 125 |
126 |
127 |
128 |
129 |
130 |
131 | ) 132 | } 133 | 134 | export default BookReview 135 | --------------------------------------------------------------------------------