diff --git a/firestore.rules b/firestore.rules index 8cd98aa..b1d4263 100644 --- a/firestore.rules +++ b/firestore.rules @@ -9,6 +9,9 @@ service cloud.firestore { return request.auth.uid != null && request.resource.data.owner.uid == request.auth.uid; } + function canDelete(){ + return request.auth.uid != null && resource.data.owner.uid == request.auth.uid; + } //TODO: TEST AND IMPLEMENT function canReadIfPublicOrOwnListing(){ @@ -21,6 +24,7 @@ service cloud.firestore { allow read: if true; // Only the authenticated user who authored the document can write allow write: if canWriteAndUpdate(); + allow delete: if canDelete(); } match /users/{userId} { allow read: if true; diff --git a/package.json b/package.json index 6b23f51..7d97cd2 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,8 @@ "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject", - "deploy": "react-scripts build && git add . && git commit -m\"create production build\" && firebase deploy" + "deploy": "react-scripts build && git add . && git commit -m\"create production build\" && firebase deploy", + "fb-rules": "firebase deploy --only firestore:rules" }, "eslintConfig": { "extends": "react-app" diff --git a/src/components/Button.jsx b/src/components/Button.jsx index 5994d47..4386e8d 100644 --- a/src/components/Button.jsx +++ b/src/components/Button.jsx @@ -10,14 +10,14 @@ const useStyles = makeStyles(theme => ({ } })) -export default function ThemeButton({children, ...props}){ +export default function ThemeButton({children, color, ...props}){ const classes = useStyles(); return ( + + + )} + {mainContent === "LOADING" && !res.message.type && ( +
+ +

Deleting your listing...

+
+ )} + {res.message.type && ( +
+ + {res.message.content} You'll be redirected to your profile in a + moment. + +
+ )} + + + + ); +} diff --git a/src/components/LogInModal.jsx b/src/components/LogInModal.jsx index f681deb..9d18329 100644 --- a/src/components/LogInModal.jsx +++ b/src/components/LogInModal.jsx @@ -28,7 +28,7 @@ const useStyles = makeStyles((theme) => ({ }, })); -export default function MyModal() { +export default function LoginModal() { const classes = useStyles(); const [open, setOpen] = React.useState(false); diff --git a/src/components/UpdateListingForm.jsx b/src/components/UpdateListingForm.jsx index a381df0..e7de6d5 100644 --- a/src/components/UpdateListingForm.jsx +++ b/src/components/UpdateListingForm.jsx @@ -15,7 +15,7 @@ import { } from "@material-ui/core"; import WifiIcon from "@material-ui/icons/Wifi"; import format from "date-fns/format"; -import { Redirect, useParams } from "react-router-dom"; +import { useParams, useHistory, Redirect } from "react-router-dom"; import Snackbar from "./Snackbar"; import Checkbox from "./Checkbox"; import DateSelector from "./DateSelector"; @@ -32,6 +32,7 @@ import getListing from '../queries/listings/getListingById'; import fBdateToHtmlString from '../utils/dateFbToHTML'; import context from './Context'; import updateListingToDb from '../queries/listings/updateListing'; +import DeleteListingModal from "./DeleteListingModal"; const useStyles = makeStyles((theme) => ({ titleLogoWrapper: { @@ -121,6 +122,7 @@ const oneToTenOptions = [ export default function CreateListing() { const classes = useStyles(); const {id} = useParams(); + const history = useHistory(); const {user: {uid}} = useContext(context); const [snackbar, setSnackbar] = useState({ @@ -152,7 +154,7 @@ export default function CreateListing() { const [additional_imgs, setAdditionalImages] = useState(null); const [disableSubmit, setDisableSubmit] = useState(false); const [resMsg, setResMsg] = useState(null); - const [redirect, setRedirect] = useState(null); + const [listing, setListing] = useState({}); useEffect( ()=>{ (async () => { @@ -160,7 +162,8 @@ export default function CreateListing() { const listing = await getListing(id); if (listing.owner.uid !== uid) { - setRedirect(`/listings/${listing.id}`); + // setRedirect(`/listings/${listing.id}`); + history.push(`/listings/${listing.id}`); return; } const {title, type, description, active, price, start_date, end_date, location, @@ -168,6 +171,7 @@ export default function CreateListing() { max_guests, wifi_speed, rules, pets, lgbtq, living_with_host, primary_img, additional_imgs, payment_methods, } = listing; + setListing(listing) setTitle(title); setDisableSubmit(id) setType(type); @@ -246,14 +250,14 @@ export default function CreateListing() { return ( <> - <> + {/* <> {redirect && (
{" "} {" "}
)} - + */} <> {resMsg && resMsg.message.type === "success" && (
@@ -694,6 +698,7 @@ export default function CreateListing() { Update Listing!
+ {listing.title && } )} diff --git a/src/queries/listings/deleteListing.js b/src/queries/listings/deleteListing.js new file mode 100644 index 0000000..a0a54d8 --- /dev/null +++ b/src/queries/listings/deleteListing.js @@ -0,0 +1,29 @@ +import db from "../../config/firestoreDb"; +import firebase from "firebase"; +import geoListings from "../../config/geofirestore"; + +export default async function deleteListing(listingId, setRes){ + + const unsubscribe = firebase.auth().onAuthStateChanged(async function (user) { + if(user){ + try{ + const res = await geoListings.doc(listingId).delete(); + setRes({ + message: { + type: "success", + content: "Your listing was successfully deleted.", + }, + }); + } catch(err){ + console.error('POSTING PROBLEM::', err); + setRes({ + message: { + type: "error", + content: "There was a problem deleting your listing. Please try again later", + }, + }); + } + unsubscribe(); + } + }) +} \ No newline at end of file diff --git a/src/queries/listings/postListing.js b/src/queries/listings/postListing.js index aec73ed..8af034a 100644 --- a/src/queries/listings/postListing.js +++ b/src/queries/listings/postListing.js @@ -10,7 +10,7 @@ export default async function postListing(listing, setRes){ additional_imgs, payment_methods, } = listing; if(!title || !location || !type || !start_date - || !bedrooms || !bathrooms || !max_guests || !primary_img){ + || !bedrooms || !bathrooms || !max_guests || !primary_img || price < 1){ setRes({ "message":{ type: "error",