Skip to content

Commit

Permalink
Merge pull request #125 from rishabh7923/v2
Browse files Browse the repository at this point in the history
Refactor search functionality and enhance post display layout
  • Loading branch information
jinx-vi-0 authored Nov 7, 2024
2 parents 726232b + ac15dee commit a7a09c2
Show file tree
Hide file tree
Showing 6 changed files with 166 additions and 95 deletions.
1 change: 0 additions & 1 deletion public/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,6 @@ body.dark-mode .welcome-section a.cta-button {
body.dark-mode .pagination {
color: #E4E4E4; /* Light pagination text color */
}
=======

/* Contact Us Page Styling */
.contact-section {
Expand Down
127 changes: 71 additions & 56 deletions server/routes/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,56 @@ router.use((req, res, next) => {
next(); // Call the next middleware or route handler
});


router.get('/posts', async (req, res) => {
try {
const locals = {
title: "All Posts",
user: req.cookies.token,
description: "Made with ❤️"
};

const perPage = 10;
const page = parseInt(req.query.page) || 1;

let query = {};

if (req.query.search) {
const searchNoSpecialChar = req.query.search.replace(/[^a-zA-Z0-9 ]/g, "");

query = {
$or: [
{ title: { $regex: new RegExp(searchNoSpecialChar, 'i') } },
{ body: { $regex: new RegExp(searchNoSpecialChar, 'i') } }
]
}
}

const data = await Post.aggregate([
{ $match: query },
{ $sort: { createdAt: -1 } },
{ $skip: (perPage * page) - perPage },
{ $limit: perPage }
]).exec()

const count = await Post.countDocuments(query);

res.render('posts', {
locals,
data,
currentRoute: 'posts',
search: req.query.search,
pagination: {
current: page,
total: Math.ceil(count / perPage)
},
});
} catch (error) {
console.log(error);
res.status(500).send("Internal Server Error");
}
});

router.get('/', async (req, res) => {
try {
const locals = {
Expand All @@ -24,25 +74,14 @@ router.get('/', async (req, res) => {
description: "Made with ❤️"
}

let perPage = 10;
let page = req.query.page || 1;

const data = await Post.aggregate([ { $sort: { createdAt: -1 } } ])
.skip(perPage * page - perPage)
.limit(perPage)
.limit(5)
.exec();

// Count is deprecated - please use countDocuments
// const count = await Post.count();
const count = await Post.countDocuments({});
const nextPage = parseInt(page) + 1;
const hasNextPage = nextPage <= Math.ceil(count / perPage);

res.render('index', {
locals,
data,
current: page,
nextPage: hasNextPage ? nextPage : null,
currentRoute: '/'
});

Expand Down Expand Up @@ -96,40 +135,6 @@ router.get('/post/:id', async (req, res) => {
});


/**
* POST /
* Post - searchTerm
*/
router.post('/search', async (req, res) => {
try {
const locals = {
title: "Seach",
description: "Simple Blog created with NodeJs, Express & MongoDb."
}

let searchTerm = req.body.searchTerm;
const searchNoSpecialChar = searchTerm.replace(/[^a-zA-Z0-9 ]/g, "")

const data = await Post.find({
$or: [
{ title: { $regex: new RegExp(searchNoSpecialChar, 'i') }},
{ body: { $regex: new RegExp(searchNoSpecialChar, 'i') }}
]
});

res.render("search", {
data,
locals,
currentRoute: '/'
});

} catch (error) {
console.log(error);
}

});


/**
* GET /
* About
Expand Down Expand Up @@ -197,43 +202,53 @@ router.post('/send-message',validateContact ,async (req, res) => {
// Post.insertMany([
// {
// title: "Understanding the Basics of HTML and CSS",
// body: "HTML (HyperText Markup Language) and CSS (Cascading Style Sheets) are the fundamental technologies for building web pages. HTML provides the structure of the page, while CSS is used to control the presentation, formatting, and layout. This blog post will guide you through the essential concepts and elements of HTML and CSS, providing examples and best practices for creating well-structured and visually appealing web pages."
// body: "HTML (HyperText Markup Language) and CSS (Cascading Style Sheets) are the fundamental technologies for building web pages. HTML provides the structure of the page, while CSS is used to control the presentation, formatting, and layout. This blog post will guide you through the essential concepts and elements of HTML and CSS, providing examples and best practices for creating well-structured and visually appealing web pages.",
// author: "Rishabh"
// },
// {
// title: "An Introduction to JavaScript for Beginners",
// body: "JavaScript is a versatile programming language that allows you to create dynamic and interactive web content. This post will cover the basics of JavaScript, including variables, data types, functions, and control structures. You'll learn how to add interactivity to your web pages and understand how JavaScript interacts with HTML and CSS to enhance user experiences."
// body: "JavaScript is a versatile programming language that allows you to create dynamic and interactive web content. This post will cover the basics of JavaScript, including variables, data types, functions, and control structures. You'll learn how to add interactivity to your web pages and understand how JavaScript interacts with HTML and CSS to enhance user experiences.",
// author: "Rishabh"
// },
// {
// title: "Building Responsive Web Designs with CSS Grid and Flexbox",
// body: "Responsive web design ensures that your website looks great on all devices, from desktops to mobile phones. CSS Grid and Flexbox are powerful layout modules that help you create flexible and responsive designs. In this blog, we'll explore the concepts and practical implementations of CSS Grid and Flexbox, with code examples and tips for creating responsive layouts."
// body: "Responsive web design ensures that your website looks great on all devices, from desktops to mobile phones. CSS Grid and Flexbox are powerful layout modules that help you create flexible and responsive designs. In this blog, we'll explore the concepts and practical implementations of CSS Grid and Flexbox, with code examples and tips for creating responsive layouts.",
// author: "Rishabh"
// },
// {
// title: "Getting Started with React: A JavaScript Library for Building User Interfaces",
// body: "React is a popular JavaScript library developed by Facebook for building user interfaces. It allows developers to create large web applications that can update and render efficiently in response to data changes. This post will introduce you to the core concepts of React, including components, JSX, state, and props, and guide you through setting up a basic React application."
// body: "React is a popular JavaScript library developed by Facebook for building user interfaces. It allows developers to create large web applications that can update and render efficiently in response to data changes. This post will introduce you to the core concepts of React, including components, JSX, state, and props, and guide you through setting up a basic React application.",
// author: "Rishabh"
// },
// {
// title: "Understanding RESTful APIs and How to Integrate Them into Your Web Applications",
// body: "RESTful APIs (Application Programming Interfaces) are a set of rules and conventions for building and interacting with web services. They allow different software systems to communicate with each other. This blog post will explain what RESTful APIs are, how they work, and how to integrate them into your web applications using JavaScript and AJAX."
// body: "RESTful APIs (Application Programming Interfaces) are a set of rules and conventions for building and interacting with web services. They allow different software systems to communicate with each other. This blog post will explain what RESTful APIs are, how they work, and how to integrate them into your web applications using JavaScript and AJAX.",
// author: "Rishabh"
// },
// {
// title: "A Guide to Modern JavaScript Frameworks: Angular, Vue, and Svelte",
// body: "Modern JavaScript frameworks like Angular, Vue, and Svelte have revolutionized web development by providing robust tools for building complex applications. This post will compare these three frameworks, discussing their unique features, strengths, and use cases. By the end of this guide, you'll have a better understanding of which framework might be the best fit for your next project."
// body: "Modern JavaScript frameworks like Angular, Vue, and Svelte have revolutionized web development by providing robust tools for building complex applications. This post will compare these three frameworks, discussing their unique features, strengths, and use cases. By the end of this guide, you'll have a better understanding of which framework might be the best fit for your next project.",
// author: "Rishabh"
// },
// {
// title: "Enhancing Web Performance with Lazy Loading and Code Splitting",
// body: "Web performance is crucial for user experience and SEO. Lazy loading and code splitting are techniques that can significantly improve the load times of your web pages. This blog will explain how lazy loading defers the loading of non-critical resources and how code splitting breaks down your code into smaller bundles. Examples and implementation strategies will be provided to help you optimize your web performance."
// body: "Web performance is crucial for user experience and SEO. Lazy loading and code splitting are techniques that can significantly improve the load times of your web pages. This blog will explain how lazy loading defers the loading of non-critical resources and how code splitting breaks down your code into smaller bundles. Examples and implementation strategies will be provided to help you optimize your web performance.",
// author: "Rishabh"
// },
// {
// title: "Mastering Git and GitHub for Version Control",
// body: "Git is a distributed version control system that helps developers track changes in their code. GitHub is a platform for hosting Git repositories. This post will cover the basics of Git and GitHub, including how to create repositories, commit changes, branch, merge, and collaborate with others. Understanding these tools is essential for modern web development and team collaboration."
// body: "Git is a distributed version control system that helps developers track changes in their code. GitHub is a platform for hosting Git repositories. This post will cover the basics of Git and GitHub, including how to create repositories, commit changes, branch, merge, and collaborate with others. Understanding these tools is essential for modern web development and team collaboration.",
// author: "Rishabh"
// },
// {
// title: "Implementing Authentication in Web Applications with JWT",
// body: "JSON Web Tokens (JWT) are a compact and secure way to transmit information between parties as a JSON object. They are commonly used for authentication and authorization in web applications. This blog post will guide you through the process of implementing JWT authentication in a web application, including generating tokens, securing endpoints, and managing user sessions."
// body: "JSON Web Tokens (JWT) are a compact and secure way to transmit information between parties as a JSON object. They are commonly used for authentication and authorization in web applications. This blog post will guide you through the process of implementing JWT authentication in a web application, including generating tokens, securing endpoints, and managing user sessions.",
// author: "Rishabh"
// },
// {
// title: "Exploring the Power of CSS Preprocessors: Sass and LESS",
// body: "CSS preprocessors like Sass and LESS extend the capabilities of standard CSS by adding features like variables, nesting, and mixins. This post will introduce you to Sass and LESS, showing you how to install and use them to write more efficient and maintainable CSS code. Examples and practical tips will help you get started with these powerful tools."
// body: "CSS preprocessors like Sass and LESS extend the capabilities of standard CSS by adding features like variables, nesting, and mixins. This post will introduce you to Sass and LESS, showing you how to install and use them to write more efficient and maintainable CSS code. Examples and practical tips will help you get started with these powerful tools.",
// author: "Rishabh"
// }
// ])
// }
Expand Down
15 changes: 5 additions & 10 deletions views/index.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@
<img src="/img/hero-image.webp" alt="person looking out through window" class="hero-image" width="981" height="528">

<section class="articles">
<h2 class="articles__heading">Latest Posts</h2>
<div style="display: flex; flex-direction: row; justify-content: space-between; align-items: baseline;">
<h2 class="articles__heading">Latest Posts</h2>
<a href="/posts">View All</a>
</div>

<ul class="article-ul">
<% data.forEach(post => { %>
Expand All @@ -19,14 +22,6 @@
<% }) %>
</ul>

<button class="add-btn"><a href="/add-post" %> ">+</a></button>
<% if (nextPage !== null) { %>
<a href="/?page=<%= nextPage %>" class="pagination">&lt; View Older Posts</a>
<% } %>
<button class="add-btn"><a class="add-btn"href="/add-post">+</a></button>






</section>
10 changes: 1 addition & 9 deletions views/partials/header.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,7 @@
</nav>

<div class="header__button">
<button class="searchBtn" aria-expanded="false">
Search
<svg width="17" height="17" viewBox="0 0 17 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7.79167 13.4583C10.9213 13.4583 13.4583 10.9213 13.4583 7.79167C13.4583 4.66205 10.9213 2.125 7.79167 2.125C4.66205 2.125 2.125 4.66205 2.125 7.79167C2.125 10.9213 4.66205 13.4583 7.79167 13.4583Z" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M14.875 14.875L11.7938 11.7938" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</button>



<% if (locals.user) { %>
<button id="LogIn"><a style="text-decoration: none;" href="/logout">Log Out</a></button>
<% } else { %>
Expand Down
89 changes: 89 additions & 0 deletions views/posts.ejs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<style>
.posts {
display: flex;
flex-direction: column;
gap: 10px;
}
.post {
border-bottom: 2px solid var(--gray-light);
}
.post .heading {
display: flex;
justify-content: space-between;
}
.post .heading a {
text-decoration: none;
list-style-type: none;
padding: 0;
margin: 0;
font-size: clamp(1.13rem, calc(1.08rem + 0.22vw), 1.25rem);
display: flex;
flex-direction: column;
}
.post .heading a:hover {
color: var(--primary-color);
text-decoration: underline;
}
.post .description {
color: var(--gray);
margin-bottom: 10px;
}
</style>


<div class="search-bar" style="display: flex; justify-content: flex-end; margin-bottom: 20px; background: transparent;">
<div action="/search" method="GET" style="display: flex;">
<input type="text" onchange="search()" value="<%= search %>" name="query" placeholder="Search posts..." required
style="border: none; border-bottom: 1px solid black; outline: none; margin-right: 10px; height: 2rem; background: transparent;">
<svg width="30" height="30" viewBox="0 0 17 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M7.79167 13.4583C10.9213 13.4583 13.4583 10.9213 13.4583 7.79167C13.4583 4.66205 10.9213 2.125 7.79167 2.125C4.66205 2.125 2.125 4.66205 2.125 7.79167C2.125 10.9213 4.66205 13.4583 7.79167 13.4583Z"
stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M14.875 14.875L11.7938 11.7938" stroke="black" stroke-width="2" stroke-linecap="round"
stroke-linejoin="round"></path>
</svg>
</div>
</div>

<div class="posts">
<% data.forEach(post=> { %>
<div class="post">
<div class="heading">
<a href="/post/<%= post._id %>">
<%= post.title %>
</a>
</div>
<div class="description">
<%= post.body.slice(0, 220) + '...' %>
</div>
</div>
<% }) %>
</div>


<div class="pagination" style="display: flex; justify-content: flex-end; margin-top: 20px; font-size: 0.875rem;">
<% if (pagination.current > 1) { %>
<a href="?search=<%= search %>&page=<%= pagination.current - 1 %>" style="margin-right: 10px;">Previous</a>
<% } %>
<% for (let i = 1; i <= pagination.total; i++) { %>
<a href="?search=<%= search %>&page=<%= i %>" style="margin: 0 5px; <%= i === pagination.current ? 'font-weight: bold;' : '' %>"><%= i %></a>
<% } %>
<% if (pagination.current < pagination.total) { %>
<a href="?search=<%= search %>&page=<%= pagination.current + 1 %>" style="margin-left: 10px;">Next</a>
<% } %>
</div>

<script>
function search() {
const query = document.querySelector('input[type="text"]').value;
window.location.href = `?search=${encodeURIComponent(query)}`;
}
</script>
19 changes: 0 additions & 19 deletions views/search.ejs

This file was deleted.

0 comments on commit a7a09c2

Please sign in to comment.