Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
157 commits
Select commit Hold shift + click to select a range
5a57e94
Static article responsive
PolCarva Aug 3, 2023
54f9b8b
comment section
PolCarva Aug 3, 2023
aa417d7
Finished frontend
PolCarva Aug 3, 2023
fa9eccc
Edit profile functionallity added
PolCarva Aug 7, 2023
1abf5f8
Delete Dummy Data file
PolCarva Aug 7, 2023
afb53c4
Edit profile functionallity added
PolCarva Aug 7, 2023
525d3f5
Fetched data for posts, added skeletons and fetched comments
PolCarva Aug 8, 2023
9e3f1f3
Merge branch 'master' of https://github.com/PolCarva/Blog
PolCarva Aug 8, 2023
03e2f30
Admin dashboard, post manager front and back
PolCarva Aug 9, 2023
40d8b68
Upload post img and edit post function
PolCarva Aug 9, 2023
f5eeb79
build script
PolCarva Aug 9, 2023
376a8a2
removed build
PolCarva Aug 9, 2023
35f4b4c
changed base_url
PolCarva Aug 9, 2023
a4ebb9f
Create _redirects
PolCarva Aug 9, 2023
92cebdd
built
PolCarva Aug 9, 2023
a5a24da
_redirects
PolCarva Aug 9, 2023
1dfd3fa
Create _redirects
PolCarva Aug 9, 2023
27e7b0e
built
PolCarva Aug 9, 2023
e179bd6
Built y redirects
PolCarva Aug 9, 2023
ca6cf41
Built y redirects
PolCarva Aug 9, 2023
7c8a8ef
changed base url to local host
PolCarva Aug 9, 2023
440fc03
Create/Edit post
PolCarva Oct 13, 2023
20cc55f
add cors settings for deploying
PolCarva Oct 13, 2023
60ef859
vercel.json file
PolCarva Oct 13, 2023
06c7486
fixed vercel.json directory
PolCarva Oct 13, 2023
c70b817
vercel.json configuration changed
PolCarva Oct 13, 2023
6b08375
same
PolCarva Oct 13, 2023
99bb7aa
changed al imports to double '
PolCarva Oct 13, 2023
62666de
add .jsx to Home to see if thats the issue
PolCarva Oct 13, 2023
ff5cc19
.jsx was not the issue
PolCarva Oct 13, 2023
128bfa8
trying to resolve imports
PolCarva Oct 13, 2023
1354ba3
changed baseURL to production
PolCarva Oct 13, 2023
ff9f8b3
added vercel.json for redirections
PolCarva Oct 13, 2023
c890ec6
add node_env variable
PolCarva Oct 13, 2023
d920fac
add node_env variable
PolCarva Oct 13, 2023
9bf1ba3
config vercel.json
PolCarva Oct 13, 2023
d705956
changed config vercel.json
PolCarva Oct 13, 2023
6df44c6
changed server to vercel
PolCarva Oct 13, 2023
931c4d4
changed back to render
PolCarva Oct 13, 2023
fa48a38
post categories backend
PolCarva Nov 15, 2023
2a5082e
Changed to Railway
PolCarva Nov 16, 2023
6304eaf
Update stable.jsx
PolCarva Nov 16, 2023
a75f64b
Merge remote-tracking branch 'origin/master'
PolCarva Nov 16, 2023
3bbf667
Updated client things
PolCarva Nov 16, 2023
62d9166
Add onError imgs
PolCarva Nov 16, 2023
46b2517
Changed on error imgs
PolCarva Nov 16, 2023
9f6fed7
Add backend categories and implement
PolCarva Nov 21, 2023
a0ae089
Fix styling and add category selection in EditPost
PolCarva Nov 21, 2023
ef33583
Add isNew property to Post model and update
PolCarva Nov 21, 2023
617bd72
Fix image loading issue and update editor styles
PolCarva Nov 22, 2023
788c5fa
Fix UI styling issues in Admin and Comments
PolCarva Nov 28, 2023
93d41b6
Refactor EditPost component and remove unused code
PolCarva Nov 28, 2023
a23b01a
Refactor postControllers and ManagePosts components
PolCarva Dec 28, 2023
8771ec2
Add getAllComments API endpoint and updateComment functionality
PolCarva Jan 18, 2024
eb5e418
Refactor post categories controller and add new category route
PolCarva Jan 30, 2024
9409c33
Update dropdown class name and fix formatting in EditPost component
PolCarva Jan 30, 2024
7a00c23
Add toast notification to homepage
PolCarva Feb 1, 2024
d1df62a
Refactor CSS classes in Footer, Header, Articles, CTA, Hero, LoginPag…
PolCarva Feb 1, 2024
20403a2
Update container and section classes in multiple components
PolCarva Feb 1, 2024
f4ff09a
Update copyright year in Footer component
PolCarva Feb 1, 2024
b05d606
Add getSingleCategory route and functionality
PolCarva Feb 2, 2024
b2c2d4f
Refactor NavItemCollapse component
PolCarva Feb 2, 2024
2aa79d5
Add nodemon and i18next dependencies, and implement i18n in App and H…
PolCarva Feb 7, 2024
03e2508
Add getAllUsers and deleteUser functions to userControllers.js
PolCarva Feb 15, 2024
712f28e
Add Users page and functionality
PolCarva Feb 15, 2024
a97905c
Remove unused imports and update user profile route
PolCarva Feb 21, 2024
f09e3bc
Remove unused imports and update userControllers.js
PolCarva Feb 22, 2024
591276f
Add internationalization support and update toast messages
PolCarva Feb 22, 2024
c5a9dd1
Update i18n translations for article detail page
PolCarva Feb 22, 2024
3011d02
Add internationalization support and update translations
PolCarva Feb 22, 2024
42a83b9
Add translation for verified and notVerified in ArticleCard component
PolCarva Feb 22, 2024
e0f2f88
Fix language change functionality in Header component
PolCarva Feb 22, 2024
a4b8cea
Add blog pagination and update translations
PolCarva Feb 27, 2024
cf37a80
Refactor BlogPage and Hero components
PolCarva Feb 27, 2024
75708e8
Refactor DataTable and HeaderAdmin components, and update Categories …
PolCarva Feb 27, 2024
0cace5a
Update i18n translations and header logo size
PolCarva Feb 27, 2024
dfb7640
Update suggested posts limit
PolCarva Feb 27, 2024
4cf3b67
Refactor BlogPage.jsx to handle empty data case
PolCarva Feb 27, 2024
e64d97e
Add url field to Post model and update postControllers and BlogPage c…
PolCarva Feb 28, 2024
6f0fb0d
Add styling for non-editable ProseMirror element
PolCarva Feb 28, 2024
3cd2bbc
Filter out new posts in SuggestedPosts component
PolCarva Feb 28, 2024
ebec033
Add getPopularCategories endpoint
PolCarva Feb 28, 2024
24f78ed
Fix URL validation and display popular categories in Hero component
PolCarva Feb 28, 2024
52184ee
Add category filter to getAllPosts API
PolCarva Feb 28, 2024
a2e5072
Refactor footer component to use dynamic content
PolCarva Feb 28, 2024
51c6313
Update button styling in Header component
PolCarva Feb 28, 2024
10f710f
Refactor postControllers.js to support filtering by tags as well as t…
PolCarva Feb 28, 2024
15bc7f4
Add tagsRoutes and update category links in Hero component
PolCarva Feb 28, 2024
1e92e48
Refactor article detail page and home page components
PolCarva Feb 28, 2024
251baef
Refactor popular categories to popular tags
PolCarva Feb 28, 2024
42b8945
Fix rendering issue in DataTable and update checkbox image path in Us…
PolCarva Feb 28, 2024
e9a9c2a
Update user avatar default path, fix import typo, and add verified ba…
PolCarva Feb 29, 2024
83e93c6
Add defaultProfile.jpg to .gitignore
PolCarva Feb 29, 2024
3e944ef
Update .gitignore and i18n.jsx files
PolCarva Feb 29, 2024
70e4636
Add nodemailer package and update post model
PolCarva Feb 29, 2024
d208df9
Add post visibility toggle functionality
PolCarva Feb 29, 2024
a53d9af
Add external link icon to ArticleCard component and fix invalidUrl al…
PolCarva Feb 29, 2024
6612dbc
Refactor button styles and add hover effects
PolCarva Feb 29, 2024
45bf4f9
Refactor article title rendering in ArticleDetailPage.jsx
PolCarva Feb 29, 2024
e287859
Refactor ArticleCard component to improve link styling
PolCarva Feb 29, 2024
68d53dc
Add @formspree/react package and update translations
PolCarva Feb 29, 2024
dddbad8
Update environment variable in stables.jsx and CTA.jsx
PolCarva Feb 29, 2024
807fe53
Add @vercel/analytics package and integrate analytics tracking
PolCarva Feb 29, 2024
a116f1d
Remove unused imports and comments in HomePage.jsx
PolCarva Feb 29, 2024
399feb8
Remove unused code and comments
PolCarva Feb 29, 2024
4be2980
Add getUserProfile endpoint and route
PolCarva Feb 29, 2024
24cd9e8
Refactor ProfileDetailPage component
PolCarva Feb 29, 2024
82cb452
Add bio and specializedIn fields to User model, update login button text
PolCarva Feb 29, 2024
b560a3c
Add bio, phone, and specialization fields to user profile
PolCarva Feb 29, 2024
1dc2107
Add user bio, phone, and specialization fields
PolCarva Feb 29, 2024
5c665d1
Add react-modal package and update API endpoint for user profile
PolCarva Feb 29, 2024
5601aee
Add user profile information to article detail page
PolCarva Feb 29, 2024
2ffcc11
Add isNew field to Post model and update UI to handle new posts
PolCarva Feb 29, 2024
78502b6
Refactor active navigation logic in HeaderAdmin component and update …
PolCarva Feb 29, 2024
c90cb59
Refactor search keyword variable name in getAllPostCategories
PolCarva Feb 29, 2024
81c3d38
Update user search filter
PolCarva Feb 29, 2024
bcfd4d5
Update BlogPage and Hero components
PolCarva Mar 1, 2024
d3f3ed5
Refactor ManagePosts component
PolCarva Mar 1, 2024
914d5b1
Add password input autoComplete attribute
PolCarva Mar 1, 2024
86cd203
Refactor ProfilePage component to handle profile data loading
PolCarva Mar 1, 2024
838bf53
Refactor sorting logic for articles
PolCarva Mar 1, 2024
fe07151
Fix URL placeholders in i18n.jsx
PolCarva Mar 1, 2024
3847652
Minot bug fixing
PolCarva Mar 1, 2024
59d2820
Fix scroll behavior in BlogPage and HomePage
PolCarva Mar 1, 2024
d9286b8
Removed forgot-passwotd
PolCarva Mar 1, 2024
50d80c1
Remove console.log statements and update translations
PolCarva Mar 1, 2024
df75452
Refactor category filter in BlogPage component
PolCarva Mar 1, 2024
1277877
Update category translation key
PolCarva Mar 1, 2024
dc51cec
Add tooltips for new posts
PolCarva Mar 1, 2024
483a24c
Fix filter condition in BlogPage.jsx
PolCarva Mar 1, 2024
c4f081d
Refactor Post model and i18n keys
PolCarva Mar 2, 2024
7f188f8
Refactor isNewPost tooltip visibility
PolCarva Mar 2, 2024
d89444a
Refactor handleFileChange function to handle initial photo state
PolCarva Mar 2, 2024
8abd365
Refactor category filtering in BlogPage component
PolCarva Mar 2, 2024
0394c5a
Profile minor changes
PolCarva Mar 3, 2024
7d73241
Bio fixes
PolCarva Mar 3, 2024
de96707
Update profile detail page styling
PolCarva Mar 3, 2024
dcf4ef2
Refactor SuggestedPosts component to filter out hidden and new posts
PolCarva Mar 3, 2024
74a00a7
Update CTA image and scrollbar width
PolCarva Mar 3, 2024
f11e4c9
Update index.html with language and meta tags
PolCarva Mar 3, 2024
64700fc
RailwayIgnore
PolCarva Mar 3, 2024
574ba92
Update description content in index.html
PolCarva Mar 3, 2024
bab8c3d
Fix typo in cta title
PolCarva Mar 4, 2024
557784a
Update CTAImgRobot image format
PolCarva Mar 4, 2024
5a8f533
Fix typo in success message in i18n.jsx
PolCarva Mar 4, 2024
d8db800
Update success message in i18n.jsx
PolCarva Mar 4, 2024
a1e9524
Refactor post update logic and handle file upload errors
PolCarva Mar 4, 2024
23168de
Refactor postControllers.js and EditPost.jsx
PolCarva Mar 4, 2024
269c53d
Add @tiptap/extension-link to package-lock.json and package.json
PolCarva Mar 5, 2024
82c34e8
Add autolink and configure HTML attributes for Link extension
PolCarva Mar 5, 2024
2c261bb
Add @vercel/speed-insights package
PolCarva Mar 5, 2024
149e4a1
Added settings and backup db in case railway is not active
PolCarva Mar 24, 2024
ef8e018
Commented out useEffect hook that displays toast messages
PolCarva Mar 25, 2024
c66b9bf
Remove /uploads from .railwayignore
PolCarva Apr 7, 2024
7a55962
Update isDbConnected setting to true in client/src/config/index.js
PolCarva Apr 13, 2024
80aa563
Merge branch 'master' of https://github.com/PolCarva/Blog
PolCarva Apr 13, 2024
fa27152
Update url max length
PolCarva Apr 17, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
.env
node_modules/
node_modules/
DummyData/
WorkSpace.code-workspace
email-pass.txt
28 changes: 28 additions & 0 deletions backend/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Ignore node_modules directory
node_modules/

# Ignore environment-specific files
.env
.env.local
.env.*.local

# Ignore build artifacts
build/
dist/

# Ignore logs
logs/

# Ignore dependency lock files
package-lock.json
yarn.lock

# Ignore IDE and editor files
.vscode/
.idea/
*.sublime-project
*.sublime-workspace

# Ignore system files
.DS_Store
Thumbs.db
17 changes: 17 additions & 0 deletions backend/config/db.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import mongoose from "mongoose";

const connectDB = async () => {
try {
const conn = await mongoose.connect(process.env.MONGO_URI, {
useNewUrlParser: true,
useUnifiedTopology: true,
});

console.log(`MongoDB connected`);
} catch (error) {
console.log(`Error: ${error.message}`);
process.exit(1);
}
};

export default connectDB;
136 changes: 136 additions & 0 deletions backend/controllers/commentControllers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
import Comment from "../models/Comment";
import Post from "../models/Post";

const createComment = async (req, res, next) => {
try {
const { desc, slug, parent, replyOnUser } = req.body;

const post = await Post.findOne({ slug });

if (!post) {
const error = new Error("Post not found");
return next(error);
}

const newComment = new Comment({
user: req.user._id,
desc,
post: post._id,
parent,
replyOnUser,
});
const savedComment = await newComment.save();

return res.json(savedComment);
} catch (error) {
next(error);
}
};

const updateComment = async (req, res, next) => {
try {
const { desc, check } = req.body;

const comment = await Comment.findById(req.params.commentId);

if (!comment) {
const error = new Error("Comment not found");
return next(error);
}

comment.desc = desc || comment.desc;
comment.check = typeof check !== "undefined" ? check : comment.check;

const updatedComment = await comment.save();

return res.json(updatedComment);
} catch (error) {
next(error);
}
};

const deleteComment = async (req, res, next) => {
try {
const comment = await Comment.findByIdAndDelete(req.params.commentId);
await Comment.deleteMany({ parent: comment._id });

if (!comment) {
const error = new Error("Comment not found");
return next(error);
}

return res.json({ message: "Comment deleted successfully" });
} catch (error) {
next(error);
}
};

const getAllComments = async (req, res, next) => {
try {
const filter = req.query.searchKeyword;
const userId = req.query.userId;

let where = {};

if (userId) {
where.user = userId;
}

if (filter) {
where.desc = { $regex: filter, $options: "i" };
}

let query = Comment.find(where);
const page = parseInt(req.query.page) || 1;
const pageSize = parseInt(req.query.limit) || 10;
const skip = (page - 1) * pageSize;
const total = await Comment.find(where).countDocuments();
const pages = Math.ceil(total / pageSize);

res.header({
"x-filter": filter,
"x-totalcount": JSON.stringify(total),
"x-currentpage": JSON.stringify(page),
"x-pagesize": JSON.stringify(pageSize),
"x-totalpagecount": JSON.stringify(pages),
});

if (page > pages) {
return res.json([]);
}

const result = await query
.skip(skip)
.limit(pageSize)
.populate([
{
path: "user",
select: ["avatar", "name", "verified"],
},
{
path: "parent",
populate: [
{
path: "user",
select: ["avatar", "name"],
},
],
},
{
path: "replyOnUser",
select: ["avatar", "name"],
},
{
path: "post",
select: ["slug", "title"],
},
])
.sort({ updatedAt: "desc" });

return res.json(result);
} catch (error) {
next(error);
}
};

export { createComment, updateComment, deleteComment, getAllComments };
36 changes: 36 additions & 0 deletions backend/controllers/mailControllers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import nodemailer from "nodemailer";

const transporter = nodemailer.createTransport({
service: "gmail",
port: 587,
secure: false, // Use `true` for port 465, `false` for all other ports
auth: {
user: process.env.ADMIN_EMAIL,
pass: process.env.ADMIN_EMAIL_PASSWORD,
},
});

const sendAdminRequestEmail = (req, res) => {
const { email, name } = req.body;
const mailOptions = {
from: {
name: "Social Multimedia",
address: process.env.ADMIN_EMAIL,
},
to: process.env.ADMIN_EMAIL,
subject: "Solicitud para ser administrador",
text: `Se ha recibido una solicitud para ser administrador de ${name}. Email: ${email}`,
html: `<h1>Solicitud para ser administrador</h1><p>Se ha recibido una solicitud para ser administrador de ${name}.</p><p>Email: ${email}</p>`,
};

transporter.sendMail(mailOptions, (error, info) => {
if (error) {
console.log(error);
res.status(500).json({ message: "Error sending email" });
} else {
res.status(200).json({ message: "Email succesfully sent" });
}
});
};

export { sendAdminRequestEmail };
161 changes: 161 additions & 0 deletions backend/controllers/postCategoriesControllers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
import Post from "../models/Post";
import PostCategories from "../models/PostCategories";

const createPostCategory = async (req, res, next) => {
try {
const { title } = req.body;

const postCategory = await PostCategories.findOne({ title });

if (postCategory) {
const error = new Error("This category already exists");
return next(error);
}

const newPostCategory = new PostCategories({ title });

const savedPostCategory = await newPostCategory.save();

return res.status(201).json(savedPostCategory);
} catch (error) {
next(error);
}
};

const getSingleCategory = async (req, res, next) => {
try {
const postCategory = await PostCategories.findById(
req.params.postCategoryId
);

if (!postCategory) {
const error = new Error("Category not found");
return next(error);
}

return res.json(postCategory);
} catch (error) {
next(error);
}
};

const getAllPostCategories = async (req, res, next) => {
try {
const filter = req.query.search;
const userId = req.query.userId;

let where = {};

if (userId) {
where.user = userId;
}

if (filter) {
where.title = { $regex: filter, $options: "i" };
}

let query = PostCategories.find(where);
const page = parseInt(req.query.page) || 1;
const pageSize = parseInt(req.query.limit) || 10;
const skip = (page - 1) * pageSize;
const total = await PostCategories.find(where).countDocuments();
const pages = Math.ceil(total / pageSize);

res.header({
"x-filter": filter,
"x-totalcount": JSON.stringify(total),
"x-currentpage": JSON.stringify(page),
"x-pagesize": JSON.stringify(pageSize),
"x-totalpagecount": JSON.stringify(pages),
});

if (page > pages) {
return res.json([]);
}

const result = await query
.skip(skip)
.limit(pageSize)
.sort({ updatedAt: "desc" });

return res.json(result);
} catch (error) {
next(error);
}
};

const updatePostCategory = async (req, res, next) => {
try {
const { title } = req.body;

const postCategory = await PostCategories.findByIdAndUpdate(
req.params.postCategoryId,
{ title: title },
{ new: true }
);

if (!postCategory) {
const error = new Error("This category does not exist");
return next(error);
}

return res.json(postCategory);
} catch (error) {
next(error);
}
};

const deletePostCategory = async (req, res, next) => {
try {
const categoryId = req.params.postCategoryId;

await Post.updateMany(
{ categories: { $in: [categoryId] } },
{ $pull: { categories: categoryId } }
);

await PostCategories.deleteOne({ _id: categoryId });

res.send({
message: "Post category deleted successfully!",
});
} catch (error) {
next(error);
}
};

const getPopularCategories = async (req, res, next) => {
try {
const categories = await PostCategories.aggregate([
{
$lookup: {
from: "posts",
localField: "_id",
foreignField: "categories",
as: "posts",
},
},
{
$project: {
title: 1,
count: { $size: "$posts" },
},
},
{ $sort: { count: -1 } },
{ $limit: 5 },
]);

return res.json(categories);
} catch (error) {
next(error);
}
}

export {
createPostCategory,
getAllPostCategories,
updatePostCategory,
deletePostCategory,
getSingleCategory,
getPopularCategories,
};
Loading