├── .gitignore ├── Backend ├── app.js ├── models │ ├── cmntIdeas.js │ ├── cmntProducts.js │ ├── ideas.js │ ├── products.js │ └── users.js ├── public │ ├── assets │ │ ├── images │ │ │ └── HeroImage.gif │ │ ├── login-hero.gif │ │ └── svg │ │ │ └── wave.svg │ └── styles.css └── views │ ├── cmntIdea.ejs │ ├── editCmntIdea.ejs │ ├── editIdea.ejs │ ├── ideas.ejs │ ├── index.ejs │ ├── login.ejs │ ├── partials │ ├── footer.ejs │ └── header.ejs │ ├── products.ejs │ ├── register.ejs │ ├── resources.ejs │ ├── showIdea.ejs │ └── submitIdea.ejs ├── LICENSE ├── README.md ├── Screenshots ├── Desktop View 2.png ├── Desktop View.png ├── Mobile View 2.png └── Mobile View.png ├── assets ├── hero-background.gif ├── hero-background.png ├── images │ └── Hero Image.gif ├── login-hero.gif ├── resources-hero.png └── svg │ └── wave (10).svg ├── index.html ├── login.html ├── resources.html ├── signup.html └── styles.css /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # TypeScript v1 declaration files 45 | typings/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | 78 | # Next.js build output 79 | .next 80 | 81 | # Nuxt.js build / generate output 82 | .nuxt 83 | dist 84 | 85 | # Gatsby files 86 | .cache/ 87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 88 | # https://nextjs.org/blog/next-9-1#public-directory-support 89 | # public 90 | 91 | # vuepress build output 92 | .vuepress/dist 93 | 94 | # Serverless directories 95 | .serverless/ 96 | 97 | # FuseBox cache 98 | .fusebox/ 99 | 100 | # DynamoDB Local files 101 | .dynamodb/ 102 | 103 | # TernJS port file 104 | .tern-port 105 | -------------------------------------------------------------------------------- /Backend/app.js: -------------------------------------------------------------------------------- 1 | const PORT = process.env.PORT || 3000; 2 | const express = require("express"); 3 | const app = express(); 4 | const bodyParser = require("body-parser"); 5 | const methodOverride = require("method-override"); 6 | const flash = require("connect-flash"); 7 | const passport = require("passport"); 8 | const LocalStrategy = require("passport-local"); 9 | const LocalMongooseStrategy = require("passport-local-mongoose"); 10 | const mongoose = require("mongoose"); 11 | const Idea = require("./models/ideas"); 12 | const Product = require("./models/products"); 13 | const Cmntproduct = require("./models/cmntProducts"); 14 | const Cmntidea = require("./models/cmntIdeas"); 15 | const User = require("./models/users"); 16 | mongoose.connect("mongodb://localhost:27017/techify_db",{ 17 | useNewUrlParser : true, 18 | useUnifiedTopology : true 19 | }) 20 | .then(()=> console.log("Connected to DB!!")) 21 | .catch(()=> console.log("error.meassage")); 22 | 23 | app.use(express.static("public")); 24 | app.use(bodyParser.urlencoded({extended : true})); 25 | app.use(methodOverride("_method")); 26 | app.locals.moment = require("moment"); 27 | app.use(flash()); 28 | 29 | app.use(require("express-session")({ 30 | secret : "Our little secret.", 31 | resave : false, 32 | saveUninitialized : false 33 | })); 34 | 35 | app.use(passport.initialize()); 36 | app.use(passport.session()); 37 | 38 | passport.use(new LocalStrategy(User.authenticate())); 39 | passport.serializeUser(User.serializeUser()); 40 | passport.deserializeUser(User.deserializeUser()); 41 | 42 | app.use(function(req,res,next){ 43 | res.locals.currentUser = req.user; 44 | res.locals.error = req.flash("error"); 45 | res.locals.success = req.flash("success"); 46 | next(); 47 | }); 48 | //========== 49 | //Main Route 50 | //========== 51 | app.get("/",(req,res) => { 52 | res.redirect("/home"); 53 | }) 54 | //home route 55 | app.get("/home",(req,res) => { 56 | res.render("index.ejs"); 57 | }) 58 | //products section 59 | app.get("/products",(req,res) => { 60 | res.render("products.ejs"); 61 | }) 62 | //resources section 63 | app.get("/resources",(req,res) => { 64 | res.render("resources.ejs"); 65 | }) 66 | 67 | 68 | //------- 69 | //Ideas 70 | //------- 71 | //Ideas(View all Ideas) 72 | app.get("/ideas",function(req,res){ 73 | Idea.find({},function(err,ideas){ 74 | if(err){ 75 | console.log(err); 76 | } 77 | else{ 78 | res.render("ideas.ejs",{ideas : ideas, currentUser : req.user}); 79 | } 80 | }); 81 | }); 82 | 83 | //Create Idea 84 | app.get("/ideas/new",isLoggedIn,function(req,res){ 85 | res.render("submitIdea.ejs"); 86 | }); 87 | 88 | //Create Idea POST Route 89 | app.post("/ideas",function(req,res){ 90 | var title = req.body.title; 91 | var body = req.body.body; 92 | var tech = req.body.tech; 93 | var author = { 94 | id : req.user._id, 95 | name : req.user.name 96 | } 97 | var newIdea = {title : title,body : body,tech : tech,author : author} 98 | Idea.create(newIdea,function(err,newlyCreatedIdea){ 99 | if(err){ 100 | req.flash("error","Some error Occurred!!"); 101 | res.render("submitIdea.ejs"); 102 | } 103 | else{ 104 | req.flash("success","Idea successfully created :)"); 105 | res.redirect("/ideas"); 106 | } 107 | }); 108 | }); 109 | 110 | // Show ideas Route 111 | app.get("/ideas/:id",function(req,res){ 112 | Idea.findById(req.params.id).populate("comments likes").exec(function(err,showIdea){ 113 | if(err){ 114 | req.redirect("/ideas"); 115 | } 116 | else{ 117 | 118 | res.render("showIdea.ejs",{idea : showIdea}); 119 | } 120 | }); 121 | }); 122 | 123 | //Edit ideas Route 124 | app.get("/ideas/:id/edit",checkIdeaOwnership,function(req,res){ 125 | Idea.findById(req.params.id,function(err,foundIdea){ 126 | if(err) { 127 | req.flash("error","Requested Idea doesn't exist"); 128 | } 129 | res.render("editIdea.ejs",{idea : foundIdea}); 130 | }); 131 | }); 132 | 133 | //Update ideas Route 134 | app.put("/ideas/:id",checkIdeaOwnership, function(req,res){ 135 | Idea.findByIdAndUpdate(req.params.id,req.body.blog,function(err,UpdatedIdea){ 136 | if(err){ 137 | req.flash("error","Some error occurred!!"); 138 | res.redirect("/ideas"); 139 | }else{ 140 | req.flash("success","Idea updated successfully"); 141 | res.redirect("/ideas/"+ req.params.id); 142 | } 143 | }); 144 | }); 145 | 146 | //Delete ideas Route 147 | app.delete("/ideas/:id",checkIdeaOwnership, function(req,res){ 148 | Idea.findByIdAndRemove(req.params.id,function(err){ 149 | if(err){ 150 | req.flash("error","Requested Idea does not exist!!"); 151 | res.redirect("/ideas"); 152 | }else{ 153 | req.flash("success","Idea deleted successfully"); 154 | res.redirect("/ideas"); 155 | } 156 | }); 157 | }); 158 | 159 | //====== 160 | //Likes 161 | //====== 162 | //Ideas like route 163 | app.post("/ideas/:id/likes",isLoggedIn,(req,res) => { 164 | Idea.findById(req.params.id,(err,foundIdea)=> { 165 | if(err) { 166 | req.flash("error","Idea not found!!!"); 167 | req.redirect("/ideas"); 168 | } 169 | var foundUserLike = foundIdea.likes.some((like) => { 170 | return like.equals(req.user._id); 171 | }); 172 | 173 | if(foundUserLike) { 174 | foundIdea.likes.pull(req.user._id); 175 | } else { 176 | foundIdea.likes.push(req.user); 177 | } 178 | 179 | foundIdea.save((err) => { 180 | if(err) { 181 | req.flash("error","An error occurred!!"); 182 | return res.redirect("/ideas"); 183 | } 184 | return res.redirect("/ideas/"+ foundIdea._id); 185 | }); 186 | 187 | }); 188 | }); 189 | 190 | //========== 191 | //Comments 192 | //========== 193 | //Show all comments 194 | app.post("/ideas/:id/comments",isLoggedIn,function(req,res) { 195 | Idea.findById(req.params.id, function(err,idea) { 196 | if(err) { 197 | console.log(err); 198 | res.redirect("/ideas"); 199 | } else { 200 | Cmntidea.create(req.body.comment,function(err, newCmnt){ 201 | if(err) { 202 | console.log(err); 203 | } else { 204 | newCmnt.author._id = req.user._id; 205 | newCmnt.author.username = req.user.name; 206 | newCmnt.author.email = req.user.username; 207 | 208 | newCmnt.save(); 209 | idea.comments.push(newCmnt); 210 | idea.save(); 211 | console.log(newCmnt); 212 | res.redirect("/ideas/"+idea._id); 213 | } 214 | }); 215 | } 216 | }) 217 | }) 218 | //new Comment 219 | app.get("/ideas/:id/comments/new",isLoggedIn,function(req,res) { 220 | Idea.findById(req.params.id,function(err, idea) { 221 | if(err) { 222 | console.log(err); 223 | } else { 224 | res.render("cmntIdea.ejs",{idea : idea}); 225 | } 226 | }) 227 | 228 | }); 229 | //Edit Comment 230 | app.get("/ideas/:id/comments/:comment_id/edit", function(req,res) { 231 | Cmntidea.findById(req.params.comment_id, function(err, foundComment) { 232 | if(err) { 233 | req.flash("error","You need to be logged in to do that!!"); 234 | res.redirect("back"); 235 | } else { 236 | res.render("editCmntIdea.ejs",{idea_id : req.params.id, comment : foundComment}); 237 | } 238 | }); 239 | 240 | }) 241 | //Put Comment 242 | app.put("/ideas/:id/comments/:comment_id",function(req,res) { 243 | Cmntidea.findByIdAndUpdate(req.params.comment_id,req.body.comment,function(err, updatedCmnt){ 244 | if(err) { 245 | req.flash("error","Something went wrong!!"); 246 | res.redirect("back"); 247 | } else { 248 | req.flash("success","Comment successfully edited"); 249 | res.redirect("/ideas/"+req.params.id); 250 | } 251 | }) 252 | }) 253 | //Delete Comment 254 | app.delete("/ideas/:id/comments/:comment_id", function(req,res){ 255 | 256 | Cmntidea.findByIdAndRemove(req.params.comment_id, function(err){ 257 | if(err){ 258 | req.flash("error","You need to be logged in to do that!!"); 259 | res.redirect("back"); 260 | } else { 261 | req.flash("success","Comment successfully deleted!!"); 262 | res.redirect("/ideas/"+ req.params.id); 263 | } 264 | }) 265 | }); 266 | 267 | //------- 268 | //Products 269 | //------- 270 | //Products(View all Products) 271 | app.get("/products",function(req,res){ 272 | Product.find({},function(err,ideas){ 273 | if(err){ 274 | console.log(err); 275 | } 276 | else{ 277 | res.render("products.ejs",{ideas : ideas, currentUser : req.user}); 278 | } 279 | }); 280 | }); 281 | 282 | //Create Idea 283 | app.get("/products/new",isLoggedIn,function(req,res){ 284 | res.render("Submit.ejs"); 285 | }); 286 | 287 | //Create Idea POST Route 288 | app.post("/products",function(req,res){ 289 | var title = req.body.title; 290 | var image = req.body.image; 291 | var price = req.body.price; 292 | var author = { 293 | id : req.user._id, 294 | name : req.user.name 295 | } 296 | var newProduct = {title : title,image : image,price : price,author : author} 297 | Product.create(newProduct,function(err,newlyCreatedProduct){ 298 | if(err){ 299 | req.flash("error","Some error Occurred!!"); 300 | res.render("Submit.ejs"); 301 | } 302 | else{ 303 | req.flash("success","Idea successfully created :)"); 304 | res.redirect("/products"); 305 | } 306 | }); 307 | }); 308 | 309 | // Show ideas Route 310 | app.get("/products/:id",function(req,res){ 311 | Product.findById(req.params.id).populate("comments likes").exec(function(err,showIdea){ 312 | if(err){ 313 | req.redirect("/products"); 314 | } 315 | else{ 316 | 317 | res.render("showProduct.ejs",{idea : showIdea}); 318 | } 319 | }); 320 | }); 321 | 322 | //Edit ideas Route 323 | app.get("/products/:id/edit",checkIdeaOwnership,function(req,res){ 324 | Product.findById(req.params.id,function(err,foundProduct){ 325 | if(err) { 326 | req.flash("error","Requested Idea doesn't exist"); 327 | } 328 | res.render("editProduct.ejs",{idea : foundProduct}); 329 | }); 330 | }); 331 | 332 | //Update ideas Route 333 | app.put("/products/:id",checkIdeaOwnership, function(req,res){ 334 | Product.findByIdAndUpdate(req.params.id,req.body.blog,function(err,UpdatedIdea){ 335 | if(err){ 336 | req.flash("error","Some error occurred!!"); 337 | res.redirect("/products"); 338 | }else{ 339 | req.flash("success","Idea updated successfully"); 340 | res.redirect("/products/"+ req.params.id); 341 | } 342 | }); 343 | }); 344 | 345 | //Delete ideas Route 346 | app.delete("/products/:id",checkIdeaOwnership, function(req,res){ 347 | Product.findByIdAndRemove(req.params.id,function(err){ 348 | if(err){ 349 | req.flash("error","Requested Idea does not exist!!"); 350 | res.redirect("/products"); 351 | }else{ 352 | req.flash("success","Idea deleted successfully"); 353 | res.redirect("/products"); 354 | } 355 | }); 356 | }); 357 | 358 | //====== 359 | //Likes 360 | //====== 361 | //Blog like route 362 | app.post("/products/:id/likes",isLoggedIn,(req,res) => { 363 | Product.findById(req.params.id,(err,foundProduct)=> { 364 | if(err) { 365 | req.flash("error","Idea not found!!!"); 366 | req.redirect("/products"); 367 | } 368 | var foundUserLike = foundIdea.likes.some((like) => { 369 | return like.equals(req.user._id); 370 | }); 371 | 372 | if(foundUserLike) { 373 | foundIdea.likes.pull(req.user._id); 374 | } else { 375 | foundIdea.likes.push(req.user); 376 | } 377 | 378 | foundProduct.save((err) => { 379 | if(err) { 380 | req.flash("error","An error occurred!!"); 381 | return res.redirect("/products"); 382 | } 383 | return res.redirect("/products/"+ foundIdea._id); 384 | }); 385 | 386 | }); 387 | }); 388 | 389 | //========== 390 | //Comments 391 | //========== 392 | //Show all comments 393 | app.post("/products/:id/comments",isLoggedIn,function(req,res) { 394 | Product.findById(req.params.id, function(err,idea) { 395 | if(err) { 396 | console.log(err); 397 | res.redirect("/products"); 398 | } else { 399 | Cmntproduct.create(req.body.comment,function(err, newCmnt){ 400 | if(err) { 401 | console.log(err); 402 | } else { 403 | newCmnt.author._id = req.user._id; 404 | newCmnt.author.username = req.user.name; 405 | newCmnt.author.email = req.user.username; 406 | 407 | newCmnt.save(); 408 | idea.cmntproducts.push(newCmnt); 409 | idea.save(); 410 | console.log(newCmnt); 411 | res.redirect("/products/"+idea._id); 412 | } 413 | }); 414 | } 415 | }) 416 | }) 417 | //new Comment 418 | app.get("/products/:id/comments/new",isLoggedIn,function(req,res) { 419 | Product.findById(req.params.id,function(err, idea) { 420 | if(err) { 421 | console.log(err); 422 | } else { 423 | res.render("newComment.ejs",{idea : idea}); 424 | } 425 | }) 426 | 427 | }); 428 | //Edit Comment 429 | app.get("/products/:id/comments/:comment_id/edit", function(req,res) { 430 | Cmntproduct.findById(req.params.comment_id, function(err, foundComment) { 431 | if(err) { 432 | req.flash("error","You need to be logged in to do that!!"); 433 | res.redirect("back"); 434 | } else { 435 | res.render("editComment.ejs",{idea_id : req.params.id, comment : foundComment}); 436 | } 437 | }); 438 | 439 | }) 440 | //Put Comment 441 | app.put("/products/:id/comments/:comment_id",function(req,res) { 442 | Cmntproduct.findByIdAndUpdate(req.params.comment_id,req.body.comment,function(err, updatedCmnt){ 443 | if(err) { 444 | req.flash("error","Something went wrong!!"); 445 | res.redirect("back"); 446 | } else { 447 | req.flash("success","Comment successfully edited"); 448 | res.redirect("/products/"+req.params.id); 449 | } 450 | }) 451 | }) 452 | //Delete Comment 453 | app.delete("/products/:id/comments/:comment_id", function(req,res){ 454 | 455 | Cmntproduct.findByIdAndRemove(req.params.comment_id, function(err){ 456 | if(err){ 457 | req.flash("error","You need to be logged in to do that!!"); 458 | res.redirect("back"); 459 | } else { 460 | req.flash("success","Comment successfully deleted!!"); 461 | res.redirect("/products/"+ req.params.id); 462 | } 463 | }) 464 | }); 465 | 466 | 467 | 468 | //======== 469 | //Contact 470 | //======== 471 | // app.get("/home/contact",(req,res) => { 472 | // res.render("contact.ejs"); 473 | // }) 474 | 475 | // app.post("/home",(req,res) => { 476 | // Contact.create(req.body.message,(err,newM) => { 477 | // if(err) { 478 | // res.redirect("/home/contact"); 479 | // } else { 480 | // console.log("New Message"); 481 | // res.redirect("/home/contact"); 482 | // } 483 | // }); 484 | 485 | // }) 486 | 487 | 488 | //=============== 489 | //Authentication 490 | //=============== 491 | app.post("/register",(req,res) => { 492 | User.register(new User({username : req.body.username, name : req.body.name,image : req.body.userImage}),req.body.password,function(err, user){ 493 | if(err) { 494 | console.log(err); 495 | var errMsg = err.message; 496 | req.flash("error",errMsg); 497 | res.redirect("/register"); 498 | } 499 | passport.authenticate("local")(req, res, function(){ 500 | req.flash("success","Account successfully created!!"); 501 | res.redirect("/home"); 502 | }) 503 | }) 504 | }) 505 | //Login 506 | app.post("/login",passport.authenticate("local",{ 507 | successRedirect : "/home", 508 | failureRedirect : "/login" 509 | }) ,function(req,res) { 510 | 511 | }) 512 | //Show Regiter 513 | app.get("/register",(req,res) =>{ 514 | res.render("register.ejs"); 515 | }) 516 | //Show Login 517 | app.get("/login", (req,res) => { 518 | res.render("login.ejs"); 519 | }) 520 | //Logout 521 | app.get("/logout",(req,res) => { 522 | req.logout(); 523 | req.flash("success","Logged You Out!!"); 524 | res.redirect("/home"); 525 | }) 526 | 527 | //============ 528 | //Middleware 529 | //============ 530 | function isLoggedIn(req,res,next){ 531 | if(req.isAuthenticated()) { 532 | 533 | return next(); 534 | } 535 | req.flash("error","You need to be logged in to do that!!"); 536 | res.redirect("/login"); 537 | } 538 | 539 | function checkIdeaOwnership(req,res,next) { 540 | if(req.isAuthenticated()) { 541 | Idea.findById(req.params.id,function(err,foundIdea){ 542 | if(err){ 543 | req.flash("error","Campground not found!!"); 544 | res.redirect("back"); 545 | }else{ 546 | if(foundIdea.author.id.equals(req.user._id)) { 547 | next(); 548 | } else { 549 | req.flash("error","You don't have the permission to do that!!"); 550 | res.redirect("back"); 551 | } 552 | 553 | } 554 | }); 555 | } else { 556 | req.flash("error","You need to be logged in to do that"); 557 | res.redirect("back"); 558 | } 559 | } 560 | 561 | function checkCommentOwnership(req,res,next) { 562 | if(req.isAuthenticated()) { 563 | Cmntidea.findById(req.params.comment_id,function(err,foundComment){ 564 | if(err){ 565 | res.redirect("back"); 566 | }else{ 567 | // console.log(foundComment.author._id); 568 | // console.log(req.user._id); 569 | // console.log(foundComment.author.id.equals(req.user._id)); 570 | if(foundComment.author.id.equals(req.user._id)) { 571 | next(); 572 | } else { 573 | res.redirect("back"); 574 | } 575 | 576 | } 577 | }); 578 | } else { 579 | res.redirect("back"); 580 | } 581 | } 582 | 583 | 584 | 585 | 586 | //Listen Route 587 | app.listen(PORT,() => { 588 | console.log("Server has started successfully!!"); 589 | }) 590 | -------------------------------------------------------------------------------- /Backend/models/cmntIdeas.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | 3 | const cmntIdeaSchema = new mongoose.Schema({ 4 | text: String, 5 | createdAt : {type : Date,default : Date.now}, 6 | author: { 7 | id : { 8 | type : mongoose.Schema.Types.ObjectId, 9 | ref : "User" 10 | }, 11 | username : String, 12 | email : String 13 | } 14 | 15 | }); 16 | 17 | module.exports = mongoose.model("Cmntidea", cmntIdeaSchema); -------------------------------------------------------------------------------- /Backend/models/cmntProducts.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | 3 | const cmntProductSchema = new mongoose.Schema({ 4 | text: String, 5 | createdAt : {type : Date,default : Date.now}, 6 | author: { 7 | id : { 8 | type : mongoose.Schema.Types.ObjectId, 9 | ref : "User" 10 | }, 11 | username : String, 12 | email : String 13 | } 14 | 15 | }); 16 | 17 | module.exports = mongoose.model("Cmntproduct", cmntProductSchema); -------------------------------------------------------------------------------- /Backend/models/ideas.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | 3 | const ideaSchema = new mongoose.Schema({ 4 | title : String, 5 | body : String, 6 | tech : String, 7 | author : { 8 | id : { 9 | type :mongoose.Schema.Types.ObjectId, 10 | ref : "User" 11 | }, name : String 12 | }, 13 | comments: [ 14 | { 15 | type: mongoose.Schema.Types.ObjectId, 16 | ref: "Cmntidea" 17 | } 18 | ], 19 | likes : [ 20 | { 21 | type : mongoose.Schema.Types.ObjectId, 22 | ref : "User" 23 | } 24 | ], 25 | createdAt : {type : Date,default : Date.now} 26 | }); 27 | 28 | 29 | 30 | module.exports = mongoose.model("Idea",ideaSchema); -------------------------------------------------------------------------------- /Backend/models/products.js: -------------------------------------------------------------------------------- 1 | var mongoose = require("mongoose"); 2 | 3 | var productSchema = new mongoose.Schema({ 4 | title : String, 5 | image : String, 6 | price : String, 7 | author : { 8 | id : { 9 | type :mongoose.Schema.Types.ObjectId, 10 | ref : "User" 11 | }, name : String 12 | }, 13 | comments: [ 14 | { 15 | type: mongoose.Schema.Types.ObjectId, 16 | ref: "Cmntproduct" 17 | } 18 | ], 19 | likes : [ 20 | { 21 | type : mongoose.Schema.Types.ObjectId, 22 | ref : "User" 23 | } 24 | ], 25 | createdAt : {type : Date,default : Date.now} 26 | }); 27 | 28 | 29 | 30 | module.exports = mongoose.model("Product",productSchema); -------------------------------------------------------------------------------- /Backend/models/users.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | const passportLocalMongoose = require("passport-local-mongoose"); 3 | 4 | const userSchema = mongoose.Schema({ 5 | name : String, 6 | username : String, 7 | image : String, 8 | password : String 9 | 10 | }); 11 | userSchema.plugin(passportLocalMongoose); 12 | module.exports = mongoose.model("User",userSchema); -------------------------------------------------------------------------------- /Backend/public/assets/images/HeroImage.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KushalBhanot/Techify/cf129822d281f288c4d323374d4b46b028faaeb3/Backend/public/assets/images/HeroImage.gif -------------------------------------------------------------------------------- /Backend/public/assets/login-hero.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KushalBhanot/Techify/cf129822d281f288c4d323374d4b46b028faaeb3/Backend/public/assets/login-hero.gif -------------------------------------------------------------------------------- /Backend/public/assets/svg/wave.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Backend/public/styles.css: -------------------------------------------------------------------------------- 1 | @import url("https://use.typekit.net/ojv4ekx.css"); 2 | 3 | * { 4 | padding: 0; 5 | margin: 0; 6 | font-family: "europa",sans-serif; 7 | box-sizing: border-box; 8 | outline:none; 9 | } 10 | /* #e6198e */ 11 | /* Color Codes & Other Variables */ 12 | :root { 13 | --primary: #ffb32c; 14 | --primary-variant: #F17C1C; 15 | --text: #000; 16 | --text-variant: #fff; 17 | --highlight: #8EE619; 18 | 19 | 20 | 21 | --tertiary: #323232; 22 | 23 | 24 | --Ideahighlight: #4194ff; 25 | } 26 | 27 | /* overall adjustments */ 28 | html { 29 | scroll-behavior: smooth; 30 | } 31 | body { 32 | overflow-x: hidden; 33 | } 34 | .container-fluid { 35 | padding: 3% 10%; 36 | } 37 | .container-fluid-hero { 38 | padding-top: 3%; 39 | padding-bottom: 3%; 40 | padding-left: 10%; 41 | } 42 | .selectDisable { 43 | -webkit-user-select: none; 44 | -khtml-user-select: none; 45 | -moz-user-select: none; 46 | -o-user-select: none; 47 | user-select: none; 48 | } 49 | 50 | /* scroll bar */ 51 | ::-webkit-scrollbar { 52 | width: 6px; 53 | background-color: #F5F5F5; 54 | } 55 | ::-webkit-scrollbar-thumb { 56 | background-color: #000000; 57 | } 58 | ::-webkit-scrollbar-track { 59 | box-shadow: inset 0 0 6px rgba(0,0,0,0.3); 60 | background-color: #F5F5F5; 61 | } 62 | 63 | /* Navigation Bar */ 64 | nav { 65 | background: var(--text-variant); 66 | color: var(--primary-variant); 67 | z-index: 1; 68 | } 69 | .navbar { 70 | /* padding: 0 0 4.5rem; */ 71 | padding-left: 10%; 72 | padding-right: 10%; 73 | } 74 | .navbar-brand { 75 | font-size: 2rem; 76 | font-weight: bolder; 77 | color: #e6198e; 78 | } 79 | .navlink-border:hover { 80 | border-bottom: 2px solid var(--primary-variant); 81 | } 82 | .nav-link { 83 | font-size: 1.5 rem; 84 | font-weight: normal; 85 | color: var(--primary-variant); 86 | } 87 | .navbar-toggler i { 88 | color: #e6198e; 89 | } 90 | .navbar-brand:hover , .nav-link:hover, .navbar-toggler i:hover { 91 | color: #e6198e; 92 | } 93 | .login-btn { 94 | color: var(--text-variant); 95 | background-image: linear-gradient(134deg,#e6198e, #e6198e, var(--primary-variant)); 96 | border-radius: 30px; 97 | padding: 10px 45px; 98 | } 99 | .login-btn:hover { 100 | border: none; 101 | color: var(--text-variant); 102 | background-image: linear-gradient(134deg, var(--primary-variant),#e6198e,#e6198e); 103 | box-shadow: 2px 2px 4px rgba(0,0,0,0.3); 104 | border-radius: 30px; 105 | padding: 10px 45px; 106 | } 107 | /* hero section */ 108 | #hero-section { 109 | height: 90vh; 110 | background-color: #f7f7f7; 111 | } 112 | .hero-intro { 113 | position: relative; 114 | z-index: 5; 115 | } 116 | #hero-section h1 { 117 | color: #F17C1C; 118 | letter-spacing: 1pxs; 119 | font-size: 48px; 120 | line-height: 106%; 121 | padding-top: 5%; 122 | } 123 | #hero-section span { 124 | color: #e6198e; 125 | font-size: 1.4em; 126 | } 127 | #hero-section p { 128 | padding-top: 5%; 129 | color: grey; 130 | font-size: 1.2em; 131 | } 132 | .cta { 133 | margin-top: 2vh; 134 | padding: 10px 45px; 135 | color: #FFF; 136 | background-image: linear-gradient(to top, #E6198E, #EB47A5); 137 | border-radius: 30px; 138 | /* transition: all ease-in-out 0.25s; */ 139 | } 140 | .cta:hover { 141 | color: #FFF; 142 | box-shadow: 4px 4px 6px rgba(0,0,0,0.3); 143 | background-image: linear-gradient(to top, #EB47A5, #E6198E); 144 | /* padding: 10px 55px; */ 145 | } 146 | .hero-image { 147 | z-index: 3; 148 | } 149 | .hero-wave { 150 | background-color: #f7f7f7; 151 | margin-top: -200px; 152 | position: absolute; 153 | bottom: 0; 154 | } 155 | @media only screen and (max-width: 992px) { 156 | .hero-image { 157 | display: none; 158 | } 159 | .hero-wave { 160 | display: none; 161 | } 162 | #hero-section { 163 | padding-right: 10%; 164 | } 165 | #hero-section h1 { 166 | font-size: normal; 167 | color: #fa7f34; 168 | } 169 | #hero-section p { 170 | padding-top: 50px; 171 | font-size: normal; 172 | } 173 | } 174 | @media only screen and (max-width: 990px) { 175 | #hero-section { 176 | background-image: url('assets/hero-background.png'); 177 | background-size: cover; 178 | background-repeat: no-repeat; 179 | background-position: center; 180 | height: 90vh; 181 | } 182 | #hero-section::before { 183 | content: ""; 184 | position: absolute; 185 | top: 0px; 186 | right: 0px; 187 | bottom: 0px; 188 | left: 0px; 189 | background-color: rgba(0,0,0,0.45); 190 | /* margin-bottom: -20%; */ 191 | } 192 | #hero-section h1 { 193 | margin-top: 5%; 194 | font-size: 2.5em; 195 | color: orange; 196 | } 197 | #hero-section p { 198 | color: seashell; 199 | padding-top: 20px; 200 | font-size: normal; 201 | } 202 | .cta { 203 | margin-top: 2%; 204 | } 205 | } 206 | @media only screen and (min-width: 880px) and (max-width: 1165px) { 207 | #hero-section { 208 | padding-top: 5vh; 209 | }; 210 | } 211 | @media only screen and (max-width: 768px) { 212 | #hero-section { 213 | padding-top: 5%; 214 | } 215 | } 216 | 217 | /* description section */ 218 | #description-section { 219 | background-color: #F5F5F9; 220 | text-align: center; 221 | padding-bottom: 200px; 222 | } 223 | #description-section h1 { 224 | margin-top: 100px; 225 | padding-bottom: 16px; 226 | color: #35353F; 227 | font-size: 32px; 228 | font-weight: bold; 229 | } 230 | #description-section p { 231 | padding: 0 15%; 232 | color: #35353F; 233 | font-size: 1.125rem; 234 | line-height: 1.75rem; 235 | opacity: 0.9; 236 | margin-bottom: 50px; 237 | } 238 | /* @media only screen and (max-width: 990px) { 239 | #description-section p { 240 | padding: 0; 241 | } 242 | } */ 243 | #description-section .fa-calendar-check { 244 | color: #EF9425; 245 | } 246 | #description-section .fa-shopping-cart { 247 | color: #47BDA1; 248 | } 249 | #description-section .fa-search { 250 | color: #862783; 251 | } 252 | .description-cta { 253 | color: var(--text-variant); 254 | background-color: #e6198e; 255 | border-radius: 50px; 256 | padding: 10px 25px; 257 | } 258 | .description-cta:hover { 259 | color: #e6198e; 260 | background-color: transparent; 261 | } 262 | 263 | /* footer */ 264 | footer { 265 | background-color: #e6198e; 266 | } 267 | footer h1:hover { 268 | color: var(--text-variant); 269 | } 270 | #back-to-top:hover { 271 | color: var(--text-variant); 272 | } 273 | footer p { 274 | color: #F5F5F5; 275 | } 276 | footer a { 277 | color: #F5F5F5; 278 | } 279 | footer a:hover { 280 | color: orange; 281 | text-decoration: none; 282 | } 283 | @media only screen and (max-width: 990px) { 284 | footer { 285 | text-align: center; 286 | } 287 | } 288 | 289 | /* login */ 290 | #login { 291 | height: 100vh; 292 | overflow: hidden; 293 | } 294 | #login-form { 295 | padding-top: 5%; 296 | padding-left: 8%; 297 | padding-right: 8%; 298 | padding-bottom: 8%; 299 | } 300 | #login-form h1 { 301 | color: #381e56; 302 | } 303 | #login-form h1 a:hover { 304 | text-decoration: none; 305 | } 306 | #login-form h3 { 307 | font-weight: bold; 308 | padding-top: 50px; 309 | } 310 | #login-form p { 311 | color: grey; 312 | } 313 | .submit-btn { 314 | color: #F5F5F5; 315 | padding: 10px 45px; 316 | background-color: rgba(56, 30, 86, 0.7); 317 | margin-top: 30px; 318 | } 319 | .submit-btn:hover { 320 | padding: 10px 55px; 321 | color: var(--text-variant); 322 | background-color: rgba(56, 30, 86, 0.9); 323 | } 324 | #login-form .extra { 325 | text-align: center; 326 | padding-top: 20px; 327 | } 328 | #login-form a { 329 | color: #381e56; 330 | } 331 | #login-img { 332 | position: relative; 333 | bottom: 0; 334 | background-color: #381e56; 335 | padding: 10% 8%; 336 | } 337 | /* signup */ 338 | #signup-form { 339 | padding-top: 1%; 340 | padding-left: 8%; 341 | padding-right: 8%; 342 | padding-bottom: 8%; 343 | } 344 | #signup-form h1 { 345 | color: #381e56; 346 | } 347 | #signup-form h1 a:hover { 348 | text-decoration: none; 349 | } 350 | #signup-form h3 { 351 | font-weight: bold; 352 | padding-top: 10px; 353 | } 354 | #signup-form p { 355 | color: grey; 356 | } 357 | #signup-form .extra { 358 | text-align: center; 359 | padding-top: 20px; 360 | } 361 | #signup-form a { 362 | color: #381e56; 363 | } 364 | 365 | /* My Code */ 366 | /* ideas section */ 367 | #ideas-section { 368 | text-align: center; 369 | height: auto; 370 | 371 | } 372 | 373 | .idea-submit-btn, .idea-submit-btn:visited { 374 | background-color: transparent; 375 | color: var(--tertiary); 376 | border: 2px solid var(--text-variant); 377 | padding: 1% 4%; 378 | margin-bottom: 6%; 379 | border-radius: 0.4em; 380 | } 381 | 382 | .idea-submit-btn:focus, .idea-submit-btn:hover { 383 | padding: 1.2% 4.5%; 384 | outline: none; 385 | } 386 | /* Ideas Card */ 387 | #card { 388 | max-width : 700px; 389 | max-height : 500px; 390 | margin-left : auto; 391 | margin-right: auto; 392 | } 393 | /* .card { 394 | border-radius: 8px; 395 | box-shadow: 5px 5px 15px var(--tertiary); 396 | transition : all 0.3s ease-in !important; 397 | background: var(--tertiary); 398 | color : var(--text-variant); 399 | 400 | } */ 401 | /* .card:hover { 402 | background : var(--primary); 403 | box-shadow : 5px 5px 10px var(--tertiary); 404 | 405 | } */ 406 | /*.card:hover h3,.card:hover i { 407 | color : var(--text); 408 | } 409 | 410 | .card h1 { 411 | font-size : 36px !important; 412 | color : var(--primary-variant) !important; 413 | text-shadow: 2px 2px var(--primary) !important; 414 | font-weight : bold !important; 415 | padding-top: 0 !important; 416 | padding-bottom: 0 !important; 417 | 418 | } 419 | .card h3 { 420 | font-size : 24px; 421 | font-weight : bold; 422 | color : var(--primary); 423 | text-shadow: 2px 2px var(--primary-variant); 424 | } 425 | .card:hover h1{ 426 | text-shadow: 3px 3px var(--tertiary) !important; 427 | } 428 | .card:hover h3 { 429 | color : var(--tertiary); 430 | } 431 | .card img { 432 | margin-top: -50px; 433 | } 434 | .card i { 435 | font-size : 26px; 436 | transition : all 0.3s ease-in; 437 | color : var(--primary-variant); 438 | } 439 | .card i:hover{ 440 | color : var(--tertiary); 441 | } 442 | .card p { 443 | font-size: 500; 444 | } */ 445 | 446 | .card-body { 447 | padding-left : 0.75rem !important; 448 | padding-right : 0.2rem !important; 449 | } 450 | .card-body-container { 451 | padding-left : 1.25rem; 452 | padding-right : 1.25rem; 453 | } 454 | 455 | .transparent { 456 | background : transparent !important; 457 | color : var(--text); 458 | } 459 | .idea-parent-container { 460 | padding-left : 10%; 461 | padding-right: 10%; 462 | } 463 | .auth-list { 464 | display: flex; 465 | list-style-type : none; 466 | } 467 | .auth-list h1 { 468 | color : var(--text); 469 | font-weight:800; 470 | font-size:4rem; 471 | } 472 | .auth-list .nav-item:hover { 473 | border-bottom : none; 474 | } 475 | #auth-in button{ 476 | padding : 5px 15px 5px 15px; 477 | width : 150px; 478 | } 479 | .user-img { 480 | width : 40px; 481 | height : 40px; 482 | 483 | } 484 | #auth-out a { 485 | text-decoration: none; 486 | 487 | } 488 | #auth-out button { 489 | padding : 5px 15px 5px 15px; 490 | } 491 | #idea-card { 492 | width : 100%; 493 | background : var(--tertiary) !important; 494 | color : var(--text-variant); 495 | } 496 | #idea-card:hover { 497 | background : var(--text) !important; 498 | box-shadow : 5px 5px 10px var(--tertiary) !important; 499 | } 500 | #idea-card i { 501 | color : var(--Ideahighlight); 502 | } 503 | .ideas-image { 504 | margin-top: 5%; 505 | } 506 | 507 | .btn-parent { 508 | display: flex; 509 | justify-content: space-between; 510 | } 511 | 512 | .comments { 513 | background : var(--text-variant); 514 | margin-top : 20px; 515 | padding : 10px 20px 10px 20px; 516 | display: flex; 517 | flex-direction: column; 518 | justify-content: center; 519 | align-items: center; 520 | color : var(--text); 521 | } 522 | .comments h1 { 523 | color : var(--text) !important; 524 | text-shadow: none !important; 525 | } 526 | .card:hover .comments h1 { 527 | text-shadow: none !important; 528 | } 529 | 530 | .comments li { 531 | text-align: center; 532 | 533 | } 534 | #cmnt { 535 | text-align: left; 536 | margin-top : 10px; 537 | background : var(--text-variant); 538 | width : 90%; 539 | padding-right : 10px; 540 | } 541 | #parent_cmnt { 542 | background : whitesmoke; 543 | margin : 5px; 544 | width : 100%; 545 | } 546 | .child_cmnt { 547 | display: flex; 548 | justify-content: space-between; 549 | 550 | } 551 | .cmnt-box { 552 | margin-top : 20px; 553 | border : 5px solid var(--nav-item); 554 | width: fit-content; 555 | text-align : left; 556 | padding-top : 10px; 557 | padding-left : 20px; 558 | padding-right : 20px; 559 | } 560 | 561 | 562 | @media only screen and (max-width : 576px) { 563 | .card-body-container { 564 | padding-left : 0 !important; 565 | padding-right : 0 !important; 566 | } 567 | .auth-list h1 { 568 | font-weight : 600; 569 | font-size : 3rem; 570 | } 571 | 572 | 573 | 574 | } 575 | @media only screen and (max-width : 420px) { 576 | .idea-parent-container { 577 | padding-right: 2%; 578 | padding-left: 2%; 579 | } 580 | .auth-container { 581 | padding-left: 8%; 582 | 583 | } 584 | } 585 | -------------------------------------------------------------------------------- /Backend/views/cmntIdea.ejs: -------------------------------------------------------------------------------- 1 | <%- include("partials/header") %> 2 | 3 | 4 | 5 | TECHIFY 6 | Hello! 7 | Add a Comment to <%= idea.title %> 8 | 9 | 10 | 11 | Comment 12 | 13 | 14 | 15 | 16 | Submit 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 |
Add a Comment to <%= idea.title %>