├── views ├── 404.ejs ├── about.ejs ├── partials │ ├── sidebar.ejs │ └── header.ejs ├── layouts │ └── main.ejs ├── search.ejs ├── customer │ ├── add.ejs │ ├── view.ejs │ └── edit.ejs └── index.ejs ├── public ├── img │ └── picture.webp └── css │ └── main.css ├── server ├── config │ └── db.js ├── models │ └── Customer.js ├── routes │ └── customer.js └── controllers │ └── customerController.js ├── package.json ├── README.md ├── LICENSE ├── app.js ├── .gitignore └── dummyData.txt /views/404.ejs: -------------------------------------------------------------------------------- 1 |

404

-------------------------------------------------------------------------------- /public/img/picture.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RaddyTheBrand/Nodejs-User-Management-Express-EJS-MongoDB/HEAD/public/img/picture.webp -------------------------------------------------------------------------------- /server/config/db.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | const connectDB = async()=> { 3 | try { 4 | mongoose.set('strictQuery', false); 5 | const conn = await mongoose.connect(process.env.MONGODB_URI); 6 | console.log(`Database Connected: ${conn.connection.host}`); 7 | } catch (error) { 8 | console.log(error); 9 | } 10 | } 11 | 12 | 13 | 14 | module.exports = connectDB; 15 | 16 | -------------------------------------------------------------------------------- /views/about.ejs: -------------------------------------------------------------------------------- 1 |
2 |

About

3 |
4 | 5 | Laptop 6 |

Photo by Garrett Sears on Unsplash

7 | 8 |
9 |

This is a simple user management system developed as part of a YouTube tutorial.

10 |

Check out my YouTube Channel and support by subscribing!

11 |
12 | -------------------------------------------------------------------------------- /views/partials/sidebar.ejs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nodejs_user_management", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "nodemon app.js" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "connect-flash": "^0.1.1", 15 | "dotenv": "^16.0.3", 16 | "ejs": "^3.1.8", 17 | "express": "^4.18.2", 18 | "express-ejs-layouts": "^2.5.1", 19 | "express-session": "^1.17.3", 20 | "method-override": "^3.0.0", 21 | "mongoose": "^7.0.0" 22 | }, 23 | "devDependencies": { 24 | "nodemon": "^2.0.21" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /server/models/Customer.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | 3 | const Schema = mongoose.Schema; 4 | const CustomerSchema = new Schema({ 5 | firstName: { 6 | type: String, 7 | required: true 8 | }, 9 | lastName: { 10 | type: String, 11 | required: true 12 | }, 13 | tel: { 14 | type: String, 15 | required: true 16 | }, 17 | email: { 18 | type: String, 19 | required: true 20 | }, 21 | details: { 22 | type: String, 23 | required: true 24 | }, 25 | createdAt: { 26 | type: Date, 27 | default: Date.now() 28 | }, 29 | updatedAt: { 30 | type: Date, 31 | default: Date.now() 32 | } 33 | }); 34 | 35 | module.exports = mongoose.model('Customer', CustomerSchema); -------------------------------------------------------------------------------- /server/routes/customer.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const customerController = require('../controllers/customerController'); 4 | 5 | /** 6 | * Customer Routes 7 | */ 8 | router.get('/', customerController.homepage); 9 | router.get('/about', customerController.about); 10 | router.get('/add', customerController.addCustomer); 11 | router.post('/add', customerController.postCustomer); 12 | router.get('/view/:id', customerController.view); 13 | router.get('/edit/:id', customerController.edit); 14 | router.put('/edit/:id', customerController.editPost); 15 | router.delete('/edit/:id', customerController.deleteCustomer); 16 | 17 | router.post('/search', customerController.searchCustomers); 18 | 19 | 20 | 21 | module.exports = router; -------------------------------------------------------------------------------- /views/partials/header.ejs: -------------------------------------------------------------------------------- 1 | 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Nodejs User Management Express EJS MongoDB 2 | 3 | ## Udates 4 | 5 | 6 | ## You need: 7 | - Database (MongoDB) Free 8 | 9 | ## Create .env file 10 | Create a .env file to store your credentials. Example below: 11 | 12 | ``` 13 | MONGODB_URI = mongodb+srv://:@mongodburlhere 14 | ``` 15 | 16 | ## Installation 17 | To install and run this project - install dependencies using npm and then start your server: 18 | 19 | ``` 20 | $ npm install 21 | $ npm start 22 | ``` 23 | 24 | ### YouTube Video & Article 25 | 26 | [YouTube Video](https://youtu.be/) 27 | 28 | [Read Article](https://raddy.dev/blog/) 29 | 30 | ### YouTube Channel - Raddy 31 | 32 | [Subscribe to my YouTube Channel](https://www.youtube.com/channel/UCvXscyQ0cLzPZeNOeXI45Sw?sub_confirmation=1) 33 | 34 | ### Website 35 | [www.raddy.dev](https://www.raddy.dev) 36 | 37 | ### Donations 38 | [Buy me a Coffee](https://www.buymeacoffee.com/RaddyTheBrand) 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Raddy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /views/layouts/main.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | <%= locals.title %> 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | <%- include('../partials/header.ejs') %> 16 | 17 |
18 |
19 | <%- include('../partials/sidebar.ejs') %> 20 | 21 |
22 | <%- body %> 23 |
24 | 25 |
26 |
27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | require('dotenv').config(); 2 | 3 | const express = require('express'); 4 | const expressLayout = require('express-ejs-layouts'); 5 | const methodOverride = require('method-override'); 6 | 7 | // npm uninstall express-flash-message 8 | //const { flash } = require('express-flash-message'); 9 | 10 | // npm install connect-flash 11 | const flash = require('connect-flash'); 12 | 13 | const session = require('express-session'); 14 | const connectDB = require('./server/config/db'); 15 | 16 | const app = express(); 17 | const port = process.env.PORT || 5000; 18 | 19 | // Connect to Database 20 | connectDB(); 21 | 22 | app.use(express.urlencoded({ extended: true })); 23 | app.use(express.json()); 24 | app.use(methodOverride('_method')); 25 | 26 | // Static Files 27 | app.use(express.static('public')); 28 | 29 | // Express Session 30 | app.use( 31 | session({ 32 | secret: 'secret', 33 | resave: false, 34 | saveUninitialized: true, 35 | cookie: { 36 | maxAge: 1000 * 60 * 60 * 24 * 7, // 1 week 37 | } 38 | }) 39 | ); 40 | 41 | // Flash Messages 42 | app.use(flash({ sessionKeyName: 'flashMessage' })); 43 | 44 | // Templating Engine 45 | app.use(expressLayout); 46 | app.set('layout', './layouts/main'); 47 | app.set('view engine', 'ejs'); 48 | 49 | // Routes 50 | app.use('/', require('./server/routes/customer')) 51 | 52 | // Handle 404 53 | app.get('*', (req, res) => { 54 | res.status(404).render('404'); 55 | }); 56 | 57 | app.listen(port, ()=> { 58 | console.log(`App listeing on port ${port}`) 59 | }); 60 | -------------------------------------------------------------------------------- /public/css/main.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-size: .875rem; 3 | } 4 | 5 | .feather { 6 | width: 16px; 7 | height: 16px; 8 | } 9 | 10 | /* 11 | * Sidebar 12 | */ 13 | 14 | .sidebar { 15 | position: fixed; 16 | top: 0; 17 | /* rtl:raw: 18 | right: 0; 19 | */ 20 | bottom: 0; 21 | /* rtl:remove */ 22 | left: 0; 23 | z-index: 100; /* Behind the navbar */ 24 | padding: 48px 0 0; /* Height of navbar */ 25 | box-shadow: inset -1px 0 0 rgba(0, 0, 0, .1); 26 | } 27 | 28 | @media (max-width: 767.98px) { 29 | .sidebar { 30 | top: 5rem; 31 | } 32 | } 33 | 34 | .sidebar-sticky { 35 | height: calc(100vh - 48px); 36 | overflow-x: hidden; 37 | overflow-y: auto; /* Scrollable contents if viewport is shorter than content. */ 38 | } 39 | 40 | .sidebar .nav-link { 41 | font-weight: 500; 42 | color: #333; 43 | } 44 | 45 | .sidebar .nav-link .feather { 46 | margin-right: 4px; 47 | color: #727272; 48 | } 49 | 50 | .sidebar .nav-link.active { 51 | color: #2470dc; 52 | } 53 | 54 | .sidebar .nav-link:hover .feather, 55 | .sidebar .nav-link.active .feather { 56 | color: inherit; 57 | } 58 | 59 | .sidebar-heading { 60 | font-size: .75rem; 61 | } 62 | 63 | /* 64 | * Navbar 65 | */ 66 | 67 | .navbar-brand { 68 | padding-top: .75rem; 69 | padding-bottom: .75rem; 70 | background-color: rgba(0, 0, 0, .25); 71 | box-shadow: inset -1px 0 0 rgba(0, 0, 0, .25); 72 | } 73 | 74 | .navbar .navbar-toggler { 75 | top: .25rem; 76 | right: 1rem; 77 | } 78 | 79 | .navbar .form-control { 80 | padding: .75rem 1rem; 81 | } 82 | 83 | .navbar .form-control::placeholder { /* Chrome, Firefox, Opera, Safari 10.1+ */ 84 | color: white; 85 | opacity: 1; /* Firefox */ 86 | } 87 | 88 | .form-control-dark { 89 | color: #fff; 90 | background-color: rgba(255, 255, 255, .1); 91 | border-color: rgba(255, 255, 255, .1); 92 | } 93 | 94 | .form-control-dark:focus { 95 | border-color: transparent; 96 | box-shadow: 0 0 0 3px rgba(255, 255, 255, .25); 97 | } -------------------------------------------------------------------------------- /views/search.ejs: -------------------------------------------------------------------------------- 1 |
2 |

Search

3 |
4 |
5 | + New User 6 |
7 |
8 |
9 | 10 |
11 | <% if (customers != "") { %> 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | <% customers.forEach(element => { %> 25 | 26 | 27 | 28 | 29 | 30 | 51 | 52 | <% }) %> 53 | 54 |
First NameLast NameTelEmail NameAction
<%= element.firstName %><%= element.lastName %><%= element.tel %><%= element.email %> 31 | 32 |
33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 |
43 | 46 |
47 | 48 |
49 | 50 |
55 | 56 | <% } else { %> 57 |

No results found.

58 | <% } %> 59 | 60 |
-------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /views/customer/add.ejs: -------------------------------------------------------------------------------- 1 |
2 |

Customer

3 |
4 |
5 | 6 |
7 |
8 |
9 | 10 |
11 |
12 |
13 | 19 |
20 |
21 | UserId 22 |
23 |
24 | 25 |
26 | 27 | 28 |
29 | 30 |
31 |
32 | 33 | 34 |
35 | 36 |
37 | 38 | 39 |
40 |
41 | 42 |
43 |
44 | 45 | 46 |
47 | 48 |
49 | 50 | 51 |
52 |
53 | 54 | 55 |
56 | 57 | 58 |
59 | 60 |
61 | 62 |
63 | 64 | 65 | 66 |
-------------------------------------------------------------------------------- /views/customer/view.ejs: -------------------------------------------------------------------------------- 1 |
2 |

<%= customer.firstName %> <%= customer.lastName %>

3 |
4 |
5 | 6 | 7 |
8 |
9 |
10 | 11 |
12 | 13 |
14 |
15 | 21 |
22 |
23 | Last Updated <%= new Date(customer.updatedAt).toUTCString() %> 24 | UserId: <%= customer._id %> 25 |
26 |
27 | 28 |
29 | 30 | -------------------------------------------------------------------------------- /views/index.ejs: -------------------------------------------------------------------------------- 1 |
2 |

Dashboard

3 |
4 |
5 | + New User 6 |
7 |
8 |
9 | 10 | <% messages.forEach(element => { %> 11 | 15 | <% }) %> 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | <% customers.forEach(element => { %> 33 | 34 | 35 | 36 | 37 | 59 | 60 | <% }) %> 61 | 62 |
First NameLast NameEmailAction
<%= element.firstName %><%= element.lastName %><%= element.email %> 38 | 39 |
40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 |
50 | 53 |
54 | 55 |
56 | 57 | 58 |
63 |
64 | 65 | 66 | 67 | <% if (customers.length > 0) { %> 68 | 101 | <% } %> 102 | 103 | -------------------------------------------------------------------------------- /views/customer/edit.ejs: -------------------------------------------------------------------------------- 1 |
2 |

Editing: <%= customer.firstName %> <%= customer.lastName %>

3 |
4 |
5 | 6 |
7 |
8 |
9 | 10 |
11 |
12 |
13 | 19 |
20 |
21 | Last Updated: <%= new Date(customer.updatedAt).toUTCString() %> 22 | UserId: <%= customer._id %> 23 |
24 |
25 | 26 |
27 | 28 | 29 |
30 | 31 |
32 |
33 | 34 | 35 |
36 | 37 |
38 | 39 | 40 |
41 |
42 | 43 |
44 |
45 | 46 | 47 |
48 | 49 |
50 | 51 | 52 |
53 |
54 | 55 |
56 | 57 | 58 |
59 | 60 |
61 | 62 | 63 | 64 | 65 |
66 | 67 |
68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /server/controllers/customerController.js: -------------------------------------------------------------------------------- 1 | const Customer = require("../models/Customer"); 2 | const mongoose = require("mongoose"); 3 | 4 | /** 5 | * GET / 6 | * Homepage 7 | */ 8 | exports.homepage = async (req, res) => { 9 | // Remove 10 | // const messages = await req.consumeFlash('info'); 11 | // Use this instead 12 | const messages = await req.flash("info"); 13 | 14 | const locals = { 15 | title: "NodeJs", 16 | description: "Free NodeJs User Management System", 17 | }; 18 | 19 | let perPage = 12; 20 | let page = req.query.page || 1; 21 | 22 | try { 23 | const customers = await Customer.aggregate([{ $sort: { createdAt: -1 } }]) 24 | .skip(perPage * page - perPage) 25 | .limit(perPage) 26 | .exec(); 27 | // Count is deprecated. Use countDocuments({}) or estimatedDocumentCount() 28 | // const count = await Customer.count(); 29 | const count = await Customer.countDocuments({}); 30 | 31 | res.render("index", { 32 | locals, 33 | customers, 34 | current: page, 35 | pages: Math.ceil(count / perPage), 36 | messages, 37 | }); 38 | } catch (error) { 39 | console.log(error); 40 | } 41 | }; 42 | // exports.homepage = async (req, res) => { 43 | // const messages = await req.consumeFlash('info'); 44 | // const locals = { 45 | // title: 'NodeJs', 46 | // description: 'Free NodeJs User Management System' 47 | // } 48 | 49 | // try { 50 | // const customers = await Customer.find({}).limit(22); 51 | // res.render('index', { locals, messages, customers } ); 52 | // } catch (error) { 53 | // console.log(error); 54 | // } 55 | // } 56 | 57 | /** 58 | * GET / 59 | * About 60 | */ 61 | exports.about = async (req, res) => { 62 | const locals = { 63 | title: "About", 64 | description: "Free NodeJs User Management System", 65 | }; 66 | 67 | try { 68 | res.render("about", locals); 69 | } catch (error) { 70 | console.log(error); 71 | } 72 | }; 73 | 74 | /** 75 | * GET / 76 | * New Customer Form 77 | */ 78 | exports.addCustomer = async (req, res) => { 79 | const locals = { 80 | title: "Add New Customer - NodeJs", 81 | description: "Free NodeJs User Management System", 82 | }; 83 | 84 | res.render("customer/add", locals); 85 | }; 86 | 87 | /** 88 | * POST / 89 | * Create New Customer 90 | */ 91 | exports.postCustomer = async (req, res) => { 92 | console.log(req.body); 93 | 94 | const newCustomer = new Customer({ 95 | firstName: req.body.firstName, 96 | lastName: req.body.lastName, 97 | details: req.body.details, 98 | tel: req.body.tel, 99 | email: req.body.email, 100 | }); 101 | 102 | try { 103 | await Customer.create(newCustomer); 104 | await req.flash("info", "New customer has been added."); 105 | 106 | res.redirect("/"); 107 | } catch (error) { 108 | console.log(error); 109 | } 110 | }; 111 | 112 | /** 113 | * GET / 114 | * Customer Data 115 | */ 116 | exports.view = async (req, res) => { 117 | try { 118 | const customer = await Customer.findOne({ _id: req.params.id }); 119 | 120 | const locals = { 121 | title: "View Customer Data", 122 | description: "Free NodeJs User Management System", 123 | }; 124 | 125 | res.render("customer/view", { 126 | locals, 127 | customer, 128 | }); 129 | } catch (error) { 130 | console.log(error); 131 | } 132 | }; 133 | 134 | /** 135 | * GET / 136 | * Edit Customer Data 137 | */ 138 | exports.edit = async (req, res) => { 139 | try { 140 | const customer = await Customer.findOne({ _id: req.params.id }); 141 | 142 | const locals = { 143 | title: "Edit Customer Data", 144 | description: "Free NodeJs User Management System", 145 | }; 146 | 147 | res.render("customer/edit", { 148 | locals, 149 | customer, 150 | }); 151 | } catch (error) { 152 | console.log(error); 153 | } 154 | }; 155 | 156 | /** 157 | * GET / 158 | * Update Customer Data 159 | */ 160 | exports.editPost = async (req, res) => { 161 | try { 162 | await Customer.findByIdAndUpdate(req.params.id, { 163 | firstName: req.body.firstName, 164 | lastName: req.body.lastName, 165 | tel: req.body.tel, 166 | email: req.body.email, 167 | details: req.body.details, 168 | updatedAt: Date.now(), 169 | }); 170 | await res.redirect(`/edit/${req.params.id}`); 171 | 172 | console.log("redirected"); 173 | } catch (error) { 174 | console.log(error); 175 | } 176 | }; 177 | 178 | /** 179 | * Delete / 180 | * Delete Customer Data 181 | */ 182 | exports.deleteCustomer = async (req, res) => { 183 | try { 184 | await Customer.deleteOne({ _id: req.params.id }); 185 | res.redirect("/"); 186 | } catch (error) { 187 | console.log(error); 188 | } 189 | }; 190 | 191 | /** 192 | * Get / 193 | * Search Customer Data 194 | */ 195 | exports.searchCustomers = async (req, res) => { 196 | const locals = { 197 | title: "Search Customer Data", 198 | description: "Free NodeJs User Management System", 199 | }; 200 | 201 | try { 202 | let searchTerm = req.body.searchTerm; 203 | const searchNoSpecialChar = searchTerm.replace(/[^a-zA-Z0-9 ]/g, ""); 204 | 205 | const customers = await Customer.find({ 206 | $or: [ 207 | { firstName: { $regex: new RegExp(searchNoSpecialChar, "i") } }, 208 | { lastName: { $regex: new RegExp(searchNoSpecialChar, "i") } }, 209 | ], 210 | }); 211 | 212 | res.render("search", { 213 | customers, 214 | locals, 215 | }); 216 | } catch (error) { 217 | console.log(error); 218 | } 219 | }; 220 | -------------------------------------------------------------------------------- /dummyData.txt: -------------------------------------------------------------------------------- 1 | *** Website Header - header.ejs 2 | 3 | 12 | 13 | 14 | *** Website Sidebar - sidebar.ejs 15 | 16 | 34 | 35 | 36 | *** Dymmy Data 37 | try { 38 | await Customer.insertMany([ 39 | { 40 | firstName: "Raddy", 41 | lastName: "NodeJs", 42 | tel: "1-353-218-4881", 43 | email: "raddy@outlook.couk", 44 | details: "Demo details text.", 45 | createdAt: Date.now(), 46 | updatedAt: Date.now() 47 | }, 48 | { 49 | firstName: "Aphrodite", 50 | lastName: "Parker", 51 | tel: "1-857-407-8574", 52 | email: "quam@protonmail.net", 53 | details: "Demo details text.", 54 | createdAt: Date.now(), 55 | updatedAt: Date.now() 56 | }, 57 | { 58 | firstName: "Camden", 59 | lastName: "Perce", 60 | tel: "(251) 719-5886", 61 | email: "aliquam.tincidunt.nunc@icloud.net", 62 | details: "Demo details text.", 63 | createdAt: Date.now(), 64 | updatedAt: Date.now() 65 | }, 66 | { 67 | firstName: "Emi", 68 | lastName: "Hutchinson", 69 | tel: "1-878-674-6876", 70 | email: "aenean.egestas@aol.org", 71 | details: "Demo details text.", 72 | createdAt: Date.now(), 73 | updatedAt: Date.now() 74 | }, 75 | { 76 | firstName: "Chaim", 77 | lastName: "Holland", 78 | tel: "1-776-825-8236", 79 | email: "a@google.couk", 80 | details: "Demo details text.", 81 | createdAt: Date.now(), 82 | updatedAt: Date.now() 83 | }, 84 | { 85 | firstName: "Harding", 86 | lastName: "Cameron", 87 | tel: "1-935-750-3637", 88 | email: "non.nisi@outlook.edu", 89 | details: "Demo details text.", 90 | createdAt: Date.now(), 91 | updatedAt: Date.now() 92 | }, 93 | { 94 | firstName: "Dane", 95 | lastName: "Kelley", 96 | tel: "(129) 964-3195", 97 | email: "morbi@aol.org", 98 | details: "Demo details text.", 99 | createdAt: Date.now(), 100 | updatedAt: Date.now() 101 | }, 102 | { 103 | firstName: "Emery", 104 | lastName: "Thornton", 105 | tel: "(565) 248-4784", 106 | email: "egestas.blandit.nam@icloud.org", 107 | details: "Demo details text.", 108 | createdAt: Date.now(), 109 | updatedAt: Date.now() 110 | }, 111 | { 112 | firstName: "Tarik", 113 | lastName: "Francis", 114 | tel: "1-679-436-4746", 115 | email: "lacus@outlook.ca", 116 | details: "Demo details text.", 117 | createdAt: Date.now(), 118 | updatedAt: Date.now() 119 | }, 120 | { 121 | firstName: "Rebecca", 122 | lastName: "Booth", 123 | tel: "1-548-944-3232", 124 | email: "sapien@icloud.couk", 125 | details: "Demo details text.", 126 | createdAt: Date.now(), 127 | updatedAt: Date.now() 128 | }, 129 | { 130 | firstName: "Solomon", 131 | lastName: "Larson", 132 | tel: "(648) 588-4779", 133 | email: "accumsan.interdum@icloud.net", 134 | details: "Demo details text.", 135 | createdAt: Date.now(), 136 | updatedAt: Date.now() 137 | }, 138 | { 139 | firstName: "Tanner", 140 | lastName: "Morin", 141 | tel: "(189) 577-5612", 142 | email: "nec.diam.duis@google.couk", 143 | details: "Demo details text.", 144 | createdAt: Date.now(), 145 | updatedAt: Date.now() 146 | }, 147 | { 148 | firstName: "September", 149 | lastName: "Walton", 150 | tel: "1-732-422-2492", 151 | email: "sed.sapien.nunc@icloud.com", 152 | details: "Demo details text.", 153 | createdAt: Date.now(), 154 | updatedAt: Date.now() 155 | }, 156 | { 157 | firstName: "Kermit", 158 | lastName: "Becker", 159 | tel: "1-163-757-8638", 160 | email: "id@yahoo.net", 161 | details: "Demo details text.", 162 | createdAt: Date.now(), 163 | updatedAt: Date.now() 164 | }, 165 | { 166 | firstName: "Anish", 167 | lastName: "Brown", 168 | tel: "1-163-757-8638", 169 | email: "Anish@yahoo.net", 170 | details: "Demo details text.", 171 | createdAt: Date.now(), 172 | updatedAt: Date.now() 173 | }, 174 | { 175 | firstName: "Duncan", 176 | lastName: "Woodard", 177 | tel: "1-163-757-8638", 178 | email: "Duncan@yahoo.net", 179 | details: "Demo details text.", 180 | createdAt: Date.now(), 181 | updatedAt: Date.now() 182 | }, 183 | { 184 | firstName: "Izabella", 185 | lastName: "Stark", 186 | tel: "1-163-757-8638", 187 | email: "Izabella@yahoo.net", 188 | details: "Demo details text.", 189 | createdAt: Date.now(), 190 | updatedAt: Date.now() 191 | }, 192 | { 193 | firstName: "Dhruv", 194 | lastName: "Fields", 195 | tel: "1-163-757-8638", 196 | email: "Dhruv@yahoo.net", 197 | details: "Demo details text.", 198 | createdAt: Date.now(), 199 | updatedAt: Date.now() 200 | }, 201 | { 202 | firstName: "Harriet", 203 | lastName: "Gillespie", 204 | tel: "1-163-757-8638", 205 | email: "Harriet@yahoo.net", 206 | details: "Demo details text.", 207 | createdAt: Date.now(), 208 | updatedAt: Date.now() 209 | }, 210 | { 211 | firstName: "Chad", 212 | lastName: "Barton", 213 | tel: "1-163-757-8638", 214 | email: "Chad@yahoo.net", 215 | details: "Demo details text.", 216 | createdAt: Date.now(), 217 | updatedAt: Date.now() 218 | }, 219 | { 220 | firstName: "Esmee", 221 | lastName: "Trujillo", 222 | tel: "1-163-757-8638", 223 | email: "Esmee@yahoo.net", 224 | details: "Demo details text.", 225 | createdAt: Date.now(), 226 | updatedAt: Date.now() 227 | }, 228 | ]); 229 | } catch (error) { 230 | console.log("err", + error); 231 | } --------------------------------------------------------------------------------