diff --git a/frontend/src/components/PostFeed.component.jsx b/frontend/src/components/PostFeed.component.jsx index c94bf4b..c9de6e8 100644 --- a/frontend/src/components/PostFeed.component.jsx +++ b/frontend/src/components/PostFeed.component.jsx @@ -6,7 +6,8 @@ import { Stack, Text, Spinner, - useBreakpointValue, VStack + useBreakpointValue, VStack, + Tabs, TabList, TabPanels, Tab, TabPanel } from '@chakra-ui/react'; import { PostContext } from '../context/PostContext'; import PostFeedCard from './PostFeedCard.component'; @@ -14,7 +15,7 @@ import ProgramFeedCard from './ProgramFeedCard.component'; import UserJoinedProgramsCard from './UserJoinedProgramsCard.component' function PostFeed() { - const { posts, isLoadingPosts, programs, isFetchingPrograms } = useContext(PostContext); + const { posts, isLoadingPosts, programs, isFetchingPrograms, recommendedPrograms, explorePrograms, forYouPosts, explorePosts } = useContext(PostContext); const isLoading = isLoadingPosts || isFetchingPrograms; @@ -40,19 +41,6 @@ function PostFeed() { }) } > - {/* Today's Programs */} - {/* {programs.length > 0 && ( - - Your Progress Today - - - )} */} - {programs.length > 0 && ( Your Active Programs: @@ -67,7 +55,7 @@ function PostFeed() { width={'full'} // Full width on small screens, larger on desktop > Recommended Programs - {programs.length > 0 ? ( + {recommendedPrograms.length > 0 ? ( programs.map((program) => ( )) @@ -75,29 +63,68 @@ function PostFeed() { No programs to recommend right now. )} - - {/* Main Feed */} - - - Your Feed - {isLoading ? ( - - - Loading Content... - - ) : posts.length > 0 ? ( - posts.map((post) => ( - + {/* Explore Programs */} + + Explore Programs + {explorePrograms.length > 0 ? ( + programs.map((program) => ( + )) ) : ( - Nothing to show here... + No programs to explore right now. )} - - + + + + {/* + Tabs for different types of posts. Explore and For You + */} + { + isLoading ? ( + + ) : ( + + + + For You + Explore + + + + {forYouPosts.length > 0 ? ( + forYouPosts.map((post) => ( + + )) + ) : ( + No posts for you right now. + )} + + + {explorePosts.length > 0 ? ( + explorePosts.map((post) => ( + + )) + ) : ( + No posts to explore right now. + )} + + + + + ) + } ); } diff --git a/frontend/src/context/PostContext.jsx b/frontend/src/context/PostContext.jsx index 42fdd1f..5343b4c 100644 --- a/frontend/src/context/PostContext.jsx +++ b/frontend/src/context/PostContext.jsx @@ -18,6 +18,10 @@ export const PostContext = createContext( bookmarkedPosts: [], isLoadingBookmarks: false, isFetchingBookmarks: false, + recommendedPrograms: [], + explorePrograms: [], + forYouPosts: [], + explorePosts: [], } ) @@ -26,6 +30,10 @@ export const PhaseContextProvider = ({ children }) => { const [programs, setPrograms] = useState([]) const [bookmarkedPosts, setBookmarkedPosts] = useState([]) const [tags, setTags] = useState([]) + const [recommendedPrograms, setRecommendedPrograms] = useState([]) + const [explorePrograms, setExplorePrograms] = useState([]) + const [forYouPosts, setForYouPosts] = useState([]) + const [explorePosts, setExplorePosts] = useState([]) const sessionToken = useSelector(userSessionToken) @@ -89,6 +97,60 @@ export const PhaseContextProvider = ({ children }) => { refetchOnWindowFocus: false }) + const { + data: recommendedProgramsData, + isFetching: recommendedProgramsIsFetching, + isLoading: recommendedProgramsIsLoading, + } = useQuery({ + queryKey: ['training-programs'], + queryFn: async () => { + const response = await apiInstance(sessionToken).get('/api/training-programs/recommended') + return response.data + }, + refetchOnWindowFocus: false, + enabled: !!sessionToken + }) + + const { + data: exploreProgramsData, + isFetching: exploreProgramsIsFetching, + isLoading: exploreProgramsIsLoading, + } = useQuery({ + queryKey: ['training-programs'], + queryFn: async () => { + const response = await apiInstance().get('/api/training-programs/explore') + return response.data + }, + refetchOnWindowFocus: false + }) + + const { + data: forYouPostsData, + isFetching: forYouPostsIsFetching, + isLoading: forYouPostsIsLoading, + } = useQuery({ + queryKey: ['posts'], + queryFn: async () => { + const response = await apiInstance(sessionToken).get('/api/posts/for-you') + return response.data + }, + refetchOnWindowFocus: false, + enabled: !!sessionToken + }) + + const { + data: explorePostsData, + isFetching: explorePostsIsFetching, + isLoading: explorePostsIsLoading, + } = useQuery({ + queryKey: ['posts'], + queryFn: async () => { + const response = await apiInstance().get('/api/posts/explore') + return response.data + }, + refetchOnWindowFocus: false + }) + useEffect(() => { if (postsData && !postsIsFetching) { // Order posts by createdAt date @@ -114,6 +176,35 @@ export const PhaseContextProvider = ({ children }) => { } }, [tagsData, tagsIsFetching]) + useEffect(() => { + if (recommendedProgramsData && !recommendedProgramsIsFetching) { + setRecommendedPrograms(recommendedProgramsData) + } + }, [recommendedProgramsData, recommendedProgramsIsFetching]) + + useEffect(() => { + if (exploreProgramsData && !exploreProgramsIsFetching && recommendedProgramsData) { + // Map through the data and set the state. Explore programs are not user-specific not should not include recommendations + const explorePrograms = exploreProgramsData.filter(program => !recommendedProgramsData.some(recommendedProgram => recommendedProgram.id === program.id)) + + setExplorePrograms(explorePrograms) + } + }, [exploreProgramsData, exploreProgramsIsFetching, recommendedProgramsData]) + + useEffect(() => { + if (forYouPostsData && !forYouPostsIsFetching) { + setForYouPosts(forYouPostsData) + } + }, [forYouPostsData, forYouPostsIsFetching]) + + useEffect(() => { + if (explorePostsData && !explorePostsIsFetching && forYouPostsData) { + const explorePosts = explorePostsData.filter(post => !forYouPostsData.some(forYouPost => forYouPost.id === post.id)) + + setExplorePosts(explorePosts) + } + }, [explorePostsData, explorePostsIsFetching, forYouPostsData]) + return ( { isFetchingBookmarks: bookmarksIsFetching, tags: tags, isLoadingTags: tagsIsLoading, - isFetchingTags: tagsIsFetching + isFetchingTags: tagsIsFetching, + recommendedPrograms, + explorePrograms, + forYouPosts, + explorePosts, }}> {children}