From bdfe3e98c02516d3c6edcec4d1817204ecdad4f7 Mon Sep 17 00:00:00 2001 From: Samriddhi903 Date: Wed, 2 Jul 2025 23:31:50 +0530 Subject: [PATCH] added image upload and display --- README.md | 3 + package-lock.json | 211 +++++++++++++++++++- package.json | 5 +- public/css/main.css | 11 + server/config/cloudinary.js | 9 + server/config/db.js | 4 +- server/controllers/dashboardController.js | 30 ++- server/controllers/imageUploadController.js | 27 +++ server/models/Notes.js | 3 + server/routes/dashboard.js | 7 +- views/dashboard/add.ejs | 88 +++++++- views/dashboard/index.ejs | 12 +- views/dashboard/view-notes.ejs | 165 ++++++++++++--- 13 files changed, 531 insertions(+), 44 deletions(-) create mode 100644 server/config/cloudinary.js create mode 100644 server/controllers/imageUploadController.js diff --git a/README.md b/README.md index f43fa44..23abf2c 100644 --- a/README.md +++ b/README.md @@ -118,6 +118,9 @@ GOOGLE_CLIENT_ID=your_google_client_id GOOGLE_CLIENT_SECRET=your_google_client_secret GOOGLE_CALLBACK_URL=http://localhost:5000/google/callback PORT=5000 +CLOUDINARY_CLOUD_NAME=your_cloudinary_name +CLOUDINARY_API_KEY=your_api_key +CLOUDINARY_API_SECRET=your_api_secret ``` 4. **Run the App** diff --git a/package-lock.json b/package-lock.json index 90fac43..cc3b16e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,8 +9,9 @@ "version": "1.0.0", "license": "ISC", "dependencies": { + "cloudinary": "^1.41.3", "connect-mongo": "^5.1.0", - "dotenv": "^16.4.5", + "dotenv": "^16.6.1", "ejs": "^3.1.10", "express": "^4.19.2", "express-ejs-layouts": "^2.5.1", @@ -18,6 +19,8 @@ "method-override": "^3.0.0", "mongodb": "^6.5.0", "mongoose": "^8.10.0", + "multer": "^2.0.1", + "multer-storage-cloudinary": "^4.0.0", "passport": "^0.7.0", "passport-google-oauth20": "^2.0.0" }, @@ -91,6 +94,12 @@ "node": ">= 8" } }, + "node_modules/append-field": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", + "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==", + "license": "MIT" + }, "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", @@ -207,6 +216,23 @@ "node": ">=16.20.1" } }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "license": "MIT" + }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -272,6 +298,30 @@ "fsevents": "~2.3.2" } }, + "node_modules/cloudinary": { + "version": "1.41.3", + "resolved": "https://registry.npmjs.org/cloudinary/-/cloudinary-1.41.3.tgz", + "integrity": "sha512-4o84y+E7dbif3lMns+p3UW6w6hLHEifbX/7zBJvaih1E9QNMZITENQ14GPYJC4JmhygYXsuuBb9bRA3xWEoOfg==", + "license": "MIT", + "dependencies": { + "cloudinary-core": "^2.13.0", + "core-js": "^3.30.1", + "lodash": "^4.17.21", + "q": "^1.5.1" + }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/cloudinary-core": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/cloudinary-core/-/cloudinary-core-2.13.1.tgz", + "integrity": "sha512-z53GPNWnvU0Zi+ns8CIVbZBfj7ps/++zDvwIyiFuq5p1MoK+KUCg0k5mBceDDHTnx1gHmHUd9aohS+gDxPNt6w==", + "license": "MIT", + "peerDependencies": { + "lodash": ">=4.0" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -293,6 +343,21 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, + "node_modules/concat-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "engines": [ + "node >= 6.0" + ], + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" + } + }, "node_modules/connect-mongo": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/connect-mongo/-/connect-mongo-5.1.0.tgz", @@ -341,6 +406,17 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, + "node_modules/core-js": { + "version": "3.43.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.43.0.tgz", + "integrity": "sha512-N6wEbTTZSYOY2rYAn85CuvWWkCK6QweMn7/4Nr3w+gDBeBhk/x4EJeY6FPo4QzDoJZxVTv8U7CMvgWk6pOHHqA==", + "hasInstallScript": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -391,9 +467,10 @@ } }, "node_modules/dotenv": { - "version": "16.4.5", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", - "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "license": "BSD-2-Clause", "engines": { "node": ">=12" }, @@ -878,6 +955,12 @@ "node": ">8" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -989,6 +1072,27 @@ "node": "*" } }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "license": "MIT", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, "node_modules/mongodb": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.13.0.tgz", @@ -1093,6 +1197,33 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, + "node_modules/multer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/multer/-/multer-2.0.1.tgz", + "integrity": "sha512-Ug8bXeTIUlxurg8xLTEskKShvcKDZALo1THEX5E41pYCD2sCVub5/kIRIGqWNoqV6szyLyQKV6mD4QUrWE5GCQ==", + "license": "MIT", + "dependencies": { + "append-field": "^1.0.0", + "busboy": "^1.6.0", + "concat-stream": "^2.0.0", + "mkdirp": "^0.5.6", + "object-assign": "^4.1.1", + "type-is": "^1.6.18", + "xtend": "^4.0.2" + }, + "engines": { + "node": ">= 10.16.0" + } + }, + "node_modules/multer-storage-cloudinary": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/multer-storage-cloudinary/-/multer-storage-cloudinary-4.0.0.tgz", + "integrity": "sha512-25lm9R6o5dWrHLqLvygNX+kBOxprzpmZdnVKH4+r68WcfCt8XV6xfQaMuAg+kUE5Xmr8mJNA4gE0AcBj9FJyWA==", + "license": "MIT", + "peerDependencies": { + "cloudinary": "^1.21.0" + } + }, "node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", @@ -1179,6 +1310,15 @@ "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.10.0.tgz", "integrity": "sha512-1orQ9MT1vHFGQxhuy7E/0gECD3fd2fCC+PIX+/jgmU/gI3EpRocXtmtvxCO5x3WZ443FLTLFWNDjl5MPJf9u+Q==" }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/object-inspect": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", @@ -1317,6 +1457,17 @@ "node": ">=6" } }, + "node_modules/q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", + "deprecated": "You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other.\n\n(For a CapTP with native promises, see @endo/eventual-send and @endo/captp)", + "license": "MIT", + "engines": { + "node": ">=0.6.0", + "teleport": ">=0.2.0" + } + }, "node_modules/qs": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", @@ -1361,6 +1512,20 @@ "node": ">= 0.8" } }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -1538,6 +1703,23 @@ "node": ">= 0.8" } }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -1604,6 +1786,12 @@ "node": ">= 0.6" } }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "license": "MIT" + }, "node_modules/uid-safe": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", @@ -1634,6 +1822,12 @@ "node": ">= 0.8" } }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", @@ -1670,6 +1864,15 @@ "node": ">=16" } }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", diff --git a/package.json b/package.json index 421cec4..c0aca3a 100644 --- a/package.json +++ b/package.json @@ -11,8 +11,9 @@ "author": "", "license": "ISC", "dependencies": { + "cloudinary": "^1.41.3", "connect-mongo": "^5.1.0", - "dotenv": "^16.4.5", + "dotenv": "^16.6.1", "ejs": "^3.1.10", "express": "^4.19.2", "express-ejs-layouts": "^2.5.1", @@ -20,6 +21,8 @@ "method-override": "^3.0.0", "mongodb": "^6.5.0", "mongoose": "^8.10.0", + "multer": "^2.0.1", + "multer-storage-cloudinary": "^4.0.0", "passport": "^0.7.0", "passport-google-oauth20": "^2.0.0" }, diff --git a/public/css/main.css b/public/css/main.css index fa29670..21ec4e1 100644 --- a/public/css/main.css +++ b/public/css/main.css @@ -87,4 +87,15 @@ h1,h2,h3,h4,h5,h6{ position: absolute; right: -50px; bottom: -30px; +} + +/* Note image previews */ +#imagePreview img, .note-image { + border: 1px solid #ccc; + border-radius: 8px; + margin-right: 8px; + margin-bottom: 8px; + max-width: 120px; + max-height: 120px; + object-fit: cover; } \ No newline at end of file diff --git a/server/config/cloudinary.js b/server/config/cloudinary.js new file mode 100644 index 0000000..234f131 --- /dev/null +++ b/server/config/cloudinary.js @@ -0,0 +1,9 @@ +const cloudinary = require('cloudinary').v2; + +cloudinary.config({ + cloud_name: process.env.CLOUDINARY_CLOUD_NAME, + api_key: process.env.CLOUDINARY_API_KEY, + api_secret: process.env.CLOUDINARY_API_SECRET, +}); + +module.exports = cloudinary; \ No newline at end of file diff --git a/server/config/db.js b/server/config/db.js index 15ce26e..767d337 100644 --- a/server/config/db.js +++ b/server/config/db.js @@ -9,4 +9,6 @@ const connectDB = async() => { console.log(error); } } -module.exports = connectDB; \ No newline at end of file +module.exports = connectDB; + +// Make sure to load environment variables for Cloudinary in your main app entry point (app.js) \ No newline at end of file diff --git a/server/controllers/dashboardController.js b/server/controllers/dashboardController.js index 91d7b99..201db7e 100644 --- a/server/controllers/dashboardController.js +++ b/server/controllers/dashboardController.js @@ -23,8 +23,10 @@ exports.dashboard = async (req, res) => { { $match: { user: new mongoose.Types.ObjectId(req.user.id) } }, { $project: { + _id: 1, title: { $substr: ["$title", 0, 30] }, body: { $substr: ["$body", 0, 100] }, + images: 1 }, }, ]) @@ -77,9 +79,20 @@ exports.dashboardViewNote = async(req,res) => { exports.dashboardUpdateNote = async(req,res) => { try { + let images = []; + if (req.body.imageUrls) { + try { + images = JSON.parse(req.body.imageUrls); + } catch (e) { images = []; } + } await Note.findOneAndUpdate( {_id: req.params.id}, - {title: req.body.title , body: req.body.body , updatedAt: Date.now() } + { + title: req.body.title, + body: req.body.body, + images: images, + updatedAt: Date.now() + } ).where({ user: req.user.id }); res.redirect('/dashboard'); } catch (error) { @@ -124,6 +137,7 @@ exports.dashboardAddNote = async(req,res) => { exports.dashboardAddNote = async(req,res) => { try { + console.log('Received body:', req.body); if (!req.body.title || req.body.title.trim() === "") { return res.render('dashboard/add', { layout: '../views/layouts/dashboard', @@ -132,9 +146,21 @@ exports.dashboardAddNote = async(req,res) => { }); } req.body.user = req.user.id; - await Note.create(req.body); + let images = []; + if (req.body.imageUrls) { + try { + images = JSON.parse(req.body.imageUrls); + } catch (e) { images = []; } + } + await Note.create({ + user: req.body.user, + title: req.body.title, + body: req.body.body, + images: images + }); res.redirect('/dashboard'); } catch (error) { + console.log('Error saving note:', error); let errorMsg = 'An error occurred while adding the note.'; if (error.name === 'ValidationError') { errorMsg = error.message; diff --git a/server/controllers/imageUploadController.js b/server/controllers/imageUploadController.js new file mode 100644 index 0000000..28b93a9 --- /dev/null +++ b/server/controllers/imageUploadController.js @@ -0,0 +1,27 @@ +const cloudinary = require('../config/cloudinary'); +const multer = require('multer'); +const { CloudinaryStorage } = require('multer-storage-cloudinary'); + +// Configure storage +const storage = new CloudinaryStorage({ + cloudinary: cloudinary, + params: { + folder: 'notesapp', + allowed_formats: ['jpg', 'jpeg', 'png', 'gif'], + }, +}); + +const upload = multer({ storage: storage }); + +// Middleware to use in routes +exports.uploadImage = upload.array('images', 5); // up to 5 images per note + +// Route handler +exports.handleUpload = (req, res) => { + try { + const imageUrls = req.files.map(file => file.path); + res.json({ imageUrls }); + } catch (err) { + res.status(500).json({ error: 'Image upload failed' }); + } +}; \ No newline at end of file diff --git a/server/models/Notes.js b/server/models/Notes.js index 7ad064a..8245787 100644 --- a/server/models/Notes.js +++ b/server/models/Notes.js @@ -14,6 +14,9 @@ const NoteSchema = new schema({ type:String, required:true, }, + images: [{ + type: String + }], createdAt:{ type:Date, default: Date.now() diff --git a/server/routes/dashboard.js b/server/routes/dashboard.js index f233bfd..1391ce4 100644 --- a/server/routes/dashboard.js +++ b/server/routes/dashboard.js @@ -2,6 +2,9 @@ const express = require('express'); const router = express.Router(); const { isLoggedIn } = require('../middleware/checkAuth'); const dashboardController = require('../controllers/dashboardController'); +const imageUploadController = require('../controllers/imageUploadController'); +const multer = require('multer'); +const upload = multer(); /** * dashboard routes @@ -11,9 +14,11 @@ router.get('/dashboard/item/:id',isLoggedIn, dashboardController.dashboardViewNo router.put('/dashboard/item/:id',isLoggedIn, dashboardController.dashboardUpdateNote); router.delete('/dashboard/item-delete/:id',isLoggedIn, dashboardController.dashboardDeleteNote); router.get('/dashboard/add',isLoggedIn, dashboardController.dashboardAddNote); -router.post('/dashboard/add',isLoggedIn, dashboardController.dashboardAddNote); +router.post('/dashboard/add',isLoggedIn, upload.none(), dashboardController.dashboardAddNote); router.get('/dashboard/search',isLoggedIn, dashboardController.dashboardSearch); router.post('/dashboard/search',isLoggedIn, dashboardController.dashboardSearchSubmit); +// Image upload route +router.post('/dashboard/upload-image', isLoggedIn, imageUploadController.uploadImage, imageUploadController.handleUpload); module.exports = router; \ No newline at end of file diff --git a/views/dashboard/add.ejs b/views/dashboard/add.ejs index 658b42a..d7f634a 100644 --- a/views/dashboard/add.ejs +++ b/views/dashboard/add.ejs @@ -25,16 +25,24 @@
<%= error %>
<% } %> -
+
-
+
+ +
+ Drag & drop images here or click to select + +
+
+
+
@@ -42,4 +50,80 @@ + + diff --git a/views/dashboard/index.ejs b/views/dashboard/index.ejs index 37b4e88..c48e2a3 100644 --- a/views/dashboard/index.ejs +++ b/views/dashboard/index.ejs @@ -14,10 +14,18 @@ diff --git a/views/dashboard/view-notes.ejs b/views/dashboard/view-notes.ejs index c5543cd..bdca0a5 100644 --- a/views/dashboard/view-notes.ejs +++ b/views/dashboard/view-notes.ejs @@ -1,44 +1,61 @@ -
- +
-
- - -
-

View Note

- - -
+
+

View Note

+ +
-
- - -
- -
- - -
- -
- -
- +
+
+
+
+ +
+ +
+
+ +
+ <% if (note.images && note.images.length > 0) { %> + <% note.images.forEach(function(url, idx) { %> +
+ Note Image + +
+ <% }); %> + <% } %> +
+
+
+ +
+ Drag & drop images here or click to select + +
+
+
+ +
+ +
+
+ +
+ +
+
- - +
@@ -68,4 +85,90 @@
- \ No newline at end of file + + + \ No newline at end of file