Skip to content

Commit

Permalink
"Added blogReducer to store, updated Masonry component to display blo…
Browse files Browse the repository at this point in the history
…g posts, and modified Home page to fetch and display first three blog posts"
  • Loading branch information
ucangun committed Sep 17, 2024
1 parent d370551 commit f7725ba
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 16 deletions.
2 changes: 2 additions & 0 deletions src/app/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import { configureStore } from "@reduxjs/toolkit";
import authReducer from "../features/authSlice";
import blogReducer from "../features/blogSlice";
import themeReducer from "../features/themeSlice";

import {
Expand All @@ -26,6 +27,7 @@ const persistedReducer = persistReducer(persistConfig, authReducer);
const store = configureStore({
reducer: {
auth: persistedReducer,
blog: blogReducer,
theme: themeReducer,
},
middleware: (getDefaultMiddleware) =>
Expand Down
36 changes: 22 additions & 14 deletions src/components/Masonry.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,35 @@ import Box from "@mui/material/Box";
import { styled } from "@mui/material/styles";
import Paper from "@mui/material/Paper";
import Masonry from "@mui/lab/Masonry";

const heights = [400, 195, 190];
import { BlogPost } from "../features/blogSlice";

const Item = styled(Paper)(({ theme }) => ({
backgroundColor: "primary.main",
...theme.typography.body2,
padding: theme.spacing(0.5),
textAlign: "center",
color: theme.palette.text.secondary,
...theme.applyStyles("dark", {
backgroundColor: "#1A2027",
}),
cursor: "pointer",
}));

export default function HomeMasonry() {
const heights = [400, 195, 195];

interface HomeMasonryProps {
firstThreeBlogs: BlogPost[];
}

export default function HomeMasonry({ firstThreeBlogs }: HomeMasonryProps) {
return (
<Box maxWidth="xl" sx={{ width: "auto", minHeight: 393, mt: "3rem" }}>
<Masonry columns={2} spacing={2}>
{heights.map((height, index) => (
<Item key={index} sx={{ height }}>
{index + 1}
<Box maxWidth="xl" sx={{ width: "auto", minHeight: 393, mt: "1rem" }}>
<Masonry columns={2} spacing={1}>
{firstThreeBlogs.map((blog, index) => (
<Item
key={blog._id}
sx={{
height: heights[index] || 200,
backgroundImage: `linear-gradient(to bottom, rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.6)), url(${blog.image})`,
backgroundSize: "cover",
backgroundPosition: "center",
}}
>
<Box sx={{ color: "white", padding: 1 }}>{blog.title}</Box>
</Item>
))}
</Masonry>
Expand Down
52 changes: 52 additions & 0 deletions src/features/blogSlice.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { createSlice } from "@reduxjs/toolkit";

export interface BlogPost {
_id: string;
userId: string;
categoryId: string;
title: string;
content: string;
image: string;
isPublish: boolean;
comments: string[];
likes: string[];
countOfVisitors: number;
createdAt: string;
updatedAt: string;
__v: number;
}

interface BlogInitial {
loading: boolean;
error: boolean;
blog: BlogPost[];
}

const initialState: BlogInitial = {
loading: false,
error: false,
blog: [],
};

const blogSlice = createSlice({
name: "blog",
initialState,
reducers: {
fetchStart: (state) => {
state.loading = true;
state.error = false;
},
getBlogSuccess: (state, { payload }) => {
state.loading = false;
state.error = false;
state.blog = payload;
},
fetchFail: (state) => {
state.loading = false;
state.error = true;
},
},
});

export const { fetchStart, getBlogSuccess, fetchFail } = blogSlice.actions;
export default blogSlice.reducer;
26 changes: 26 additions & 0 deletions src/hooks/useBlogCall.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import axios from "axios";
import { useDispatch } from "react-redux";
import { fetchFail, fetchStart } from "../features/authSlice";
import { getBlogSuccess } from "../features/blogSlice";

const BASE_URL: string = import.meta.env.VITE_BASE_URL;

const useBlogCall = () => {
const dispatch = useDispatch();

const getBlogs = async (): Promise<void> => {
dispatch(fetchStart());
try {
const { data } = await axios(`${BASE_URL}blogs`);
console.log(data);
dispatch(getBlogSuccess(data.data));
} catch (error) {
dispatch(fetchFail());
console.error(error);
}
};

return { getBlogs };
};

export default useBlogCall;
15 changes: 13 additions & 2 deletions src/pages/Home.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
import { Container } from "@mui/material";
import Navbar from "../components/Navbar";

import HomeMasonry from "../components/Masonry";
import useBlogCall from "../hooks/useBlogCall";
import { useEffect } from "react";
import { useSelector } from "react-redux";
import { RootState } from "../app/store";

const Home = () => {
const { getBlogs } = useBlogCall();
const { blog } = useSelector((state: RootState) => state.blog);
const firstThreeBlogs = blog.slice(0, 3);

useEffect(() => {
getBlogs();
}, []);

return (
<Container
maxWidth="xl"
Expand All @@ -12,7 +23,7 @@ const Home = () => {
}}
>
<Navbar />
<HomeMasonry />
<HomeMasonry firstThreeBlogs={firstThreeBlogs} />
</Container>
);
};
Expand Down

0 comments on commit f7725ba

Please sign in to comment.