Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion my-blog-app/backend/.gitignore → my-blog-app/.gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
node_modules/
/dist
dist/
build/
uploads/
.env
8 changes: 4 additions & 4 deletions my-blog-app/Frontend/src/common/blogCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,14 @@ const BlogCard = ({ editOption, blogData }: BlogCardProps) => {
{blogData?.map((blog) => (
<div
className=" w-full md:w-[49%] flex flex-col items-start p-3 gap-3 border rounded-lg shadow cursor-pointer hover:shadow-lg overflow-hidden"
key={blog.blogId}
key={blog._id}
>
{/* //sending blogData with navigate function of router */}
<Link to={`/blog/${blog.blogId}`}>
<Link to={`/blog/${blog._id}`}>
<div className="w-full flex flex-row-reverse gap-2 justify-between items-start">
<div className="size-40">
<img
src={`http://localhost:5000/uploads/${blog.blogImageLink ?? ""}`} // getting the image
src={`${import.meta.env.VITE_SERVER_URL}/uploads/${blog.blogImageLink ?? ""}`} // getting the image
alt="Blog related"
className=" w-full h-full rounded-lg"
/>
Expand All @@ -60,7 +60,7 @@ const BlogCard = ({ editOption, blogData }: BlogCardProps) => {

<div className="flex w-full justify-between items-center px-2 ">
<LikesAndComment
blogId={blog.blogId}
_id={blog._id}
likeCounts={blog.blogLikesCount}
commentCounts={blog.blogCommentsCount}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { CommentsInteractionProps } from "../types/types";
import toast from "react-hot-toast";
import { useEffect, useState } from "react";

const CommentComponent = ({ blogId }: CommentsInteractionProps) => {
const CommentComponent = ({ _id }: CommentsInteractionProps) => {
const [inputCommentValue, setInputCommentValue] = useState("");
const [cmtBtn, setCmtBtn] = useState(true); // state for handling toggel of comment button

Expand All @@ -27,13 +27,13 @@ const CommentComponent = ({ blogId }: CommentsInteractionProps) => {

//saving the comments in database
async function postComments(newComment: {
blogId: number;
blogId: string;
username: string;
commentText: string;
}) {
try {
const comment = await axios.post(
"http://localhost:5000/comments",
`${import.meta.env.VITE_SERVER_URL}/comments`,
newComment
);
toast.success("comment posted successfully");
Expand All @@ -51,7 +51,7 @@ const CommentComponent = ({ blogId }: CommentsInteractionProps) => {
//getting the comment data from Form
if (isLoggedIn && userName) {
const commentContent = {
blogId,
blogId: _id,
username: userName, //
commentText: inputCommentValue,
};
Expand Down Expand Up @@ -84,7 +84,7 @@ const CommentComponent = ({ blogId }: CommentsInteractionProps) => {
Comment
</button>
</div>
<ShowingComments blogId={blogId} />
<ShowingComments _id={_id} />
</>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,25 @@
import { useEffect,useState } from 'react';
import DefaultProfile from "../../../images/defaultProfile.png";
import axios from 'axios';
import {CommentsData} from "../../types/types";
import {CommentsData, CommentProps} from "../../types/types";


type CommentProps = {
blogId:number
}

const ShowingComments = ({blogId}:CommentProps) => {
const ShowingComments = ({_id}:CommentProps) => {
const [showComment, setShowComment] = useState<CommentsData[]>([]);

// getting the comments
useEffect(()=>{
async function getComments (){
try {
const response = await axios.get(`http://localhost:5000/comments/${blogId}`);
const response = await axios.get(`${import.meta.env.VITE_SERVER_URL}/comments/${_id}`);
setShowComment(response.data);
} catch (error) {
console.log(error, "cannot get the comments of this blog");
}
}
getComments();
},[blogId])
},[_id])

return (
<div className="w-full flex flex-col gap-6 p-2 rounded-xl my-2">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ import { Blog } from "../types/types";
const CompleteBlogViewPage = () => {
const [fullBlog, setFullBlog] = useState<Blog | null>(null);
const { id } = useParams<{ id: string }>();
const blogId = Number(id); //converting the id into nummber
const blogId = id; // MongoDB _id is a string

useEffect(() => {
async function fetchingBlogById() {
try {
const response = await axios.get<Blog>(
`http://localhost:5000/blogs/${blogId}`
`${import.meta.env.VITE_SERVER_URL}/blogs/${blogId}`
);
setFullBlog(response.data);
} catch (error) {
Expand Down Expand Up @@ -46,7 +46,7 @@ const CompleteBlogViewPage = () => {
<hr />
<div className="py-4 px-8">
<LikesAndComment
blogId={fullBlog?.blogId}
_id={fullBlog?._id}
likeCounts={fullBlog.blogLikesCount}
commentCounts={fullBlog.blogCommentsCount}
/>
Expand All @@ -56,7 +56,7 @@ const CompleteBlogViewPage = () => {
<div className="w-full mx-auto h-96 mb-14 ">
<img
className="w-full h-full rounded-xl"
src={`http://localhost:5000/uploads/${
src={`${import.meta.env.VITE_SERVER_URL}/uploads/${
fullBlog.blogImageLink ?? ""
}`}
alt="CoverImg"
Expand All @@ -71,7 +71,7 @@ const CompleteBlogViewPage = () => {
<h2 className="text-2xl font-semibold py-4">
Comments({fullBlog.blogCommentsCount})
</h2>
<CommentComponent blogId={fullBlog?.blogId} />
<CommentComponent _id={fullBlog?._id} />
</div>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { BlogInteractionProps } from "../types/types";
import toast from "react-hot-toast";
import { useAppSelector } from "../../redux/app/hooks/hooks";

const LikesAndComment = ({ blogId, likeCounts, commentCounts }:BlogInteractionProps) => {
const LikesAndComment = ({ _id, likeCounts, commentCounts }:BlogInteractionProps) => {

const [liked, setLiked] = useState<boolean>(false);
const [updatingLikesCount, setUpdatingLikesCount] = useState<number>(likeCounts);
Expand All @@ -24,7 +24,7 @@ const LikesAndComment = ({ blogId, likeCounts, commentCounts }:BlogInteractionPr
if (isLoggedIn && userName) {
async function getLikesByUsername() {
try {
const response = await axios.get(`http://localhost:5000/likes/${blogId}`);
const response = await axios.get(`${import.meta.env.VITE_SERVER_URL}/likes/${_id}`);
const allLikes = response.data;
setLiked(
allLikes.some((like:{username:string}) => like.username === userName)
Expand All @@ -36,13 +36,13 @@ const LikesAndComment = ({ blogId, likeCounts, commentCounts }:BlogInteractionPr
}
getLikesByUsername();
}
}, [userName, blogId, isLoggedIn]);
}, [userName, _id, isLoggedIn]);

// create post api for updating the likes count
async function sendingLikeDataToServer(likeData: { blogId: number; username: string }) {
async function sendingLikeDataToServer(likeData: { blogId: string; username: string }) {
try {
const response = await axios.post(
"http://localhost:5000/likes",
`${import.meta.env.VITE_SERVER_URL}/likes`,
likeData
);
console.log(
Expand All @@ -57,7 +57,7 @@ const LikesAndComment = ({ blogId, likeCounts, commentCounts }:BlogInteractionPr
const handleLike = () => {
if (isLoggedIn && userName) {
const likeData = {
blogId,
blogId: _id,
username: userName,
};
sendingLikeDataToServer(likeData); //calling the sending like function
Expand All @@ -73,7 +73,7 @@ const LikesAndComment = ({ blogId, likeCounts, commentCounts }:BlogInteractionPr
async function deleteTheLikePost() {
try {
const response = await axios.delete(
`http://localhost:5000/likes/${blogId}/${userName}`
`${import.meta.env.VITE_SERVER_URL}/likes/${_id}/${userName}`
);
console.log("blog unliked", response.data);
} catch (error) {
Expand Down
68 changes: 36 additions & 32 deletions my-blog-app/Frontend/src/common/types/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,52 +2,56 @@ import { RawDraftContentState } from "draft-js";

//usting this interface in fullview page
export type Blog = {
blogId: number;
_id: string;
blogAuthor: string;
blogTitle: string;
blogSubtitle: string;
blogContent:RawDraftContentState;
blogContent: RawDraftContentState;
blogImageLink?: string;
blogLikesCount: number;
blogCommentsCount: number;
};

//using this in blogCard component
export type BlogCardProps = {
editOption?: boolean;
blogData?: Blog[];
};
editOption?: boolean;
blogData?: Blog[];
};

export type CommentsInteractionProps = {
blogId: number;
}
export type CommentsInteractionProps = {
_id: string;
}

export type CommentsData = {
blogId:number,
username:string,
commentText: string
}
export type CommentsData = {
blogId: number,
username: string,
commentText: string
}

// using this in likeAndComment component
export type BlogInteractionProps = {
blogId: number;
likeCounts: number;
commentCounts: number;
};

//using this interface in login and signup page
export interface UserDetails {
username?:string;
fullname?:string;
email?:string;
password?:string;
confirmPassword?:string;
}
export type BlogInteractionProps = {
_id: string;
likeCounts: number;
commentCounts: number;
};

//using this interface in login and signup page
export interface UserDetails {
username?: string;
fullname?: string;
email?: string;
password?: string;
confirmPassword?: string;
}

export interface NewBlogData {
author?:string;
title?:string;
subtitle?:string;
blogContent?:string;
blogImageLink?:string|null;
author?: string;
title?: string;
subtitle?: string;
blogContent?: string;
blogImageLink?: string | null;
}

export type CommentProps = {
_id:string
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,18 @@ const MostPopularBlog = () => {
useEffect(() => {
async function fetchBlogs() {
try {
const Blogs = await axios.get("http://localhost:5000/blogs");
const Blogs = await axios.get(`${import.meta.env.VITE_SERVER_URL}/blogs`);
console.log("here is the blog data", Blogs.data);
const mostLikedBlogs = Blogs.data.filter(
(blog: Blog) => blog.blogLikesCount > 10
); // filtering out the most liked blogs from server respones
mostLikedBlogs.sort(
(b: Blog, a: Blog) => a.blogLikesCount - b.blogLikesCount
); // after filtering we are sorting the blogs on the base of its like counts
// console.log("here is the moreLikedBlogData:",mostLikedBlogs);
setBlogData(mostLikedBlogs);
const allBlogs = Blogs.data;

// const mostLikedBlogs = allBlogs.filter(
// (blog: Blog) => blog.blogLikesCount > 10
// ); // filtering out the most liked blogs from server respones
// mostLikedBlogs.sort(
// (b: Blog, a: Blog) => a.blogLikesCount - b.blogLikesCount
// ); // after filtering we are sorting the blogs on the base of its like counts

setBlogData(allBlogs);
} catch (error) {
console.log("Error in fetching the data:", error);
}
Expand Down
18 changes: 9 additions & 9 deletions my-blog-app/Frontend/src/components/login-page/loginPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import axios from "axios";
import toast from "react-hot-toast";
import React, { useState } from "react";

interface Userdetails{
username:string,
password:string,
interface Userdetails {
username: string,
password: string,
};

const LoginPage = () => {
Expand All @@ -20,9 +20,9 @@ const LoginPage = () => {
});
const [errorMsg, setErrorMsg] = useState<string>("");
// const [loginBtn, setLoginBtn] = useState<boolen>(false);


const handleBlur = (e:React.FocusEvent<HTMLInputElement>) => {

const handleBlur = (e: React.FocusEvent<HTMLInputElement>) => {
e.preventDefault();
if (!inputValue.username || !inputValue.password) {
setErrorMsg("Username or Password fields cannot be blank!");
Expand All @@ -32,7 +32,7 @@ const LoginPage = () => {
}
};

const handleInputChange = (e:React.ChangeEvent<HTMLInputElement>) => {
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target;
setInputValue((prev) => ({
...prev,
Expand All @@ -46,21 +46,21 @@ const LoginPage = () => {
}) {
try {
const response = await axios.post(
"http://localhost:5000/login",
`${import.meta.env.VITE_SERVER_URL}/login`,
userCredential
);
localStorage.setItem("authenticated", response.data.authenticated);
dispatch(login(response.data.user)); //
toast.success("Login successfully!");
setInputValue({username:"",password:""});
setInputValue({ username: "", password: "" });
navigate("/");
} catch (error) {
console.log("login error", error);
toast.error("username or password incorrect. Try again!");
}
}

const handleLogin = (e:React.FormEvent<HTMLFormElement>) => {
const handleLogin = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
const userCredential = {
username: inputValue.username,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const UserWrittenBlogs = () => {
useEffect(() => {
async function getBlogs() {
try {
const response = await axios.get<Blog[]>(`http://localhost:5000/blogs`);
const response = await axios.get<Blog[]>(`${import.meta.env.VITE_SERVER_URL}/blogs`);
const allBlogs = response.data;
const blogsWrittenByUser = allBlogs.filter(
(blog) => username === blog.blogAuthor
Expand Down
Loading