Skip to content

Commit

Permalink
in backend adding : pictures-controllers.js & pictures-module.js, POS…
Browse files Browse the repository at this point in the history
…T => /api/places endpoint || in frontend fixind some bugs in SignUp.js Login.js & creating NewPicture.js for => /pictures/new path and connect it with his api endpoint
  • Loading branch information
djebby committed Mar 21, 2022
1 parent a6e0198 commit 6bf22a9
Show file tree
Hide file tree
Showing 11 changed files with 308 additions and 74 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
/backend/node_modules
/backend/.env
/backend/package-lock.json
/backend/uploads/images/*
/backend/uploads/images/*.png
/backend/uploads/images/*.jpg
/backend/uploads/images/*.jpeg
/frontend/node_modules
/frontend/package-lock.json
48 changes: 48 additions & 0 deletions backend/controllers/pictures-controllers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
const { validationResult } = require("express-validator");

const HttpError = require("../models/http-error.js");
const Pictures = require("../models/pictures-model.js");
const User = require("../models/user-model.js");

// POST => /api/places
const createPictures = async (req, res, next) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return next(
new HttpError(
"Invalid inputs passed, please check your data.",
404
)
);
}
const { title, description, address } = req.body;

let newPic = undefined;
let user = undefined;
try {
user = await User.findById("62385d55706ae98bebc2fb5a"); // the user id should come from the chech-auth middleware
if (!user) {
return next(new HttpError("sorry there is no user with this id ", 404));
}
newPic = new Pictures({
title,
description,
image_url: req.file.path,
address,
creator_id: "62385d55706ae98bebc2fb5a",
});
await newPic.save();
user.pictures_ids.push(newPic);
await user.save();
} catch (error) {
return next(
new HttpError(
"Creating place failed, please try again " + error.message,
500
)
);
}
res.status(201).json({ newPic });
};

module.exports = { createPictures };
Empty file.
12 changes: 12 additions & 0 deletions backend/models/pictures-model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const mongoose = require("mongoose");
const Schema = mongoose.Schema;

const pictureSchema = new Schema({
title: { type: String, required: true, minlength: 3 },
description: { type: String, required: true, minlength: 10 },
image_url:{ type: String, required: true},
address: { type: String, required: true },
creator_id: { type: mongoose.Types.ObjectId, required: true, ref: "users"}
});

module.exports = mongoose.model("pictures", pictureSchema);
4 changes: 2 additions & 2 deletions backend/models/user-model.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ const userSchema = new Schema({
password: { type: String, required: true },
image_url: { type: String, required: true },
pictures_ids: [
{ type: mongoose.Types.ObjectId, required: true, ref: "Picture" },
{ type: mongoose.Types.ObjectId, required: true, ref: "pictures" },
],
});

module.exports = mongoose.model("User", userSchema);
module.exports = mongoose.model("users", userSchema);
18 changes: 13 additions & 5 deletions backend/routes/pictures-routes.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
const express = require("express");
const router = express.Router();
const { check } = require("express-validator");

const picturesControllers = require("../controllers/pictures-controllers.js");
const fileUpload = require("../middleware/file-upload.js");

router.post(
"/",
fileUpload.single("image"),
[
check("title").isLength({ min: 3 }),
check("description").isLength({ min: 10 }),
],
picturesControllers.createPictures
);





module.exports = router;
module.exports = router;
4 changes: 3 additions & 1 deletion backend/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const fs = require("fs");
const path = require("path");

const usersRoutes = require("./routes/users-routes.js");
const usersPictures = require("./routes/pictures-routes.js");

app.use(bodyParser.json());
app.use("/uploads/images", express.static(path.join("uploads", "images"))); //serve the image staticlly
Expand All @@ -20,6 +21,7 @@ app.use((req, res, next) => {
next();
});
app.use("/api/users", usersRoutes);
app.use("/api/pictures", usersPictures);

// Error Handling Middelware
app.use((error, req, res, next) => {
Expand All @@ -37,7 +39,7 @@ app.use((error, req, res, next) => {
});

mongoose
.connect(process.env.MONGO_URI)
.connect(process.env.LOCAL_MONGO_URI)
.then(() => {
console.log("Connection to DB Server Successfully ;)");
app.listen(process.env.PORT || 4000);
Expand Down
Empty file added backend/uploads/images/.gitkeep
Empty file.
188 changes: 183 additions & 5 deletions frontend/src/pictures/pages/NewPicture.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,187 @@
import React from 'react'
import React, { useRef, useState } from "react";
import Wrapper from "../../shared/components/UIElements/Wrapper.js";
import Input from "../../shared/components/UIElements/Input.js";

const NewPicture = () => {
//-----------------------------------------------------------------------------------------------------------------------------hooks-part
const refTitle = useRef("");
const refDescription = useRef("");
const refAddress = useRef("");
const refImage = useRef();
const [isLoading, setIsLoading] = useState(false);
const [successAlertVisibility, setSuccessAlertVisibility] = useState(false);
const [inputValidation, setInputValidation] = useState({
titleCssClasses: "",
descriptionCssClasses: "",
imageCssClasses: "",
wrongInputsAlertVisibility: false,
wrongInputsAlertMessage: "",
});
//-----------------------------------------------------------------------------------------------------------------------------errorHandler
const errorHandler = (errorMessage) => {
setIsLoading(false);
setInputValidation((prevInputValidation) => ({
...prevInputValidation,
wrongInputsAlertVisibility: true,
wrongInputsAlertMessage: errorMessage,
}));
setTimeout(() => {
setInputValidation((prevInputValidation) => ({
...prevInputValidation,
wrongInputsAlertVisibility: false,
}));
}, 5000);
};
//-----------------------------------------------------------------------------------------------------------------------------onSubmitHandler
const onSubmitHandler = async () => {
setIsLoading(true);
try {
if (
refTitle.current.value.trim().length >= 3 &&
refDescription.current.value.trim().length >= 10 &&
refImage.current.files[0] !== undefined
) {
const formData = new FormData();
formData.append("title", refTitle.current.value);
formData.append("description", refDescription.current.value);
formData.append("address", refAddress.current.value);
formData.append("image", refImage.current.files[0]);
const response = await fetch(
`${process.env.REACT_APP_BACKEND_URL}pictures/`,
{
method: "POST",
body: formData,
headers: {},
}
);
const data = await response.json();
setIsLoading(false);
if (response.ok) {
// this response give us the new posted picture
console.log(response.ok, data);
setSuccessAlertVisibility(true);
setTimeout(() => {
setSuccessAlertVisibility(false);
}, 5000);
//reset the form & the css classes of validation
refTitle.current.value = "";
refDescription.current.value = "";
refAddress.current.value = "";
refImage.current.value = "";
setInputValidation({
titleCssClasses: "",
descriptionCssClasses: "",
imageCssClasses: "",
wrongInputsAlertVisibility: false,
wrongInputsAlertMessage: "",
});
} else {
//error from backend validation...
errorHandler(data.message);
console.log(data); // failed to post the pic try again...
}
} else {
//error from frontend validation...
errorHandler("Please Enter a Valid Inputs Value");
}
} catch (error) {
errorHandler("Failed to fetch");
console.log(error);
}
};
//-----------------------------------------------------------------------------------------------------------------------------return(JSX)
return (
<div>NewPicture</div>
)
}
<Wrapper>
{inputValidation.wrongInputsAlertVisibility && (
<div className="alert alert-danger" role="alert">
<i className="bi bi-exclamation-octagon-fill m-1"></i>
{inputValidation.wrongInputsAlertMessage}
</div>
)}
{successAlertVisibility && (
<div className="alert alert-success" role="alert">
<i className="bi bi-send-check m-1"></i>
Picture Added Successfully
</div>
)}
<Input
ref={refTitle}
type="text"
name="title"
placeholder="picture title..."
label="Picture Title : "
cssClasses={inputValidation.titleCssClasses}
onBlur={() => {
setInputValidation((prevCssClasses) => ({
...prevCssClasses,
titleCssClasses:
refTitle.current.value.trim().length >= 3
? "is-valid"
: "is-invalid",
}));
}}
/>
<Input
ref={refDescription}
type="text"
name="description"
placeholder="picture description..."
label="Picture Description : "
cssClasses={inputValidation.descriptionCssClasses}
onBlur={() => {
setInputValidation((prevCssClasses) => ({
...prevCssClasses,
descriptionCssClasses:
refDescription.current.value.trim().length >= 10
? "is-valid"
: "is-invalid",
}));
}}
/>
<Input
ref={refAddress}
type="text"
name="address"
placeholder="picture address..."
label="Picture Address : "
/>

export default NewPicture;
<Input
ref={refImage}
type="file"
name="image"
accept=".jpg,.png,.jpeg"
label="Picture : "
cssClasses={inputValidation.imageCssClasses}
onChange={() => {
setInputValidation((prevCssClasses) => ({
...prevCssClasses,
imageCssClasses:
refImage.current.files[0] === undefined
? "is-invalid"
: "is-valid",
}));
}}
/>
<button
className="btn btn-info"
onClick={onSubmitHandler}
disabled={isLoading}
>
{isLoading ? (
<>
<span
className="spinner-border spinner-border-sm"
role="status"
aria-hidden="true"
></span>
Loading...
</>
) : (
"post"
)}
</button>
</Wrapper>
);
};
export default NewPicture;
Loading

0 comments on commit 6bf22a9

Please sign in to comment.