Skip to content

Commit

Permalink
add delete listing functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
bpmutter committed Aug 12, 2020
1 parent 1f0ac6a commit 3adbaba
Show file tree
Hide file tree
Showing 9 changed files with 179 additions and 11 deletions.
4 changes: 4 additions & 0 deletions firestore.rules
Original file line number Diff line number Diff line change
Expand Up @@ -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(){
Expand All @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
4 changes: 2 additions & 2 deletions src/components/Button.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
<Button
{...props}
className={classes.button}
variant="contained"
color="primary"
color={color || "primary"}
component="div"
>
{children}
Expand Down
3 changes: 2 additions & 1 deletion src/components/CreateListing.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ export default function CreateListing(){
setLivingWithHost(false);
setRoommates("");
}
const priceInt = parseInt(price.value)
const priceInt = parseInt(price.value);
const bathroomsInt = parseInt(bathrooms);
const bedroomsInt = parseInt(bedrooms);
const maxGuestsInt = parseInt(max_guests);
Expand Down Expand Up @@ -253,6 +253,7 @@ export default function CreateListing(){
defaultValue={price.value}
onChange={price.onChange}
InputProps={{
inputProps: { min: 1},
startAdornment: (
<InputAdornment position="start">$</InputAdornment>
),
Expand Down
128 changes: 128 additions & 0 deletions src/components/DeleteListingModal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import React, {useState, useEffect} from "react";
import { useHistory } from 'react-router-dom';
import { makeStyles, Link, Typography, CircularProgress, Button as MuiButton} from "@material-ui/core";
import Button from './Button';
import Modal from "@material-ui/core/Modal";
import DeleteIcon from "@material-ui/icons/Delete";
import red from "@material-ui/core/colors/red";
import CloseIcon from "@material-ui/icons/Close";
import deleteListing from '../queries/listings/deleteListing';
const useStyles = makeStyles((theme) => ({
modalContent: {
position: "absolute",
width: 400,
backgroundColor: theme.palette.background.paper,
border: "2px solid #000",
boxShadow: theme.shadows[5],
padding: theme.spacing(2, 4, 3),
top: `50%`,
left: `50%`,
transform: `translate(-50%, -50%)`,
outlineColor: theme.palette.secondary.light,
},
buttonWrapper: {
display: 'flex',
justifyContent: 'center',
marginTop: theme.spacing(1.5),
marginBottom: theme.spacing(1.5),
},
deleteButton: {
marginRight: theme.spacing(2),
fontFamily: theme.typography.special,
color: red[500],
cursor: "pointer",
display: 'inline-flex',
alignItems: 'center',
},
title: {
fontFamily: theme.typography.special,
color: theme.palette.primary.dark,
marginBottom: theme.spacing(2)
},
progress: {
display: 'flex',
justifyContent: 'center',
}
}));

export default function DeleteListingModal({listing}) {
const classes = useStyles();
const history = useHistory();
const [open, setOpen] = useState(false);
const [res, setRes] = useState({message: {}})
const [mainContent, setMainContent] = useState("START")


const handleOpen = () => {
setOpen(true);
};

const handleClose = () => {
setOpen(false);
};

const handleDelete = async () => {

await deleteListing(listing.id, setRes);
setTimeout(()=>{
history.push('/profile');
}, 3000)
}

useEffect(()=>{
if(res.message.type === "success"){

}
},[res.message])



return (
<>
<MuiButton className={classes.deleteButton} onClick={handleOpen}>
<DeleteIcon />{" "}Delete Listing
</MuiButton>
<Modal
open={open}
onClose={handleClose}
aria-labelledby="aCasa log in"
aria-describedby="log into your aCasa account here"
disableAutoFocus={true}
>
<div className={classes.modalContent}>
<div>
<CloseIcon onClick={handleClose} />
</div>
<Typography component="h4" variant="h4" align="center" className={classes.title} color="primary">
Delete Listing
</Typography>
{mainContent === "START" && !res.message.type && (
<div>
<Typography>
<b>Warning:</b> Deletion of listings is permanent, and once you
click delete below, you won't be able to recover the listing.
</Typography>
<div className={classes.buttonWrapper}>
<Button onClick={handleDelete}>Delete</Button>
</div>
</div>
)}
{mainContent === "LOADING" && !res.message.type && (
<div className={classes.progress}>
<CircularProgress size={100} />
<p>Deleting your listing...</p>
</div>
)}
{res.message.type && (
<div>
<Typography>
{res.message.content} You'll be redirected to your profile in a
moment.
</Typography>
</div>
)}
</div>
</Modal>
</>
);
}
2 changes: 1 addition & 1 deletion src/components/LogInModal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
15 changes: 10 additions & 5 deletions src/components/UpdateListingForm.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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: {
Expand Down Expand Up @@ -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({
Expand Down Expand Up @@ -152,22 +154,24 @@ 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 () => {
if(uid){
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,
location_description, shared, roommates, bedrooms, bathrooms,
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);
Expand Down Expand Up @@ -246,14 +250,14 @@ export default function CreateListing() {

return (
<>
<>
{/* <>
{redirect && (
<div>
{" "}
<Redirect to={redirect} />{" "}
</div>
)}
</>
</> */}
<>
{resMsg && resMsg.message.type === "success" && (
<div>
Expand Down Expand Up @@ -694,6 +698,7 @@ export default function CreateListing() {
Update Listing!
</Button>
</div>
{listing.title && <DeleteListingModal listing={listing} />}
</form>
)}
</ContentPaper>
Expand Down
29 changes: 29 additions & 0 deletions src/queries/listings/deleteListing.js
Original file line number Diff line number Diff line change
@@ -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();
}
})
}
2 changes: 1 addition & 1 deletion src/queries/listings/postListing.js
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down

0 comments on commit 3adbaba

Please sign in to comment.