working before adding toastify

This commit is contained in:
QkoSad
2022-11-30 16:31:09 +02:00
parent 7d4e2d1b69
commit 98d2d372e8
38 changed files with 2822 additions and 98 deletions
+1636
View File
File diff suppressed because it is too large Load Diff
+2
View File
@@ -6,8 +6,10 @@
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"firebase": "^9.14.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.4.3",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

-38
View File
@@ -1,38 +0,0 @@
.App {
text-align: center;
}
.App-logo {
height: 40vmin;
pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
}
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
.App-link {
color: #61dafb;
}
@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
+21 -18
View File
@@ -1,24 +1,27 @@
import logo from './logo.svg';
import './App.css';
import Navbar from './components/Navbar'
import {BrowserRouter as Router,Routes, Route} from 'react-router-dom'
import Explore from './pages/Explore'
import Profile from './pages/Profile'
import ForgotPassword from './pages/ForgotPassword'
import Offers from './pages/Offers'
import Signin from './pages/Signin'
import Signup from './pages/Signup'
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
<>
<Router>
<Routes>
<Route path='/' element={<Explore />}/>
<Route path='/offers' element={<Offers />}/>
<Route path='/profile' element={<Profile />}/>
<Route path='/sign-in' element={<Signin />}/>
<Route path='/sign-up' element={<Signup />}/>
<Route path='/forgot-password' element={<ForgotPassword />}/>
</Routes>
<Navbar/>
</Router>
</>
);
}
-8
View File
@@ -1,8 +0,0 @@
import { render, screen } from '@testing-library/react';
import App from './App';
test('renders learn react link', () => {
render(<App />);
const linkElement = screen.getByText(/learn react/i);
expect(linkElement).toBeInTheDocument();
});
Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><g><rect fill="none" height="24" width="24"/></g><g><path d="M20,7h-5V4c0-1.1-0.9-2-2-2h-2C9.9,2,9,2.9,9,4v3H4C2.9,7,2,7.9,2,9v11c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V9 C22,7.9,21.1,7,20,7z M9,12c0.83,0,1.5,0.67,1.5,1.5S9.83,15,9,15s-1.5-0.67-1.5-1.5S8.17,12,9,12z M12,18H6v-0.75c0-1,2-1.5,3-1.5 s3,0.5,3,1.5V18z M13,9h-2V4h2V9z M18,16.5h-4V15h4V16.5z M18,13.5h-4V12h4V13.5z"/></g></svg>

After

Width:  |  Height:  |  Size: 521 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><g><rect fill="none" height="24" width="24"/></g><g><g><g><circle cx="7" cy="7" r="2"/></g><g><path d="M20,13V4.83C20,3.27,18.73,2,17.17,2c-0.75,0-1.47,0.3-2,0.83l-1.25,1.25C13.76,4.03,13.59,4,13.41,4 c-0.4,0-0.77,0.12-1.08,0.32l2.76,2.76c0.2-0.31,0.32-0.68,0.32-1.08c0-0.18-0.03-0.34-0.07-0.51l1.25-1.25 C16.74,4.09,16.95,4,17.17,4C17.63,4,18,4.37,18,4.83V13h-6.85c-0.3-0.21-0.57-0.45-0.82-0.72l-1.4-1.55 c-0.19-0.21-0.43-0.38-0.69-0.5C7.93,10.08,7.59,10,7.24,10C6,10.01,5,11.01,5,12.25V13H2v6c0,1.1,0.9,2,2,2c0,0.55,0.45,1,1,1 h14c0.55,0,1-0.45,1-1c1.1,0,2-0.9,2-2v-6H20z"/></g></g></g></svg>

After

Width:  |  Height:  |  Size: 730 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><g><rect fill="none" height="24" width="24"/></g><g><g><rect fill="none" height="3" width="5" x="6" y="7"/><rect fill="none" height="3" width="5" x="13" y="7"/><path d="M20,10V7c0-1.1-0.9-2-2-2H6C4.9,5,4,5.9,4,7v3c-1.1,0-2,0.9-2,2v5h1.33L4,19h1l0.67-2h12.67L19,19h1l0.67-2H22v-5 C22,10.9,21.1,10,20,10z M11,10H6V7h5V10z M18,10h-5V7h5V10z"/></g></g></svg>

After

Width:  |  Height:  |  Size: 490 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/></svg>

After

Width:  |  Height:  |  Size: 206 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"/></svg>

After

Width:  |  Height:  |  Size: 234 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"/></svg>

After

Width:  |  Height:  |  Size: 306 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm-5.5-2.5l7.51-3.49L17.5 6.5 9.99 9.99 6.5 17.5zm5.5-6.6c.61 0 1.1.49 1.1 1.1s-.49 1.1-1.1 1.1-1.1-.49-1.1-1.1.49-1.1 1.1-1.1z"/></svg>

After

Width:  |  Height:  |  Size: 409 B

+15
View File
@@ -0,0 +1,15 @@
<svg width="124" height="124" viewBox="0 0 124 124" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0)">
<path d="M119.081 51.0933L69.0114 51.0909C66.8004 51.0909 65.0083 52.8828 65.0083 55.0938V71.0887C65.0083 73.2992 66.8004 75.0916 69.0112 75.0916H97.2073C94.1198 83.1043 88.3572 89.8147 81.005 94.0785L93.0277 114.891C112.314 103.737 123.716 84.1664 123.716 62.2585C123.716 59.1391 123.486 56.9092 123.026 54.3982C122.677 52.4905 121.02 51.0933 119.081 51.0933Z" fill="#167EE6"/>
<path d="M62.3391 99.1246C48.5404 99.1246 36.4944 91.5853 30.0247 80.429L9.21289 92.4247C19.8039 110.781 39.6442 123.141 62.3391 123.141C73.4724 123.141 83.9775 120.144 93.0272 114.92V114.891L81.0044 94.0785C75.505 97.2682 69.141 99.1246 62.3391 99.1246Z" fill="#12B347"/>
<path d="M93.0275 114.919V114.891L81.0047 94.0781C75.5053 97.2675 69.1418 99.1242 62.3394 99.1242V123.141C73.4727 123.141 83.9783 120.143 93.0275 114.919Z" fill="#0F993E"/>
<path d="M24.9802 61.7646C24.9802 54.9631 26.8363 48.5999 30.0253 43.1007L9.21345 31.105C3.96074 40.1262 0.963379 50.6028 0.963379 61.7646C0.963379 72.9265 3.96074 83.4031 9.21345 92.4242L30.0253 80.4285C26.8363 74.9294 24.9802 68.5661 24.9802 61.7646Z" fill="#FFD500"/>
<path d="M62.3391 24.4057C71.3372 24.4057 79.6023 27.603 86.0581 32.9214C87.6508 34.2334 89.9656 34.1387 91.4244 32.6798L102.757 21.3467C104.413 19.6915 104.295 16.9821 102.527 15.4482C91.7102 6.06454 77.6368 0.388916 62.3391 0.388916C39.6442 0.388916 19.8039 12.7498 9.21289 31.1056L30.0247 43.1013C36.4944 31.9449 48.5404 24.4057 62.3391 24.4057Z" fill="#FF4B26"/>
<path d="M86.0584 32.9214C87.6511 34.2334 89.9661 34.1387 91.4248 32.6798L102.758 21.3467C104.413 19.6915 104.295 16.9821 102.527 15.4482C91.7106 6.0643 77.6372 0.388916 62.3394 0.388916V24.4057C71.3372 24.4057 79.6026 27.603 86.0584 32.9214Z" fill="#D93F21"/>
</g>
<defs>
<clipPath id="clip0">
<rect width="122.752" height="122.752" fill="white" transform="translate(0.963379 0.388794)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/></svg>

After

Width:  |  Height:  |  Size: 192 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z"/></svg>

After

Width:  |  Height:  |  Size: 213 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M21.41 11.58l-9-9C12.05 2.22 11.55 2 11 2H4c-1.1 0-2 .9-2 2v7c0 .55.22 1.05.59 1.42l9 9c.36.36.86.58 1.41.58s1.05-.22 1.41-.59l7-7c.37-.36.59-.86.59-1.41s-.23-1.06-.59-1.42zM13 20.01L4 11V4h7v-.01l9 9-7 7.02z"/><circle cx="6.5" cy="6.5" r="1.5"/></svg>

After

Width:  |  Height:  |  Size: 402 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2z"/></svg>

After

Width:  |  Height:  |  Size: 382 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/></svg>

After

Width:  |  Height:  |  Size: 266 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M12 6c1.1 0 2 .9 2 2s-.9 2-2 2-2-.9-2-2 .9-2 2-2m0 10c2.7 0 5.8 1.29 6 2H6c.23-.72 3.31-2 6-2m0-12C9.79 4 8 5.79 8 8s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm0 10c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/></svg>

After

Width:  |  Height:  |  Size: 360 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81 1.66 0 3-1.34 3-3s-1.34-3-3-3-3 1.34-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9c-1.66 0-3 1.34-3 3s1.34 3 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.16c-.05.21-.08.43-.08.65 0 1.61 1.31 2.92 2.92 2.92 1.61 0 2.92-1.31 2.92-2.92s-1.31-2.92-2.92-2.92z"/></svg>

After

Width:  |  Height:  |  Size: 516 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M9 16h6v-6h4l-7-7-7 7h4zm-4 2h14v2H5z"/></svg>

After

Width:  |  Height:  |  Size: 194 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z"/></svg>

After

Width:  |  Height:  |  Size: 366 B

+72
View File
@@ -0,0 +1,72 @@
import { useNavigate, useLocation } from "react-router-dom";
import { ReactComponent as OfferIcon } from "../assets/svg/localOfferIcon.svg";
import { ReactComponent as ExploreIcon } from "../assets/svg/exploreIcon.svg";
import { ReactComponent as PersonIcon } from "../assets/svg/personOutlineIcon.svg";
function Navbar() {
const navigate = useNavigate();
const location = useLocation();
const pathMatchRoute = (route) => {
if (route === location.pathname) {
return true;
}
};
return (
<footer className="navbar">
<nav className="navbarNan">
<ul className="navbarListItems">
<li className="navbarListItems" onClick={() => navigate("/explore")}>
<ExploreIcon
fill={pathMatchRoute("/") ? "#2c2c2c" : "#8f8f8f"}
width="36px"
height="36px"
/>
<p
className={
pathMatchRoute("/")
? "navbarListItemNameActive"
: "navbarListItemName"
}
>
Explore
</p>
</li>
<li className="navbarListItems" onClick={() => navigate("/offers")}>
<OfferIcon
fill={pathMatchRoute("/offers") ? "#2c2c2c" : "#8f8f8f"}
width="36px"
height="36px"
/>
<p
className={
pathMatchRoute("/offers")
? "navbarListItemNameActive"
: "navbarListItemName"
}
>
Explore
</p>
</li>
<li className="navbarListItems" onClick={() => navigate("/profile")}>
<PersonIcon
fill={pathMatchRoute("/profile") ? "#2c2c2c" : "#8f8f8f"}
width="36px"
height="36px"
/>
<p
className={
pathMatchRoute("/profile")
? "navbarListItemNameActive"
: "navbarListItemName"
}
>
Explore
</p>
</li>
</ul>
</nav>
</footer>
);
};
export default Navbar
+15
View File
@@ -0,0 +1,15 @@
import { initializeApp } from "firebase/app";
import {getFirestore} from 'firebase/firestore'
// Your web app's Firebase configuration
const firebaseConfig = {
apiKey: "AIzaSyDkQS2GoBx-IR_BR4dD_4bPUNGaPyMQugI",
authDomain: "house-marketplace-app-7e89f.firebaseapp.com",
projectId: "house-marketplace-app-7e89f",
storageBucket: "house-marketplace-app-7e89f.appspot.com",
messagingSenderId: "66680163160",
appId: "1:66680163160:web:c1874be8bb6d9e273e732d"
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
export const db = getFirestore()
+818 -10
View File
@@ -1,13 +1,821 @@
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@200;300;400;500;600;700;800;900&display=swap');
* {
box-sizing: border-box;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
html::-webkit-scrollbar {
display: none;
}
body {
font-family: 'Montserrat', sans-serif;
background-color: #f2f4f8;
margin: 0;
box-sizing: border-box;
}
a {
text-decoration: none;
display: block;
color: #000000;
}
button {
outline: none;
border: none;
}
.input,
.passwordInput,
.emailInput,
.nameInput,
.textarea {
box-shadow: rgba(0, 0, 0, 0.11);
border: none;
background: #ffffff;
border-radius: 3rem;
height: 3rem;
width: 100%;
outline: none;
font-family: 'Montserrat', sans-serif;
padding: 0 3rem;
font-size: 1rem;
}
@media (min-width: 1100px) {
.input,
.passwordInput,
.emailInput,
.nameInput,
.textarea {
padding: 0 5rem;
}
}
.textarea {
padding: 1rem 1.5rem;
height: 300px;
border-radius: 1rem;
}
.primaryButton {
cursor: pointer;
background: #00cc66;
border-radius: 1rem;
padding: 0.85rem 2rem;
color: #ffffff;
font-weight: 600;
font-size: 1.25rem;
width: 80%;
margin: 0 auto;
display: flex;
align-items: center;
justify-content: center;
}
.removeIcon {
cursor: pointer;
position: absolute;
top: -3%;
right: -2%;
}
.editIcon {
cursor: pointer;
position: absolute;
top: -3.4%;
right: 20px;
}
.pageContainer,
.offers,
.profile,
.listingDetails,
.category,
.explore {
margin: 1rem;
}
@media (min-width: 1024px) {
.pageContainer,
.offers,
.profile,
.listingDetails,
.category,
.explore {
margin: 3rem;
}
}
.loadingSpinnerContainer {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: rgba(0, 0, 0, 0.5);
z-index: 5000;
display: flex;
justify-content: center;
align-items: center;
}
.loadingSpinner {
width: 64px;
height: 64px;
border: 8px solid;
border-color: #00cc66 transparent #00cc66 transparent;
border-radius: 50%;
animation: spin 1.2s linear infinite;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.pageHeader {
font-size: 2rem;
font-weight: 800;
}
.navbar {
position: fixed;
left: 0;
bottom: 0;
right: 0;
height: 85px;
background-color: #ffffff;
z-index: 1000;
display: flex;
justify-content: center;
align-items: center;
}
.navbarNav {
width: 100%;
margin-top: 0.75rem;
overflow-y: hidden;
}
.navbarListItems {
margin: 0;
padding: 0;
display: flex;
justify-content: space-evenly;
align-items: center;
}
.navbarListItem {
cursor: pointer;
display: flex;
flex-direction: column;
align-items: center;
}
.navbarListItemName,
.navbarListItemNameActive {
margin-top: 0.25rem;
font-size: 14px;
font-weight: 600;
color: #8f8f8f;
}
.navbarListItemNameActive {
color: #2c2c2c;
}
.nameInput {
margin-bottom: 2rem;
background: url('./assets/svg/badgeIcon.svg') #ffffff 2.5% center no-repeat;
}
.emailInput {
margin-bottom: 2rem;
background: url('./assets/svg/personIcon.svg') #ffffff 2.5% center no-repeat;
}
.passwordInputDiv {
position: relative;
}
.passwordInput {
margin-bottom: 2rem;
background: url('./assets/svg/lockIcon.svg') #ffffff 2.5% center no-repeat;
}
.showPassword {
cursor: pointer;
position: absolute;
top: -4%;
right: 1%;
padding: 1rem;
}
.forgotPasswordLink {
cursor: pointer;
color: #00cc66;
font-weight: 600;
text-align: right;
}
.signInBar,
.signUpBar {
margin-top: 3rem;
display: flex;
justify-content: space-between;
align-items: center;
position: inherit;
}
.signInButton,
.signUpButton,
.signInText,
.signUpText {
cursor: pointer;
}
@media (min-width: 1024px) {
.signInBar,
.signUpBar {
justify-content: start;
}
}
.signInText,
.signUpText {
font-size: 1.5rem;
font-weight: 700;
}
.signInButton,
.signUpButton {
display: flex;
justify-content: center;
align-items: center;
width: 3rem;
height: 3rem;
background-color: #00cc66;
border-radius: 50%;
}
@media (min-width: 1024px) {
.signInButton,
.signUpButton {
margin-left: 3rem;
}
}
.socialLogin {
margin-top: 4rem;
display: flex;
flex-direction: column;
align-items: center;
}
.socialIconDiv {
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
padding: 0.75rem;
margin: 1.5rem;
width: 3rem;
height: 3rem;
background-color: #ffffff;
border-radius: 50%;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.1);
}
.socialIconImg {
width: 100%;
}
.registerLink {
margin-top: 4rem;
color: #00cc66;
font-weight: 600;
text-align: center;
margin-bottom: 3rem;
}
@media (min-width: 1217px) {
.explore {
margin-bottom: 10rem;
}
}
@media (max-height: 536) {
.explore {
margin-bottom: 10rem;
}
}
.exploreHeading,
.exploreCategoryHeading {
font-weight: 700;
}
.exploreCategoryHeading {
margin-top: 3rem;
}
.swiper-container {
min-height: 225px;
height: 23vw;
}
.swiper-pagination-bullet-active {
background-color: #ffffff !important;
}
.swiperSlideDiv {
position: relative;
width: 100%;
height: 100%;
}
.swiperSlideImg {
width: 100%;
object-fit: cover;
}
.swiperSlideText {
color: #ffffff;
position: absolute;
top: 70px;
left: 0;
font-weight: 600;
max-width: 90%;
font-size: 1.25rem;
background-color: rgba(0, 0, 0, 0.8);
padding: 0.5rem;
}
@media (min-width: 1024px) {
.swiperSlideText {
font-size: 1.75rem;
}
}
.swiperSlidePrice {
color: #000000;
position: absolute;
top: 143px;
left: 11px;
font-weight: 600;
max-width: 90%;
background-color: #ffffff;
padding: 0.25rem 0.5rem;
border-radius: 1rem;
}
@media (min-width: 1024px) {
.swiperSlidePrice {
font-size: 1.25rem;
}
}
.exploreCategories {
display: flex;
justify-content: space-between;
}
.exploreCategories a {
width: 48%;
}
.exploreCategoryImg {
min-height: 115px;
height: 15vw;
width: 100%;
border-radius: 1.5rem;
object-fit: cover;
margin: 0 auto;
}
.exploreCategoryName {
font-weight: 500;
text-align: left;
}
.category {
margin-bottom: 10rem;
}
.categoryListings {
padding: 0;
}
.categoryListing {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 1rem;
position: relative;
}
.categoryListingLink {
display: contents;
}
.categoryListingImg {
width: 30%;
height: 100px;
border-radius: 1.5rem;
object-fit: cover;
}
@media (min-width: 1024px) {
.categoryListingImg {
width: 19%;
height: 217px;
}
}
.categoryListingDetails {
width: 65%;
}
@media (min-width: 1024px) {
.categoryListingDetails {
width: 79%;
}
}
.categoryListingLocation {
font-weight: 600;
font-size: 0.7rem;
opacity: 0.8;
margin-bottom: 0;
}
.categoryListingName {
font-weight: 600;
font-size: 1.25rem;
margin: 0;
}
.categoryListingPrice {
margin-top: 0.5rem;
font-weight: 600;
font-size: 1.1rem;
color: #00cc66;
margin-bottom: 0;
display: flex;
align-items: center;
}
.categoryListingInfoDiv {
display: flex;
justify-content: space-between;
max-width: 275px;
}
.categoryListingInfoText {
font-weight: 500;
font-size: 0.7rem;
}
.loadMore {
cursor: pointer;
width: 8rem;
margin: 0 auto;
text-align: center;
padding: 0.25rem 0.5rem;
background-color: #000000;
color: #ffffff;
font-weight: 600;
border-radius: 1rem;
opacity: 0.7;
margin-top: 2rem;
}
.listingDetails {
margin-bottom: 10rem;
}
.shareIconDiv {
cursor: pointer;
position: fixed;
top: 3%;
right: 5%;
z-index: 2;
background-color: #ffffff;
border-radius: 50%;
width: 3rem;
height: 3rem;
display: flex;
justify-content: center;
align-items: center;
}
.listingName {
font-weight: 600;
font-size: 1.5rem;
margin-bottom: 0.5rem;
}
.listingLocation {
margin-top: 0;
font-weight: 600;
}
.discountPrice {
padding: 0.25rem 0.5rem;
background-color: #000000;
color: #ffffff;
border-radius: 1rem;
font-size: 0.8rem;
font-weight: 600;
display: inline;
}
.listingType {
padding: 0.25rem 0.5rem;
background-color: #00cc66;
color: #ffffff;
border-radius: 2rem;
display: inline;
font-weight: 600;
font-size: 0.8rem;
margin-right: 1rem;
}
.listingDetailsList {
padding: 0;
list-style-type: none;
}
.listingDetailsList li {
margin: 0.3rem 0;
font-weight: 500;
opacity: 0.8;
}
.listingLocationTitle {
margin-top: 2rem;
font-weight: 600;
font-size: 1.25rem;
}
.leafletContainer {
width: 100%;
height: 200px;
overflow-x: hidden;
margin-bottom: 3rem;
}
@media (min-width: 1024px) {
.leafletContainer {
height: 400px;
}
}
.linkCopied {
position: fixed;
top: 9%;
right: 5%;
z-index: 2;
background-color: #ffffff;
border-radius: 1rem;
padding: 0.5rem 1rem;
font-weight: 600;
}
.contactListingName {
margin-top: -1rem;
margin-bottom: 0;
font-weight: 600;
}
.contactListingLocation {
margin-top: 0.25rem;
font-weight: 600;
}
.contactLandlord {
margin-top: 2rem;
display: flex;
align-items: center;
}
.landlordName {
font-weight: 600;
font-size: 1.2rem;
}
.messageForm {
margin-top: 0.5rem;
}
.messageDiv {
margin-top: 2rem;
display: flex;
flex-direction: column;
margin-bottom: 4rem;
}
.messageLabel {
margin-bottom: 0.5rem;
}
.profile {
margin-bottom: 10rem;
}
.profileHeader {
display: flex;
justify-content: space-between;
align-items: center;
}
.logOut {
cursor: pointer;
font-family: 'Montserrat', sans-serif;
font-size: 1rem;
font-weight: 600;
color: #ffffff;
background-color: #00cc66;
padding: 0.25rem 0.75rem;
border-radius: 1rem;
}
.profileDetailsHeader {
display: flex;
justify-content: space-between;
max-width: 500px;
}
.personalDetailsText {
font-weight: 600;
}
.changePersonalDetails {
cursor: pointer;
font-weight: 600;
color: #00cc66;
}
.profileCard {
background-color: #ffffff;
border-radius: 1rem;
padding: 1rem;
box-shadow: rgba(0, 0, 0, 0.2);
max-width: 500px;
}
.profileDetails {
display: flex;
flex-direction: column;
}
.profileName,
.profileEmail,
.profileAddress,
.profileAddressActive,
.profileEmailActive,
.profileNameActive {
all: unset;
margin: 0.3rem 0;
font-weight: 600;
width: 100%;
}
.profileNameActive {
background-color: rgba(44, 44, 44, 0.1);
}
.profileEmail,
.profileAddress,
.profileAddressActive,
.profileEmailActive {
font-weight: 500;
}
.profileEmailActive {
background-color: rgba(44, 44, 44, 0.1);
}
.profileAddressActive {
background-color: rgba(44, 44, 44, 0.1);
}
.createListing {
background-color: #ffffff;
border-radius: 1rem;
padding: 0.25rem 1rem;
box-shadow: rgba(0, 0, 0, 0.2);
margin-top: 2rem;
font-weight: 600;
max-width: 500px;
display: flex;
justify-content: space-between;
align-items: center;
}
.listingText {
margin-top: 3rem;
font-weight: 600;
}
.lisitingsList {
padding: 0;
}
.formLabel {
font-weight: 600;
margin-top: 1rem;
display: block;
}
.formButtons {
display: flex;
}
.formButton,
.formInput,
.formInputAddress,
.formInputName,
.formInputSmall,
.formInputFile,
.formButtonActive {
padding: 0.9rem 3rem;
background-color: #ffffff;
font-weight: 600;
border-radius: 1rem;
font-size: 1rem;
margin: 0.5rem 0.5rem 0 0;
display: flex;
justify-content: center;
align-items: center;
}
.formButtonActive {
background-color: #00cc66;
color: #ffffff;
}
.flex {
display: flex;
}
.formInput,
.formInputAddress,
.formInputName,
.formInputSmall,
.formInputFile {
border: none;
outline: none;
font-family: 'Montserrat', sans-serif;
}
.formInputSmall,
.formInputFile {
margin-right: 3rem;
padding: 0.9rem 0.7rem;
text-align: center;
}
.formInputName {
padding: 0.9rem 1rem;
width: 90%;
max-width: 326px;
}
.formInputAddress {
padding: 0.9rem 1rem;
width: 90%;
max-width: 326px;
}
.formPriceDiv {
display: flex;
align-items: center;
}
.formPriceText {
margin-left: -1.5rem;
font-weight: 600;
}
.imagesInfo {
font-size: 0.9rem;
opacity: 0.75;
}
.formInputFile {
width: 100%;
}
.formInputFile::-webkit-file-upload-button {
background-color: #00cc66;
border: none;
color: #ffffff;
font-weight: 600;
padding: 0.5rem 0.75rem;
border-radius: 1rem;
margin-right: 1rem;
}
.createListingButton {
margin-top: 5rem;
}
.offers {
margin-bottom: 10rem;
}
.offerBadge {
padding: 0.25rem 0.5rem;
background-color: #000000;
color: #ffffff;
border-radius: 1rem;
margin-left: 1rem;
font-size: 0.8rem;
opacity: 0.75;
}
-5
View File
@@ -2,7 +2,6 @@ import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
@@ -11,7 +10,3 @@ root.render(
</React.StrictMode>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
-1
View File
@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3"><g fill="#61DAFB"><path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/><circle cx="420.9" cy="296.5" r="45.7"/><path d="M520.5 78.1z"/></g></svg>

Before

Width:  |  Height:  |  Size: 2.6 KiB

+10
View File
@@ -0,0 +1,10 @@
function Explore (){
return (
<>
<h1>My app</h1>
</>
);
}
export default Explore
+9
View File
@@ -0,0 +1,9 @@
function ForgotPassword (){
return (
<>
<h1>My app</h1>
</>
);
}
export default ForgotPassword
+9
View File
@@ -0,0 +1,9 @@
function Offers (){
return (
<>
<h1>My app</h1>
</>
);
}
export default Offers
+9
View File
@@ -0,0 +1,9 @@
function Profile (){
return (
<>
<h1>My app</h1>
</>
);
}
export default Profile
+82
View File
@@ -0,0 +1,82 @@
import { useState } from "react";
import { Link, useNavigate } from "react-router-dom";
import { ReactComponent as ArrowRightIcon } from "../assets/svg/keyboardArrowRightIcon.svg";
import visibilityIcon from "../assets/svg/visibilityIcon.svg";
import { getAuth, signInWithEmailAndPassword } from "firebase/auth";
function Signin() {
const [showPassword, setShowPassword] = useState(false);
const [formData, setFormData] = useState({ email: "", password: "" });
const { email, password } = formData;
const navigate = useNavigate();
const onChange = (e) => {
setFormData((prevState) => ({
...prevState,
[e.target.id]: e.target.value,
}));
};
const onSubmit = async (e) => {
e.preventDefault();
const auth = getAuth();
try {
const userCredential = await signInWithEmailAndPassword(
auth,
email,
password
);
if (userCredential.user) {
navigate("/");
}
} catch (error) {
console.log(error);
}
};
return (
<>
<div className="pageContainer">
<header>
<p className="pageHeader">Welcome Back!</p>
</header>
<form onSubmit={onSubmit}>
<input
className="emailInput"
type="email"
placeholder="Email"
id="email"
value={email}
onChange={onChange}
/>
<div className="passwordInputDiv">
<input
type={showPassword ? "text" : "password"}
className="passwordInput"
placeholder="Password"
id="password"
value={password}
onChange={onChange}
/>
<img
className="showPassword"
src={visibilityIcon}
onClick={() => setShowPassword((prevState) => !prevState)}
/>
</div>
<Link to="/forgot-password" className="forgotPasswordLink">
Forgot Password
</Link>
<div className="signInBar">
<p className="sigInText">Sign In</p>
<button className="signInButton">
<ArrowRightIcon fill="#ffffff" width="34px" height="34px" />
</button>
</div>
</form>
<Link to="/sign-up" className="registerLink">
Sign Up Instead
</Link>
</div>
</>
);
}
export default Signin;
+108
View File
@@ -0,0 +1,108 @@
import { useState } from "react";
import { Link, useNavigate } from "react-router-dom";
import { ReactComponent as ArrowRightIcon } from "../assets/svg/keyboardArrowRightIcon.svg";
import visibilityIcon from "../assets/svg/visibilityIcon.svg";
import {
getAuth,
createUserWithEmailAndPassword,
updateProfile,
} from "firebase/auth";
import { db } from "../firebase.config";
import { setDoc,doc, serverTimestamp } from "firebase/firestore";
function Signup() {
const [showPassword, setShowPassword] = useState(false);
const [formData, setFormData] = useState({
name: "",
email: "",
password: "",
});
const { name, email, password } = formData;
const navigate = useNavigate();
const onChange = (e) => {
setFormData((prevState) => ({
...prevState,
[e.target.id]: e.target.value,
}));
};
const onSubmit = async (e) => {
e.preventDefault();
try {
const auth = getAuth();
const userCredential = await createUserWithEmailAndPassword(
auth,
email,
password
);
const user = userCredential.user;
updateProfile(auth.currentUser, { displayName: name });
const fromDataCopy = { ...formData };
delete fromDataCopy.password;
fromDataCopy.timestamp = serverTimestamp();
await setDoc(doc(db,'users',user.uid), fromDataCopy)
navigate("/");
} catch (error) {
console.log(error);
}
};
return (
<>
<div className="pageContainer">
<header>
<p className="pageHeader">Welcome Back!</p>
</header>
<form onSubmit={onSubmit}>
<input
className="nameInput"
type="text"
placeholder="Name"
id="name"
value={name}
onChange={onChange}
/>
<input
className="emailInput"
type="email"
placeholder="Email"
id="email"
value={email}
onChange={onChange}
/>
<div className="passwordInputDiv">
<input
type={showPassword ? "text" : "password"}
className="passwordInput"
placeholder="Password"
id="password"
value={password}
onChange={onChange}
/>
<img
className="showPassword"
src={visibilityIcon}
onClick={() => setShowPassword((prevState) => !prevState)}
/>
</div>
<Link to="/forgot-password" className="forgotPasswordLink">
Forgot Password
</Link>
<div className="signUpBar">
<p className="sigUpText">Sign In</p>
<button className="signUpButton">
<ArrowRightIcon fill="#ffffff" width="34px" height="34px" />
</button>
</div>
</form>
<Link to="/sign-in" className="registerLink">
Sign In Instead
</Link>
</div>
</>
);
}
export default Signup;
-13
View File
@@ -1,13 +0,0 @@
const reportWebVitals = onPerfEntry => {
if (onPerfEntry && onPerfEntry instanceof Function) {
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
getCLS(onPerfEntry);
getFID(onPerfEntry);
getFCP(onPerfEntry);
getLCP(onPerfEntry);
getTTFB(onPerfEntry);
});
}
};
export default reportWebVitals;
-5
View File
@@ -1,5 +0,0 @@
// jest-dom adds custom jest matchers for asserting on DOM nodes.
// allows you to do things like:
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom';