From e67362604e5b1d1179f846c50b9d39c41c525169 Mon Sep 17 00:00:00 2001 From: saif-elhady Date: Sun, 19 May 2024 21:43:21 +0300 Subject: [PATCH 1/4] full project --- .gitignore | 3 +- app.js | 9 ++ controllers/urlController.js | 41 ++++++ models/url.js | 10 ++ package-lock.json | 255 ++++++++++++++++++++++++++++++++++- package.json | 5 +- routes/index.js | 8 +- views/index.ejs | 45 +++++-- 8 files changed, 358 insertions(+), 18 deletions(-) create mode 100644 controllers/urlController.js create mode 100644 models/url.js diff --git a/.gitignore b/.gitignore index 40b878d..d16f63d 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -node_modules/ \ No newline at end of file +node_modules/ +.env \ No newline at end of file diff --git a/app.js b/app.js index 04be2f9..c3fe35c 100644 --- a/app.js +++ b/app.js @@ -1,13 +1,21 @@ const createError = require('http-errors'); const express = require('express'); +const mongoose = require('mongoose'); const path = require('path'); const cookieParser = require('cookie-parser'); const logger = require('morgan'); +require('dotenv').config(); const indexRouter = require('./routes/index'); const app = express(); +//connect to mongoDB +const dbURI = process.env.DB_URI; +mongoose.connect(dbURI) + .then((result) => app.listen(3000)) + .catch((err) => console.log(err)); + // view engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'ejs'); @@ -20,6 +28,7 @@ app.use(express.static(path.join(__dirname, 'public'))); app.use('/', indexRouter); + // catch 404 and forward to error handler app.use(function (req, res, next) { next(createError(404)); diff --git a/controllers/urlController.js b/controllers/urlController.js new file mode 100644 index 0000000..aeec010 --- /dev/null +++ b/controllers/urlController.js @@ -0,0 +1,41 @@ +const URL = require('../models/url'); + +const getHome = (req, res) => { + URL.find() + .then((urls) => { + res.render('index', { title: 'urlShortner', urls }); + }) + .catch((err) => { + res.render('error', { message: "Failed to load home page", error: err } ); + }) +}; + +const urlPost = (req, res) => { + const long = req.body.urlInput; + const alias = req.body.aliasInput; + const url = new URL({ long, alias}); + url.save() + .then(() => { + res.redirect('/'); + console.log('a new link added') + }) + .catch((err) => { + res.render('error', { message: "Failed to load home page", error: err }); + }) +} + +const urlDelete = (req, res) => { + const id = req.params.id; + URL.findByIdAndDelete(id) + .then(result => { + res.json({ redirect: '/'}) + }) + .catch((err) => { + res.render('error', { message: "Failed to load home page", error: err }); }) + } + +module.exports = { + getHome, + urlPost, + urlDelete +} \ No newline at end of file diff --git a/models/url.js b/models/url.js new file mode 100644 index 0000000..43c3e22 --- /dev/null +++ b/models/url.js @@ -0,0 +1,10 @@ +const mongoose = require('mongoose'); +const Schema = mongoose.Schema; + +const urlSchema = new Schema({ + long: { type: String, required: true }, + alias: { type: String, required: true } +}, { timestamps: true }) + +const URL = mongoose.model('URL', urlSchema); +module.exports = URL; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 6fd9de3..b32cc42 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,15 +10,39 @@ "dependencies": { "cookie-parser": "~1.4.4", "debug": "~2.6.9", + "dotenv": "^16.4.5", "ejs": "^3.1.9", "express": "^4.18.2", "http-errors": "~1.6.3", - "morgan": "~1.9.1" + "mongoose": "^8.4.0", + "morgan": "~1.9.1", + "path": "^0.12.7" }, "devDependencies": { "nodemon": "^3.0.1" } }, + "node_modules/@mongodb-js/saslprep": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.7.tgz", + "integrity": "sha512-dCHW/oEX0KJ4NjDULBo3JiOaK5+6axtpBbS+ao2ZInoAL9/YRQLhXzSNAFz7hP4nzLkIqsfYAK/PDE3+XHny0Q==", + "dependencies": { + "sparse-bitfield": "^3.0.3" + } + }, + "node_modules/@types/webidl-conversions": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", + "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==" + }, + "node_modules/@types/whatwg-url": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.5.tgz", + "integrity": "sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==", + "dependencies": { + "@types/webidl-conversions": "*" + } + }, "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -195,6 +219,14 @@ "node": ">=8" } }, + "node_modules/bson": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-6.7.0.tgz", + "integrity": "sha512-w2IquM5mYzYZv6rs3uN2DZTOBe2a0zXLj53TGDqwF4l6Sz/XsISrisXOJihArF9+BZ6Cq/GjVht7Sjfmri7ytQ==", + "engines": { + "node": ">=16.20.1" + } + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -385,6 +417,17 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -823,6 +866,14 @@ "node": ">=10" } }, + "node_modules/kareem": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.6.3.tgz", + "integrity": "sha512-C3iHfuGUXK2u8/ipq9LfjFfXFxAZMQJJq7vLS45r3D9Y2xQ/m4S8zaR4zMLFWh9AsNPXmcFfUDhTEO8UIC/V6Q==", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -843,6 +894,11 @@ "node": ">= 0.6" } }, + "node_modules/memory-pager": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==" + }, "node_modules/merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", @@ -897,6 +953,86 @@ "node": "*" } }, + "node_modules/mongodb": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.6.2.tgz", + "integrity": "sha512-ZF9Ugo2JCG/GfR7DEb4ypfyJJyiKbg5qBYKRintebj8+DNS33CyGMkWbrS9lara+u+h+yEOGSRiLhFO/g1s1aw==", + "dependencies": { + "@mongodb-js/saslprep": "^1.1.5", + "bson": "^6.7.0", + "mongodb-connection-string-url": "^3.0.0" + }, + "engines": { + "node": ">=16.20.1" + }, + "peerDependencies": { + "@aws-sdk/credential-providers": "^3.188.0", + "@mongodb-js/zstd": "^1.1.0", + "gcp-metadata": "^5.2.0", + "kerberos": "^2.0.1", + "mongodb-client-encryption": ">=6.0.0 <7", + "snappy": "^7.2.2", + "socks": "^2.7.1" + }, + "peerDependenciesMeta": { + "@aws-sdk/credential-providers": { + "optional": true + }, + "@mongodb-js/zstd": { + "optional": true + }, + "gcp-metadata": { + "optional": true + }, + "kerberos": { + "optional": true + }, + "mongodb-client-encryption": { + "optional": true + }, + "snappy": { + "optional": true + }, + "socks": { + "optional": true + } + } + }, + "node_modules/mongodb-connection-string-url": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.1.tgz", + "integrity": "sha512-XqMGwRX0Lgn05TDB4PyG2h2kKO/FfWJyCzYQbIhXUxz7ETt0I/FqHjUeqj37irJ+Dl1ZtU82uYyj14u2XsZKfg==", + "dependencies": { + "@types/whatwg-url": "^11.0.2", + "whatwg-url": "^13.0.0" + } + }, + "node_modules/mongoose": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.4.0.tgz", + "integrity": "sha512-fgqRMwVEP1qgRYfh+tUe2YBBFnPO35FIg2lfFH+w9IhRGg1/ataWGIqvf/MjwM29cZ60D5vSnqtN2b8Qp0sOZA==", + "dependencies": { + "bson": "^6.7.0", + "kareem": "2.6.3", + "mongodb": "6.6.2", + "mpath": "0.9.0", + "mquery": "5.0.0", + "ms": "2.1.3", + "sift": "17.1.3" + }, + "engines": { + "node": ">=16.20.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mongoose" + } + }, + "node_modules/mongoose/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, "node_modules/morgan": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz", @@ -912,6 +1048,46 @@ "node": ">= 0.8.0" } }, + "node_modules/mpath": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", + "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mquery": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-5.0.0.tgz", + "integrity": "sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==", + "dependencies": { + "debug": "4.x" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/mquery/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/mquery/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, "node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -1027,6 +1203,15 @@ "node": ">= 0.8" } }, + "node_modules/path": { + "version": "0.12.7", + "resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz", + "integrity": "sha512-aXXC6s+1w7otVF9UletFkFcDsJeO7lSZBPUQhtb5O0xJe8LtYhj/GxldoL09bBj9+ZmE2hNoHqQSFMN5fikh4Q==", + "dependencies": { + "process": "^0.11.1", + "util": "^0.10.3" + } + }, "node_modules/path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", @@ -1044,6 +1229,14 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -1062,6 +1255,14 @@ "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", "dev": true }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "engines": { + "node": ">=6" + } + }, "node_modules/qs": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", @@ -1288,6 +1489,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/sift": { + "version": "17.1.3", + "resolved": "https://registry.npmjs.org/sift/-/sift-17.1.3.tgz", + "integrity": "sha512-Rtlj66/b0ICeFzYTuNvX/EF1igRbbnGSvEyT79McoZa/DeGhMyC5pWKOEsZKnpkqtSeovd5FL/bjHWC3CIIvCQ==" + }, "node_modules/simple-update-notifier": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", @@ -1300,6 +1506,14 @@ "node": ">=10" } }, + "node_modules/sparse-bitfield": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "dependencies": { + "memory-pager": "^1.0.2" + } + }, "node_modules/statuses": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", @@ -1352,6 +1566,17 @@ "nodetouch": "bin/nodetouch.js" } }, + "node_modules/tr46": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", + "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", + "dependencies": { + "punycode": "^2.3.0" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -1378,6 +1603,14 @@ "node": ">= 0.8" } }, + "node_modules/util": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", + "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", + "dependencies": { + "inherits": "2.0.3" + } + }, "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", @@ -1394,6 +1627,26 @@ "node": ">= 0.8" } }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-url": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-13.0.0.tgz", + "integrity": "sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==", + "dependencies": { + "tr46": "^4.1.1", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=16" + } + }, "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 4c3762d..dba4981 100644 --- a/package.json +++ b/package.json @@ -8,10 +8,13 @@ "dependencies": { "cookie-parser": "~1.4.4", "debug": "~2.6.9", + "dotenv": "^16.4.5", "ejs": "^3.1.9", "express": "^4.18.2", "http-errors": "~1.6.3", - "morgan": "~1.9.1" + "mongoose": "^8.4.0", + "morgan": "~1.9.1", + "path": "^0.12.7" }, "devDependencies": { "nodemon": "^3.0.1" diff --git a/routes/index.js b/routes/index.js index 5890929..86529ee 100644 --- a/routes/index.js +++ b/routes/index.js @@ -1,8 +1,10 @@ const router = require('express').Router(); +const urlController = require ('../controllers/urlController') /* GET home page. */ -router.get('/', function (req, res, next) { - res.render('index', { title: 'Express' }); -}); +router.get('/', urlController.getHome); +router.post('/', urlController.urlPost); +router.delete('/:id', urlController.urlDelete); module.exports = router; + diff --git a/views/index.ejs b/views/index.ejs index 70b7faa..c3703d2 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -47,6 +47,7 @@ padding: 8px; text-align: left; border-bottom: 1px solid #ddd; + } th { @@ -74,21 +75,41 @@ Original URL Shortened URL + - - https://github.com/cat-backend-nodejs/nodejs-roadmap - http://localhost:3000/nodejs - - - https://stackoverflow.com/users/11936196/seif-el-din-sweilam - http://localhost:3000/stackoverflow - - - https://drive.google.com/drive/u/1/folders/1bpiBKNBd9n0Z79wrZvHVT1KyA9OBROLx - http://localhost:3000/himym - + <% if (urls.length> 0) { %> + <% urls.forEach((url)=>{ %> + + + <%=url.long%> + + + + + <%=url.alias%> + + + Delete + + <%})%> + <%}%> + \ No newline at end of file From 99368e90991bf75d19158cefca9fb31e9dd792bc Mon Sep 17 00:00:00 2001 From: saif-elhady Date: Fri, 24 May 2024 14:17:22 +0300 Subject: [PATCH 2/4] adding a redirect handler method --- controllers/urlController.js | 18 +++++++++++++++++- routes/index.js | 1 + 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/controllers/urlController.js b/controllers/urlController.js index aeec010..b2b0035 100644 --- a/controllers/urlController.js +++ b/controllers/urlController.js @@ -23,6 +23,21 @@ const urlPost = (req, res) => { res.render('error', { message: "Failed to load home page", error: err }); }) } +const urlRedirect = (req, res) => { + const alias = req.params.alias; + URL.findOne({ alias }) + .then((url) => { + if (url) { + res.redirect(url.long); + } + else { + res.render('error', { message: "Failed to load home page", error: err }); + } + }) + .catch((err) => { + res.render('error', { message: "Failed to load home page", error: err }); + }) +} const urlDelete = (req, res) => { const id = req.params.id; @@ -37,5 +52,6 @@ const urlDelete = (req, res) => { module.exports = { getHome, urlPost, - urlDelete + urlDelete, + urlRedirect, } \ No newline at end of file diff --git a/routes/index.js b/routes/index.js index 86529ee..1e2c167 100644 --- a/routes/index.js +++ b/routes/index.js @@ -5,6 +5,7 @@ const urlController = require ('../controllers/urlController') router.get('/', urlController.getHome); router.post('/', urlController.urlPost); router.delete('/:id', urlController.urlDelete); +router.get('/:alias', urlController.urlRedirect); module.exports = router; From a5cff5188cb1ace7c39166f5b4ee766f399bda86 Mon Sep 17 00:00:00 2001 From: saif-elhady Date: Fri, 24 May 2024 15:14:18 +0300 Subject: [PATCH 3/4] fixing redirection bug --- controllers/urlController.js | 6 +++--- routes/index.js | 3 ++- views/index.ejs | 5 ++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/controllers/urlController.js b/controllers/urlController.js index b2b0035..162e21a 100644 --- a/controllers/urlController.js +++ b/controllers/urlController.js @@ -28,14 +28,14 @@ const urlRedirect = (req, res) => { URL.findOne({ alias }) .then((url) => { if (url) { - res.redirect(url.long); + res.redirect(`${url.long}`); } else { - res.render('error', { message: "Failed to load home page", error: err }); + res.render('error', { message: "Invalid alias", error: err }); } }) .catch((err) => { - res.render('error', { message: "Failed to load home page", error: err }); + res.render('error', { message: "Failed to redirect", error: err }); }) } diff --git a/routes/index.js b/routes/index.js index 1e2c167..0757748 100644 --- a/routes/index.js +++ b/routes/index.js @@ -4,8 +4,9 @@ const urlController = require ('../controllers/urlController') /* GET home page. */ router.get('/', urlController.getHome); router.post('/', urlController.urlPost); -router.delete('/:id', urlController.urlDelete); router.get('/:alias', urlController.urlRedirect); +router.delete('/:id', urlController.urlDelete); + module.exports = router; diff --git a/views/index.ejs b/views/index.ejs index c3703d2..d48eda4 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -85,9 +85,8 @@ - - <%=url.alias%> - + + http://localhost:3000/<%=url.alias%> Delete From 6b35b3a6caa04244bdcbb9f4e908544926b8c8cc Mon Sep 17 00:00:00 2001 From: Saif Elhady <45790420+saif-elhady@users.noreply.github.com> Date: Fri, 7 Jun 2024 03:16:13 +0300 Subject: [PATCH 4/4] Update README.md --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 595dc02..cf584e8 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,9 @@ Fork this repository and use the given files to start with. ## Idea A URL shortener website is a service that converts long website addresses into shorter, more manageable links. Users input a lengthy URL, and the website generates a condensed version, making it easier to share and remember. - +## Demo +[Demo]: https://url-shortener-7eyn.onrender.com +[Demo][Demo] ## Interface The application interface consists of one page which contains: @@ -43,4 +45,4 @@ http://localhost:3000/{alias} * Project Completeness (25 pts.) * Clean Code and Modulation (15 pts.) * Descriptive Git Commit Messages (10 pts.) -* Nice touches (5 pts. bonus) \ No newline at end of file +* Nice touches (5 pts. bonus)