├── .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 |
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 && {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 |
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 |
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 |
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 | You need to enable JavaScript to run this app.
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 |
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 |
15 |
16 |
17 |
18 | {name}
19 | {userName}
20 |
21 |
22 | View Profile
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 |
15 |
16 |
17 |
18 | {name}
19 | {name}
20 |
21 |
22 | View Profile
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 |
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 |
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 |
setNotificationModal(false)}
15 | for="notificattonModal"
16 | className="cursor-pointer text-2xl absolute right-6 top-3"
17 | >
18 |
19 |
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 |
13 | {/*
14 | {price}
15 |
*/}
16 | {/*
17 | {discount}
18 |
*/}
19 |
20 |
21 | {title}
22 |
23 |
24 | {description}
25 |
26 |
27 |
28 | Details
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 |
45 | ✕
46 |
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 |
39 | Download The Guides
40 |
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 |
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 | customer
41 | Email
42 | Phone
43 | Profession
44 | email
45 | Phone
46 |
47 | Action
48 |
49 |
50 |
53 | {data?.map((d, index) => (
54 |
60 | ))}
61 |
62 |
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 | window.history.back()} className='lg:ml-24 btn btn-sm'>back
19 |
All Workers: {workers?.length}
20 |
21 |
22 |
23 |
24 |
25 |
26 | Avatar
27 | Name
28 | Profession
29 | Details
30 |
31 |
32 |
33 | {
34 | workers?.map((worker, index)=> )
40 | }
41 |
42 |
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 |
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 | navigate(`/payment/${_id}`)}
37 | >Book Now
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 | window.history.back()} className='lg:ml-24 btn btn-sm'>back
18 |
All Engineers: {engineers?.length}
19 |
20 |
21 |
22 |
23 |
24 |
25 | Avatar
26 | Name
27 | Profession
28 | Details
29 |
30 |
31 |
32 | {
33 | engineers?.map((engineer, index)=> )
39 | }
40 |
41 |
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 |
Get Started
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 | {/* Edit */}
78 |
79 | Edit
80 |
81 | handleDelete(_id)}
83 | className="btn btn-xs btn-warning"
84 | >
85 | Delete
86 |
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 |
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 |
46 | hire a engineer
47 |
48 |
49 |
50 |
51 | hire workers
52 |
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 |
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 | {/*
60 | Download
61 | */}
62 |
63 |
70 | Details
71 |
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 |
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 | //
Book Builder
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 |
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 |
83 | Download
84 |
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 |
81 | details
82 |
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 | Pay
95 |
96 | ) : (
97 | handleDelete(d._id)}
100 | >
101 | delete
102 |
103 | )}
104 | {/* delete */}
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 |
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 |
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 |
41 | Explore Now
42 |
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 |
58 |
{name}
59 |
60 | {/*
902 Post
61 |
62 |
1300 Likes
*/}
63 |
{surname}
64 |
65 |
87 |
88 |
92 | Follow
93 |
94 |
98 | massage
99 |
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 |
67 | ✕
68 |
69 | {/*
Booking for: {name} */}
70 |
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 |
97 | details
98 |
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 | setBookingModal(true)}
111 | className="btn btn-xs btn-success"
112 | >
113 | {status === 'processing' ? 'accept' : 'pending'}
114 |
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 |
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 |
112 | add review{' '}
113 |
114 |
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 |
116 | details
117 |
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 | handleStatus(d._id)}
149 | >
150 | {status ? status : 'accept'}
151 |
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 |
setManageSellPostModal(true)}
21 | for="sellPost"
22 | className=" text-lg font-medium border rounded-xl border-teal-400 py-1 cursor-pointer hover:bg-teal-400 hover:text-white px-5 mr-3 text-teal-600 duration-500"
23 | >
24 | Post Sell
25 |
26 |
27 | {
28 | manageSellPostModal &&
29 |
34 | }
35 | >
36 | }
37 |
38 |
39 | {/* */}
40 |
41 |
42 |
43 |
48 |
53 |
54 |
55 |
62 |
63 |
64 | {/* */}
65 |
69 |
74 |
79 |
80 |
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 | {/* Add New */}
96 |
97 | {/* */}
98 |
102 | Add New
103 |
104 |
105 |
106 | {/* */}
107 |
108 |
109 |
110 |
114 | ✕
115 |
116 |
117 | Please provide the following information!
118 |
119 | {/* form */}
120 |
127 |
128 |
129 |
130 |
131 |
136 |
143 |
144 | Sl.
145 | Title
146 | Type
147 | Price
148 | Duration
149 | Discount
150 | Projects
151 | Action
152 |
153 |
154 |
157 | {data.map((constructor, index) => (
158 |
164 | ))}
165 |
166 |
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 |
setManageSellPostModal(true)}
16 | for="sellPost"
17 | className=" text-lg font-medium border rounded-xl border-teal-400 py-1 cursor-pointer hover:bg-teal-400 hover:text-white px-5 mr-3 text-teal-600 duration-500"
18 | >
19 | Post Sell
20 |
21 |
22 | {
23 | manageSellPostModal &&
24 |
29 | }
30 |
31 |
32 | {/* */}
33 |
34 |
35 |
36 |
41 |
46 |
47 |
48 |
55 |
56 |
57 | {/* */}
58 |
62 |
67 |
72 |
73 |
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 |
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 |
126 |
127 |
128 |
129 |
130 |
131 | )
132 | }
133 |
134 | export default BookReview
135 |
--------------------------------------------------------------------------------