working before adding toastify
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 96 KiB |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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
|
||||
@@ -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()
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 +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 |
@@ -0,0 +1,10 @@
|
||||
|
||||
function Explore (){
|
||||
return (
|
||||
<>
|
||||
<h1>My app</h1>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default Explore
|
||||
@@ -0,0 +1,9 @@
|
||||
|
||||
function ForgotPassword (){
|
||||
return (
|
||||
<>
|
||||
<h1>My app</h1>
|
||||
</>
|
||||
);
|
||||
}
|
||||
export default ForgotPassword
|
||||
@@ -0,0 +1,9 @@
|
||||
|
||||
function Offers (){
|
||||
return (
|
||||
<>
|
||||
<h1>My app</h1>
|
||||
</>
|
||||
);
|
||||
}
|
||||
export default Offers
|
||||
@@ -0,0 +1,9 @@
|
||||
|
||||
function Profile (){
|
||||
return (
|
||||
<>
|
||||
<h1>My app</h1>
|
||||
</>
|
||||
);
|
||||
}
|
||||
export default Profile
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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';
|
||||