added option for geolocation, that requires an api and currently does not work, and completed the add listing functionality

This commit is contained in:
QkoSad
2022-12-02 18:33:38 +02:00
parent 5c96af8b6c
commit d79737a497
4 changed files with 137 additions and 23 deletions
+22 -6
View File
@@ -17,6 +17,7 @@
"react-router-dom": "^6.4.3", "react-router-dom": "^6.4.3",
"react-scripts": "5.0.1", "react-scripts": "5.0.1",
"react-toastify": "^9.1.1", "react-toastify": "^9.1.1",
"uuid": "^9.0.0",
"web-vitals": "^2.1.4" "web-vitals": "^2.1.4"
} }
}, },
@@ -15913,6 +15914,14 @@
"websocket-driver": "^0.7.4" "websocket-driver": "^0.7.4"
} }
}, },
"node_modules/sockjs/node_modules/uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
"bin": {
"uuid": "dist/bin/uuid"
}
},
"node_modules/source-list-map": { "node_modules/source-list-map": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
@@ -16928,9 +16937,9 @@
} }
}, },
"node_modules/uuid": { "node_modules/uuid": {
"version": "8.3.2", "version": "9.0.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==",
"bin": { "bin": {
"uuid": "dist/bin/uuid" "uuid": "dist/bin/uuid"
} }
@@ -29240,6 +29249,13 @@
"faye-websocket": "^0.11.3", "faye-websocket": "^0.11.3",
"uuid": "^8.3.2", "uuid": "^8.3.2",
"websocket-driver": "^0.7.4" "websocket-driver": "^0.7.4"
},
"dependencies": {
"uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
}
} }
}, },
"source-list-map": { "source-list-map": {
@@ -29995,9 +30011,9 @@
"integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA=="
}, },
"uuid": { "uuid": {
"version": "8.3.2", "version": "9.0.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg=="
}, },
"v8-to-istanbul": { "v8-to-istanbul": {
"version": "8.1.1", "version": "8.1.1",
+1
View File
@@ -12,6 +12,7 @@
"react-router-dom": "^6.4.3", "react-router-dom": "^6.4.3",
"react-scripts": "5.0.1", "react-scripts": "5.0.1",
"react-toastify": "^9.1.1", "react-toastify": "^9.1.1",
"uuid": "^9.0.0",
"web-vitals": "^2.1.4" "web-vitals": "^2.1.4"
}, },
"scripts": { "scripts": {
+114 -15
View File
@@ -1,10 +1,20 @@
import { useState, useRef, useEffect } from "react"; import { useState, useRef, useEffect } from "react";
import { getAuth, onAuthStateChanged } from "firebase/auth"; import { getAuth, onAuthStateChanged } from "firebase/auth";
import {
getStorage,
ref,
uploadBytesResumable,
getDownloadURL,
} from "firebase/storage";
import { db } from "../firebase.config";
import { addDoc, collection, serverTimestamp } from "firebase/firestore";
import { v4 as uuidv4 } from "uuid";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import Spinner from "../components/Spinner"; import Spinner from "../components/Spinner";
import { toast } from "react-toastify";
function CreateLising() { function CreateLising() {
const [geolocationEnabled, setGeolocationEnabled] = useState(true); const [geolocationEnabled, setGeolocationEnabled] = useState(false);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [formData, setFormData] = useState({ const [formData, setFormData] = useState({
type: "rent", type: "rent",
@@ -56,8 +66,96 @@ function CreateLising() {
}; };
}, [isMounted]); }, [isMounted]);
const onSubmit = (e) => { const onSubmit = async (e) => {
e.prevent.default(); e.preventDefault();
setLoading(false);
if (discountedPrice >= regularPrice) {
setLoading(false);
toast.error("Discounted price needs to be less than regular price");
return;
}
if (images.length > 6) {
setLoading(false);
toast.error("Max 6 images");
return;
}
let geolocation = {};
let location;
if (geolocationEnabled) {
//Don't want to register for a geolocation
/* const response = await fetch(
`http://api.positionstack.com/v1/forward?access_key=${APIKEY}&query=${address}`
);
const data = await response.json();
setFormData((prevState) => ({
...prevState,
latitude: data.data[0].latitude,
longitude: data.data[0].longitude,
}));
*/
} else {
geolocation.lat = latittude;
geolocation.lng = longitude;
location = address;
}
const storeImage = async (image) => {
return new Promise((resolve, reject) => {
const storage = getStorage();
const fileName = `${auth.currentUser.uid}-${image.name}-${uuidv4()}`;
const storageRef = ref(storage, "images/" + fileName);
const uploadTask = uploadBytesResumable(storageRef, image);
uploadTask.on(
"state_changed",
(snapshot) => {
const progress =
(snapshot.bytesTransferred / snapshot.totalBytes) * 100;
console.log("Upload is " + progress + "% done");
switch (snapshot.state) {
case "paused":
console.log("Upload is paused");
break;
case "running":
console.log("Upload is running");
break;
}
},
(error) => {
reject(error);
},
() => {
getDownloadURL(uploadTask.snapshot.ref).then((downloadURL) => {
resolve(downloadURL);
});
}
);
});
};
const imgUrls = await Promise.all(
[...images].map((image) => storeImage(image))
).catch(() => {
setLoading(false);
toast.error("Image is not uploaded");
return;
});
const formDataCopy = {
...formData,
imgUrls,
geolocation,
timestamp: serverTimestamp(),
};
formDataCopy.location=address
delete formDataCopy.images;
delete formDataCopy.address;
location && (formDataCopy.location = location);
!formDataCopy.offer && delete formDataCopy.discountedPrice;
const docRef = await addDoc(collection(db, "listings"), formDataCopy);
setLoading(false);
toast.success("Listing saved");
navigate(`/category/${formDataCopy.type}/${docRef.id}`);
}; };
const onMutate = (e) => { const onMutate = (e) => {
@@ -72,7 +170,7 @@ function CreateLising() {
if (e.target.files) { if (e.target.files) {
setFormData((prevState) => ({ setFormData((prevState) => ({
...prevState, ...prevState,
image: e.target.files, images: e.target.files,
})); }));
} }
if (!e.target.files) { if (!e.target.files) {
@@ -114,7 +212,7 @@ function CreateLising() {
Rent Rent
</button> </button>
</div> </div>
<label className="formLabel">Sell / Rent</label> <label className="formLabel">Name</label>
<input <input
className="formInputName" className="formInputName"
type="text" type="text"
@@ -204,6 +302,7 @@ function CreateLising() {
No No
</button> </button>
</div> </div>
<label className="formLabel">Address</label>
<textarea <textarea
className="formInputAddress" className="formInputAddress"
type="text" type="text"
@@ -238,12 +337,12 @@ function CreateLising() {
</div> </div>
</div> </div>
)} )}
<label className='formLabel'>Offer</label> <label className="formLabel">Offer</label>
<div className='formButtons'> <div className="formButtons">
<button <button
className={offer ? 'formButtonActive' : 'formButton'} className={offer ? "formButtonActive" : "formButton"}
type='button' type="button"
id='offer' id="offer"
value={true} value={true}
onClick={onMutate} onClick={onMutate}
> >
@@ -251,10 +350,10 @@ function CreateLising() {
</button> </button>
<button <button
className={ className={
!offer && offer !== null ? 'formButtonActive' : 'formButton' !offer && offer !== null ? "formButtonActive" : "formButton"
} }
type='button' type="button"
id='offer' id="offer"
value={false} value={false}
onClick={onMutate} onClick={onMutate}
> >
@@ -292,14 +391,14 @@ function CreateLising() {
/> />
</> </>
)} )}
<label className="formLabel">Discounted Price</label> <label className="formLabel">Images</label>
<p className="imagesInfo"> <p className="imagesInfo">
The first image will be the cover (max 6). The first image will be the cover (max 6).
</p> </p>
<input <input
className="formInputFile" className="formInputFile"
type="file" type="file"
id="image" id="images"
onChange={onMutate} onChange={onMutate}
max="6" max="6"
accept=".jpg,.png,.jpeg" accept=".jpg,.png,.jpeg"
-2
View File
@@ -12,8 +12,6 @@ import {
import { db } from "../firebase.config"; import { db } from "../firebase.config";
import { toast } from "react-toastify"; import { toast } from "react-toastify";
import Spinner from "../components/Spinner"; import Spinner from "../components/Spinner";
import { async } from "@firebase/util";
import Listing from "../components/ListingItem";
import ListingItem from "../components/ListingItem"; import ListingItem from "../components/ListingItem";
function Offers() { function Offers() {