Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
yashverma3 committed Aug 28, 2023
0 parents commit 929c0bc
Show file tree
Hide file tree
Showing 40 changed files with 19,010 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules
.env
167 changes: 167 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
<div align="center">
<h1>🏕️ YelpCamp 🌲</h1>
</div>

<div align="center">
<h2>- Development Process -</h2>
</div>

## Initial Setup

- [x] Add Landing Page
- [x] Add Campgrounds Page that lists all campgrounds

## Each Campground has:

- [x] Name
- [x] Image

## Layout and Basic Styling

- [x] Create our header and footer partials
- [x] Add in Bootstrap

## Creating New Campgrounds

- [x] Setup new campground POST route
- [x] Add in body-parser
- [x] Setup route to show form
- [x] Add basic unstyled form

## Style the campgrounds page

- [x] Add a better header/title
- [x] Make campgrounds display in a grid

## Style the Navbar and Form

- [x] Add a navbar to all templates
- [x] Style the new campground form

## Add Mongoose

- [x] Install and configure Mongoose
- [x] Setup campground model
- [x] Use campground model inside of our routes

## Show Page

- [x] Review the RESTful routes we've seen so far
- [x] Add description to our campground model
- [x] Show db.collection.drop()
- [x] Add a show route/template

## Refactor Mongoose Code

- [x] Create a models directory
- [x] Use module.exports
- [x] Require everything correctly

## Add Seeds File

- [x] Add a seeds.js file
- [x] Run the seeds file every time the server starts

## Add the Comment model

- [x] Make our errors go away
- [x] Display comments on campground show page

## Comment New/Create

- [x] Discuss nested routes
- [x] Add the comment new and create routes
- [x] Add the new comment form

## Style Show Page

- [x] Add sidebar to show page
- [x] Display comments nicely

## Finish Styling Show Page

- [x] Add public directory
- [x] Add custom stylesheet

## Auth Pt. 1 - Add User Model

- [x] Install all packages needed for auth
- [x] Define User model

## Auth Pt. 2 - Register

- [x] Cconfigure Passport
- [x] Add register routes
- [x] Add register template

## Auth Pt. 3 - Login

- [x] Add login routes
- [x] Add login template

## Auth Pt. 4 - Logout/Navbar

- [x] Add logout route
- [x] Prevent user from adding a comment if not signed in
- [x] Add links to navbar

## Auth Pt. 5 - Show/Hide Links

- [x] Show/hide auth links in navbar

## Refactor The Routes

- [x] Use Express router to reoragnize all routes

## Users + Comments

- [x] Associate users and comments
- [x] Save author's name to a comment automatically

## Users + Campgrounds

- [x] Prevent an unauthenticated user from creating a campground
- [x] Save username + id to newly created campground

## Editing Campgrounds

- [x] Add method override
- [x] Add edit route for campgrounds
- [x] Add link to edit page
- [x] Add update route

## Deleting Campgrounds

- [x] Add destroy route
- [x] Add delete button

## Authorization (permission)

- [x] User can only edit his/her campgrounds
- [x] User can only delete his/her campgrounds
- [x] Hide/Show edit and delete buttons

## Editing comments

- [x] Add edit route for comments
- [x] Add edit template
- [x] Add edit button
- [x] Add update route

## Deleting comments

- [x] Add destroy route
- [x] Add delete button

## Authorization part 2: Comments

- [x] User can only edit his/her comments
- [x] User can only delete his/her comments
- [x] Hide/Show edit and delete buttons
- [x] Refactor middleware

## Adding in flash

- [x] Demo working version
- [x] Install and configure connect-flash
- [x] Add bootstrap alerts to header
112 changes: 112 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
if(process.env.NODE_ENV !== "production") {
require('dotenv').config();
}

const express = require('express');
const path = require('path');
const mongoose = require('mongoose');
const ejsMate = require('ejs-mate');
const session = require('express-session');
const flash = require('connect-flash');
const ExpressError = require('./utils/ExpressError');
const methodOverride = require('method-override');
const passport = require('passport');
const LocalStrategy = require('passport-local');
const User = require('./models/user');
const helmet = require('helmet');
const mongoSanitize = require('express-mongo-sanitize');
const userRoutes = require('./routes/users');
const campgroundRoutes = require('./routes/campgrounds');
const reviewRoutes = require('./routes/reviews');
const MongoStore = require("connect-mongo");
const dbUrl = process.env.DB_URL
mongoose.connect(dbUrl, {
useNewUrlParser: true,
useUnifiedTopology: true
});

const db = mongoose.connection;
db.once("open", () => {
console.log("Database connected");
}).on('error', (error) => {
console.log('Connection error', error);
});

const app = express();

app.engine('ejs', ejsMate)
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'))

app.use(express.urlencoded({ extended: true }));
app.use(methodOverride('_method'));
app.use(express.static(path.join(__dirname, 'public')))
app.use(mongoSanitize({
replaceWith:'_'
}))

const secret = process.env.SECRET || 'thisshouldbebettersecret';

// const store = new MongoStore({
// url: dbUrl,
// secret: 'thisshouldbebettersecret',
// touchAfter: 24 * 60 * 60
// });

// store.on("error", function(e){
// console.log("SESSION STORE ERROR",e)
// })

const sessionConfig = {
// store,
name:'session',
secret,
resave: false,
saveUninitialized: true,
cookie: {
httpOnly: true,
// secure:true,
expires: Date.now() + 604800000,
maxAge: 604800000
}
}
app.use(session(sessionConfig));
app.use(flash());

app.use(passport.initialize());
app.use(passport.session());
passport.use(new LocalStrategy(User.authenticate()));

passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());

app.use((req,res,next)=>{
res.locals.currentUser = req.user;
res.locals.success = req.flash('success');
res.locals.error = req.flash('error');
next();
})

app.use('/',userRoutes);
app.use('/campgrounds',campgroundRoutes)
app.use('/campgrounds/:id/reviews',reviewRoutes)

app.get('/', (req, res) => {
res.render('home')
});

app.all('*', (req, res, next) => {
next(new ExpressError('Page Not Found', 404))
})

app.use((err, req, res, next) => {
const { statusCode = 500 } = err;
if (!err.message) err.message = 'Oh No, Something Went Wrong!'
res.status(statusCode).render('error', { err })
})

const port = process.env.PORT || 3000;

app.listen(port, () => {
console.log(`Serving on port ${port}`)
})
21 changes: 21 additions & 0 deletions cloudinary/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const cloudinary = require('cloudinary').v2;
const {CloudinaryStorage} = require('multer-storage-cloudinary');

cloudinary.config({
cloud_name: process.env.CLOUDINARY_CLOUD_NAME,
api_key: process.env.CLOUDINARY_KEY,
api_secret: process.env.CLOUDINARY_SECRET
});

const storage = new CloudinaryStorage({
cloudinary,
params:{
folder: 'YelpCamp',
allowedFormats: ['jpeg','png','jpg']
}
});

module.exports = {
cloudinary,
storage
}
76 changes: 76 additions & 0 deletions controllers/campgrounds.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
const Campground = require('../models/campground');
const mbxGeocoding = require("@mapbox/mapbox-sdk/services/geocoding");
const mapBoxToken = process.env.MAPBOX_TOKEN;
const geocoder = mbxGeocoding({accessToken:mapBoxToken});
const { cloudinary } = require("../cloudinary");

module.exports.index = async (req, res) => {
const campgrounds = await Campground.find({});
res.render('campgrounds/index', { campgrounds })
}

module.exports.renderNewForm = (req, res) => {
res.render('campgrounds/new');
}

module.exports.createCampground = async (req, res, next) => {
const geoData = await geocoder.forwardGeocode({
query: req.body.campground.location,
limit: 1
}).send()
const campground = new Campground(req.body.campground);
campground.geometry = geoData.body.features[0].geometry;
campground.images = req.files.map(f => ({ url: f.path, filename: f.filename }));
campground.author = req.user._id;
await campground.save();
console.log(campground);
req.flash('success', 'Successfully made a new campground!');
res.redirect(`/campgrounds/${campground._id}`)
}
module.exports.showCampground = async (req, res) => {
const campground = await Campground.findById(req.params.id).populate({
path: 'reviews',
populate: {
path: 'author'
}
}).populate('author');
if (!campground) {
req.flash('error', 'Cannot find that campground');
return res.redirect('/campgrounds');
}
res.render('campgrounds/show', { campground });
}

module.exports.renderEditForm = async (req, res) => {
const { id } = req.params;
const campground = await Campground.findById(id)
if (!campground) {
req.flash('error', 'Cannot find that campground');
return res.redirect('/campgrounds');
}
res.render('campgrounds/edit', { campground });
}

module.exports.updateCampground = async (req, res) => {
const { id } = req.params;
console.log(req.body);
const campground = await Campground.findByIdAndUpdate(id, { ...req.body.campground });
const imgs = req.files.map(f => ({ url: f.path, filename: f.filename }));
campground.images.push(...imgs);
if (req.body.deleteImages) {
for(let filename of req.body.deleteImages){
await cloudinary.uploader.destroy(filename);
}
await campground.updateOne({ $pull: { images: { filename: { $in: req.body.deleteImages } } } });
}
await campground.save();
req.flash('success', 'Successfully updated campground!')
res.redirect(`/campgrounds/${campground._id}`)
}

module.exports.deleteCampground = async (req, res) => {
const { id } = req.params;
await Campground.findByIdAndDelete(id);
req.flash('success', 'Successfully deleted campground!');
res.redirect('/campgrounds');
}
Loading

0 comments on commit 929c0bc

Please sign in to comment.