diff --git a/src/components/fetchAnArticle/AnArticle.tsx b/src/components/fetchAnArticle/AnArticle.tsx new file mode 100644 index 0000000..54d35d8 --- /dev/null +++ b/src/components/fetchAnArticle/AnArticle.tsx @@ -0,0 +1,80 @@ +import { useArticleViewModel } from "article/controller/articleViewModel"; +import { useArticleStore } from "article/data/articleStoreImplementation"; +import { useEffect } from "react"; +import * as ArticlePart from "../../components/Article/Article"; +import { useParams } from "react-router"; +import AskeletonArticle from "./AskeletonArticle"; +import Container from "components/Container"; +import NotFound from "./NotFound"; +import { SVGSearch } from "components/icons"; +import BaseLayout from "components/BaseLayout"; + +const AnArticle = () => { + const store = useArticleStore(); + const { article, hasError, shouldShowLoading } = useArticleViewModel(store); + + const { id } = useParams(); + const newId = `${id}`; + + useEffect(() => { + store.getArticle(newId); + }, [id]); + + if (hasError) { + return <NotFound />; + } + return ( + <BaseLayout> + <Container variant="straight"> + {shouldShowLoading ? ( + <AskeletonArticle /> + ) : ( + <> + <ArticlePart.Article.Breadcumbs> + {article?.topic} + </ArticlePart.Article.Breadcumbs> + <div className="flex flex-col gap-4 pb-4"> + <ArticlePart.Article.Title className="text-3xl "> + {article?.title} + </ArticlePart.Article.Title> + <ArticlePart.Article.Authors> + {article?.authors !== undefined ? article?.authors : "Unknown"} + </ArticlePart.Article.Authors> + <hr></hr> + </div> + + <ArticlePart.Article.InteractionButtons emphasis="high" /> + {article?.tags && ( + <div className="keywords my-10 flex flex-col gap-2"> + <ArticlePart.Article.Title className="text-2xl"> + Keywords + </ArticlePart.Article.Title> + + <ArticlePart.Article.Keywords className="transition ease-in-out delay-50"> + {article?.tags} + </ArticlePart.Article.Keywords> + </div> + )} + <div className="abstract my-10 flex flex-col gap-2"> + <ArticlePart.Article.Title className="text-2xl"> + Abstract + </ArticlePart.Article.Title> + <ArticlePart.Article.Description> + {article?.summary !== undefined ? ( + article?.summary + ) : ( + <div className=" bg-gray-100 w-full stroke-gray-800 text-xl flex justify-center py-1"> + <SVGSearch className="w-14" /> + </div> + )} + </ArticlePart.Article.Description> + </div> + </> + )} + </Container> + </BaseLayout> + ); +}; + +// \n +export default AnArticle; diff --git a/src/components/fetchAnArticle/AnArticleBody.tsx b/src/components/fetchAnArticle/AnArticleBody.tsx new file mode 100644 index 0000000..55d7f95 --- /dev/null +++ b/src/components/fetchAnArticle/AnArticleBody.tsx @@ -0,0 +1,58 @@ +import { useArticleViewModel } from "article/controller/articleViewModel"; +import { useArticleStore } from "article/data/articleStoreImplementation"; +import "react-loading-skeleton/dist/skeleton.css"; +import Skeleton from "react-loading-skeleton"; +import { useParams } from "react-router"; +import { useEffect } from "react"; + +/* -------------------------------------------------------------------------- */ +/* Components */ +/* -------------------------------------------------------------------------- */ +import * as ArticlePart from "../../components/Article/Article"; +import BaseLayout from "components/BaseLayout"; +import Container from "components/Container"; +import NotFound from "./NotFound"; + +const AnArticleBody = () => { + const store = useArticleStore(); + const { article, hasError, shouldShowLoading } = useArticleViewModel(store); + const { id } = useParams(); + const newId = `${id}`; + useEffect(() => { + store.getArticle(newId); + }, [id]); + if (hasError) <NotFound />; + return ( + <BaseLayout> + <Container variant="straight"> + {shouldShowLoading ? ( + <> + <Skeleton count={1} /> + <div className="gap-4 py-12 px-20"> + <Skeleton + count={1} + containerClassName=" text-3xl" + className="mb-6" + /> + <Skeleton count={15} containerClassName="" /> + </div> + </> + ) : ( + <> + <ArticlePart.Article.Breadcumbs> + {article?.topic} + </ArticlePart.Article.Breadcumbs> + <div className="gap-4 py-12 px-20"> + <ArticlePart.Article.Title className="text-3xl"> + {article?.title} + </ArticlePart.Article.Title> + <div className="py-6">{article?.content}</div> + </div> + </> + )} + </Container> + </BaseLayout> + ); +}; + +export default AnArticleBody; diff --git a/src/components/fetchAnArticle/AskeletonArticle.tsx b/src/components/fetchAnArticle/AskeletonArticle.tsx new file mode 100644 index 0000000..f0b9702 --- /dev/null +++ b/src/components/fetchAnArticle/AskeletonArticle.tsx @@ -0,0 +1,59 @@ +import Skeleton from "react-loading-skeleton"; +import "react-loading-skeleton/dist/skeleton.css"; +const AskeletonArticle = () => { + return ( + <> + <Skeleton count={1} /> + <div className="flex flex-col gap-4 pb-4"> + <Skeleton count={1} containerClassName="title w-3/4 text-2xl" /> + <Skeleton count={1} containerClassName="authors w-1/4" /> + <hr></hr> + </div> + <div className="interActions-buttons flex"> + <Skeleton count={1} containerClassName="w-1/12 mr-2 text-xl" /> + <Skeleton count={1} containerClassName="w-1/12 mr-2 text-xl" /> + <Skeleton count={1} containerClassName="w-1/12 mr-2 text-xl" /> + <Skeleton count={1} containerClassName="w-1/12 mr-2 text-xl" /> + </div> + <div className=" my-10 flex flex-col gap-2"> + <Skeleton + count={1} + className="keywords-title text-2xl" + containerClassName="w-1/4" + /> + <div className="flex"> + <Skeleton + count={1} + className="border-2 border-[#ebebeb]" + containerClassName="w-1/6 mr-2" + baseColor="transparent" + /> + <Skeleton + count={1} + className="border-2 border-[#ebebeb]" + containerClassName="w-1/6 mr-2" + baseColor="transparent" + /> + <Skeleton + count={1} + className="border-2 border-[#ebebeb]" + containerClassName="w-1/6 mr-2" + baseColor="transparent" + /> + <Skeleton + count={1} + className="border-2 border-[#ebebeb]" + containerClassName="w-1/6 mr-2" + baseColor="transparent" + /> + </div> + </div> + <div className="my-10 flex flex-col gap-2"> + <Skeleton count={1} width={200} className="text-2xl" /> + <Skeleton count={25} /> + </div> + </> + ); +}; + +export default AskeletonArticle; diff --git a/src/components/fetchAnArticle/NotFound.tsx b/src/components/fetchAnArticle/NotFound.tsx new file mode 100644 index 0000000..5db7e0d --- /dev/null +++ b/src/components/fetchAnArticle/NotFound.tsx @@ -0,0 +1,33 @@ +import React from "react"; +import Container from "components/Container"; +import { Button } from "components/Button/Button"; +import Link from "components/Link"; + +const NotFound = () => { + return ( + <Container + variant="straight" + className="flex flex-col items-center justify-center + font-serif h-screen my-auto + " + > + <div + className="bg-[url('https://cdn.dribbble.com/users/285475/screenshots/2083086/dribbble_1.gif')] + h-[450px] + w-full text-center text-7xl " + > + 404 + </div> + <h3 className="font-bold text-2xl text-center">Page does not exist</h3> + <h4 className="text-center"> + Maybe you got a broken link, or maybe you made a misprint in the address + bar + </h4> + <Button className="my-4"> + <Link href="/">Go to home</Link> + </Button> + </Container> + ); +}; + +export default NotFound;