diff --git a/src/components/blog/feed/index.tsx b/src/components/blog/feed/index.tsx index 58d0088..9dfc31b 100644 --- a/src/components/blog/feed/index.tsx +++ b/src/components/blog/feed/index.tsx @@ -1,16 +1,37 @@ -import React from "react"; +import React, { useEffect, useState } from "react"; import { useFeed, FeedItemData } from "../wp"; import { Post } from "./post"; import { FilterControl } from "./filter-control"; import { Spinner } from "../../spinner"; import { SortMethodSelection, defaultSortMethod, SortMethod } from "./sorting"; +import { favoritPosts } from "../../../users_api/UserAPI"; function PostList({ sortMethod }: { sortMethod: SortMethod }) { + const [favoritposts, setFavoritPosts] = useState([]); + const [loaded, setLoaded] = useState(false); const { loading, error, data } = useFeed(); - const [firstRenderDone, setFirstRenderDone] = React.useState(false); + const [firstRenderDone, setFirstRenderDone] = useState(false); - React.useEffect(() => { + const fetchFavorits = async () => { + let response; + try { + response = await favoritPosts(); + } catch (error) { + setFavoritPosts([]); + } + // @ts-ignore + let slugs = response.slugs; + setFavoritPosts(JSON.parse(JSON.stringify(slugs))); + setLoaded(true); + }; + + useEffect(() => { + const loggedInUser = localStorage.getItem("user"); + + if (loggedInUser) { + fetchFavorits(); + } if (data) setFirstRenderDone(true); }, [data]); @@ -26,15 +47,19 @@ function PostList({ sortMethod }: { sortMethod: SortMethod }) { if (loading && firstRenderDone) return ; - return ( -
- {(items[0] ? (items as FeedItemData[]).sort(sortMethod.fn) : items).map( - (data, i) => ( - - ) - )} -
- ); + if (loaded) { + return ( +
+ {(items[0] ? (items as FeedItemData[]).sort(sortMethod.fn) : items).map( + (data, i) => ( + + ) + )} +
+ ); + } + + return } export const Feed: React.FC = () => { diff --git a/src/components/blog/feed/post/index.tsx b/src/components/blog/feed/post/index.tsx index c958d0c..633dc93 100644 --- a/src/components/blog/feed/post/index.tsx +++ b/src/components/blog/feed/post/index.tsx @@ -9,8 +9,10 @@ import { BookmarkButton } from "../../single/bookmark-button"; import { DetailBar } from "./detail-bar"; import styles from "./post.module.css"; +import { LatestPostData } from "../../wp/latest_post"; export type ParsedPostData = { + slug: string; path: string; title: string; excerpt: string; @@ -22,10 +24,11 @@ export type ParsedPostData = { tags?: TagData[]; }; -export const Post: React.FC<{ data?: FeedItemData }> = ({ data }) => { +export const Post: React.FC<{ data?: FeedItemData | LatestPostData, favorits: string[]}> = ({ data, favorits }) => { const parsedData = React.useMemo( () => data && { + slug: data.slug, path: `/blog/${data.slug}`, title: data.title, excerpt: data.excerpt, @@ -84,7 +87,7 @@ export const Post: React.FC<{ data?: FeedItemData }> = ({ data }) => { )}
- +
); diff --git a/src/components/blog/post-list/index.tsx b/src/components/blog/post-list/index.tsx deleted file mode 100644 index af5613b..0000000 --- a/src/components/blog/post-list/index.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import React, { useEffect, useState } from "react"; -import { favoritPosts } from "../../../users_api/UserAPI"; - -import { usePosts } from "../wp"; -import { Post } from "./post"; - -export const PostList: React.FC = () => { - const [favoritposts, setFavoritPosts] = useState([]); - const { isLoading, error, data } = usePosts(); - - useEffect(() => { - const loggedInUser = localStorage.getItem('user'); - if (loggedInUser) { - const fetchFavorits = async () => { - let response; - try { - response = await favoritPosts() - } catch(error) { - console.log(error) - } - // @ts-ignore - let slugs = response.slugs - setFavoritPosts(JSON.parse(JSON.stringify(slugs))) - } - fetchFavorits(); - } - }, []) - - if (isLoading) return
Loading...
; - if (error || !data) return
Es ist ein Fehler aufgetreten.
; - - return ( -
- {data.map((postData, i) => ( - e === postData.slug) ? true : false}/> - ))} -
- ); -}; diff --git a/src/components/blog/post-list/post/bookmark-button/index.tsx b/src/components/blog/post-list/post/bookmark-button/index.tsx deleted file mode 100644 index 6f5c9aa..0000000 --- a/src/components/blog/post-list/post/bookmark-button/index.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import React from "react"; -import cn from "classnames"; - -import { BookmarkIcon } from "./icon"; - -import styles from "./bookmark.module.css"; -import { deFavorisePost, favorisePost } from "../../../../../users_api/UserAPI"; - -export const BookmarkButton: React.FC <{ slug: string, favorit: boolean }> = ({ slug, favorit }) => { - const [active, setActive] = React.useState(favorit); - - const updateFavorise = async (slug: string) => { - let favorite_blogpost = { - slug - } - if (active) { - try { - await deFavorisePost(favorite_blogpost) - } catch(error) { - console.log(error) - } - } else { - try { - await favorisePost(favorite_blogpost) - } catch(error) { - console.log(error) - } - } - } - - return ( - - ); -}; diff --git a/src/components/blog/post-list/post/index.tsx b/src/components/blog/post-list/post/index.tsx deleted file mode 100644 index 848e0b6..0000000 --- a/src/components/blog/post-list/post/index.tsx +++ /dev/null @@ -1,65 +0,0 @@ -import React from "react"; -import { Link } from "react-router-dom"; - -import { Media } from "../media"; -import { PostData } from "../../wp"; - -import { BookmarkButton } from "./bookmark-button"; -import { DetailBar } from "./detail-bar"; - -// const Link: React.FC<{ slug: string; className: string; }> = ({ slug, className }) => ( -// -// ); - -export const Post: React.FC<{ data: PostData, favorit: boolean }> = ({ - data: { title, slug, excerpt, featured_media, date, _embedded }, - favorit -}) => { - const path = `/blog/${slug}`; - - return ( -
- -
- {featured_media ? ( - - ) : null} -
- -
-
- -
- {excerpt && ( - <> -
- - mehr lesen - - - )} -
-
- -
-
- -
-
- ); -}; diff --git a/src/components/blog/single/bookmark-button/index.tsx b/src/components/blog/single/bookmark-button/index.tsx index 8ec0884..e666e9b 100644 --- a/src/components/blog/single/bookmark-button/index.tsx +++ b/src/components/blog/single/bookmark-button/index.tsx @@ -1,20 +1,52 @@ -import React from "react"; +import React, { useEffect, useState } from "react"; import cn from "classnames"; import { BookmarkIcon } from "./icon"; import styles from "./bookmark.module.css"; +import { deFavorisePost, favorisePost } from "../../../../users_api/UserAPI"; export const BookmarkButton: React.FC<{ disabled?: boolean; onSolidBackground?: boolean; -}> = ({ disabled, onSolidBackground }) => { - const [active, setActive] = React.useState(false); + slug: string; + posts: string[]; +}> = ({ disabled, onSolidBackground, slug, posts }) => { + const [active, setActive] = useState(false); + + const updateFavorise = async (slug: string) => { + let favorite_blogpost = { + slug, + }; + if (active) { + try { + await deFavorisePost(favorite_blogpost); + } catch (error) { + } + } else { + try { + await favorisePost(favorite_blogpost); + } catch (error) { + } + } + }; + + + useEffect(() => { + if (posts.includes(slug)) { + setActive(true); + } + }, [posts, slug]); + + return ( - - - - ) : ( - <> - - - - - - - - )} -
- - - - ); -}; diff --git a/src/components/layout/header/desktop-nav/index.tsx b/src/components/layout/header/desktop-nav/index.tsx index 4edd4fa..9bcadb2 100644 --- a/src/components/layout/header/desktop-nav/index.tsx +++ b/src/components/layout/header/desktop-nav/index.tsx @@ -7,10 +7,12 @@ import type { NavItem } from ".."; import { Button } from "../button"; import { SearchButton } from "../search-button"; -export const DesktopNav: React.FC<{ items: NavItem[]; onDark?: boolean }> = ({ - items, - onDark, -}) => { +export const DesktopNav: React.FC<{ + items: NavItem[]; + onDark?: boolean; + user?: any; + handleLogOut: () => void; +}> = ({ items, onDark, user, handleLogOut }) => { const { pathname } = useLocation(); return ( @@ -37,10 +39,27 @@ export const DesktopNav: React.FC<{ items: NavItem[]; onDark?: boolean }> = ({
- - + {user ? ( + <> + + + + + + ) : ( + <> + + + + + + + + )}
); diff --git a/src/components/layout/header/index.tsx b/src/components/layout/header/index.tsx index f244da6..95b85d5 100644 --- a/src/components/layout/header/index.tsx +++ b/src/components/layout/header/index.tsx @@ -1,9 +1,10 @@ -import React from "react"; +import React, { useEffect, useState } from "react"; import cn from "classnames"; -import { Link } from "react-router-dom"; +import { Link, useHistory } from "react-router-dom"; import { DesktopNav } from "./desktop-nav"; import { MobileNav } from "./mobile-nav"; +import { logout } from "../../../users_api/UserAPI"; export type NavItem = { path: string; @@ -15,37 +16,63 @@ const items: NavItem[] = [ { path: "/blog", label: "Archiv" }, ]; -export const Header: React.FC<{ onDark?: boolean }> = ({ onDark }) => ( -
-
-
-
-
- -
- Klimabox - -
-
-
- +export const Header: React.FC<{ onDark?: boolean }> = ({ onDark }) => { + const [user, setUser] = useState(undefined); + let history = useHistory(); + + useEffect(() => { + const loggedInUser = localStorage.getItem('user'); + if (loggedInUser) { + const foundUser = JSON.parse(loggedInUser); + setUser(foundUser); + } else { + setUser(undefined) + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [localStorage.getItem('user')]); + + const handleLogout = async () => { + try { + await logout() + } catch(error) { + console.log(error) + } + localStorage.removeItem('user') + history.push('/') + } + + return ( +
+
+
+
+
+ +
+ Klimabox +
-
- +
+
+ handleLogout()}/> +
+
+ handleLogout()} /> +
-
-); + ); +}; diff --git a/src/components/layout/header/mobile-nav/index.tsx b/src/components/layout/header/mobile-nav/index.tsx index d251843..c6b31ae 100644 --- a/src/components/layout/header/mobile-nav/index.tsx +++ b/src/components/layout/header/mobile-nav/index.tsx @@ -10,9 +10,13 @@ import { SearchButton } from "../search-button"; export function MobileNav({ items, onDark, + user, + handleLogOut, }: { items: NavItem[]; onDark?: boolean; + user?: any; + handleLogOut: () => void; }) { const { pathname } = useLocation(); const [open, setOpen] = React.useState(false); @@ -48,12 +52,31 @@ export function MobileNav({
-
- -
-
- -
+ {user ? ( + <> +
+ + + +
+
+ +
+ + ) : ( + <> +
+ + + +
+
+ + + +
+ + )}
diff --git a/src/components/layout/index.tsx b/src/components/layout/index.tsx index 243e49d..5d5a6e9 100644 --- a/src/components/layout/index.tsx +++ b/src/components/layout/index.tsx @@ -1,7 +1,7 @@ import React from "react"; -import { Header } from "./header"; import { Footer } from "./footer"; +import { Header } from "./header"; import { SideNav } from "./side-nav"; type LayoutProps = { diff --git a/src/components/user-dashboard/favorite-posts/index.tsx b/src/components/user-dashboard/favorite-posts/index.tsx index e25bb62..f77a20c 100644 --- a/src/components/user-dashboard/favorite-posts/index.tsx +++ b/src/components/user-dashboard/favorite-posts/index.tsx @@ -1,10 +1,20 @@ import React from "react"; +import { Post } from "../../blog/feed/post"; +import { FeedItemData, useFeed } from "../../blog/wp"; -import { Post } from "../../blog/post-list/post"; -import { useFavoritPost } from "../../blog/wp/favorit_posts"; +import { Spinner } from "../../spinner"; + +export const FavoritePosts: React.FC <{ posts: Array, loaded: boolean }> = ({ posts, loaded }) => { + const { loading, error, data } = useFeed(); + + const items = React.useMemo>( + () => + data + ? data.posts.edges.map((edge) => edge.node) + : new Array(9).fill(undefined), + [data] + ); -export const FavoritePosts: React.FC <{ posts: Array }> = ({ posts }) => { - const { isLoading, error, data } = useFavoritPost(posts); if (posts.length === 0) { return (
@@ -17,7 +27,7 @@ export const FavoritePosts: React.FC <{ posts: Array }> = ({ posts }) =
) } else { - if (isLoading) return
Loading...
; + if (loading || !loaded) return ; if (error || !data) return
Es ist ein Fehler aufgetreten.
; return ( @@ -26,10 +36,18 @@ export const FavoritePosts: React.FC <{ posts: Array }> = ({ posts }) = Meine lieblings Posts
- {data.map((postData, i) => ( - - ))} -
+ {(items.map( + (data, i) => { + if (posts.some((e) => e === data?.slug)) { + return ( + + ) + } + return null; + } + + ))} +
); } diff --git a/src/components/user-dashboard/index.tsx b/src/components/user-dashboard/index.tsx index 2f03f04..aec6866 100644 --- a/src/components/user-dashboard/index.tsx +++ b/src/components/user-dashboard/index.tsx @@ -15,9 +15,11 @@ export default interface TopicInterface { export const UserDashboard: React.FC = () => { const [favoritposts, setFavoritPosts] = useState([]); + const [favoritsLoaded, setFavortitsLoaded] = useState(false); const [topics, setTopics] = useState([]); const [tickets, setTickets] = useState([]); + const fetchFavorits = async () => { let response; try { @@ -30,6 +32,7 @@ export const UserDashboard: React.FC = () => { let slugs = response.slugs setFavoritPosts(JSON.parse(JSON.stringify(slugs))) } + setFavortitsLoaded(true); } const fetchTopics = async () => { @@ -103,7 +106,6 @@ export const UserDashboard: React.FC = () => { fetchTickets(); } - return (
@@ -116,11 +118,11 @@ export const UserDashboard: React.FC = () => {
- +
- +
); diff --git a/src/components/user-dashboard/latest-blog-post/index.tsx b/src/components/user-dashboard/latest-blog-post/index.tsx index 8ab727a..248bdf4 100644 --- a/src/components/user-dashboard/latest-blog-post/index.tsx +++ b/src/components/user-dashboard/latest-blog-post/index.tsx @@ -1,21 +1,23 @@ import React from "react"; +import { Post } from "../../blog/feed/post"; -import { Post } from "../../blog/post-list/post"; -import { usePost } from "../../blog/wp"; +import { LatestPostData, useLatestPost } from "../../blog/wp/latest_post"; +import { Spinner } from "../../spinner"; -export const LatestBlogPost: React.FC <{ posts: Array }> = ({ posts }) => { - const { isLoading, error, data } = usePost("dauerbrenner-braunkohleausstieg-klimaschuetzerinnen-sitzen-auf-heissen-kohlen"); +export const LatestBlogPost: React.FC <{ posts: Array, loaded: boolean }> = ({ posts, loaded }) => { + const { loading, error, data } = useLatestPost(); + const item = React.useMemo( + () => + data + ? data.posts.edges[0].node + : undefined, + [data] + ); - if (isLoading) return
Loading...
; + if (loading || !loaded) return
; if (error || !data) return
Es ist ein Fehler aufgetreten.
; - let favorit = false; - posts.forEach((post) => { - if (post === data.slug) { - favorit = true - } - }) return (
@@ -23,7 +25,7 @@ export const LatestBlogPost: React.FC <{ posts: Array }> = ({ posts }) Latest Post
- +
);