From f4e83e0cc8bf2d9ed46bf9f1cdb55aee45fa7226 Mon Sep 17 00:00:00 2001 From: Maximus <ten.maksim97@gmail.com> Date: Thu, 8 Sep 2022 11:11:22 +0300 Subject: [PATCH 1/2] updated link to universal component --- src/components/typography/Link.tsx | 54 +++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 13 deletions(-) diff --git a/src/components/typography/Link.tsx b/src/components/typography/Link.tsx index 15a3eb8..184bbb7 100644 --- a/src/components/typography/Link.tsx +++ b/src/components/typography/Link.tsx @@ -1,21 +1,49 @@ import React from "react"; +import { NavLink, NavLinkProps } from "react-router-dom"; +import classNames from "classnames"; type Props = { - href?: string; + to: string; children: React.ReactNode; disabled?: boolean; className?: string; -} & Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, "">; +} & NavLinkProps & + Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, "">; -export default function Link({ href, children, disabled, ...props }: Props) { - return ( - // eslint-disable-next-line jsx-a11y/anchor-is-valid - <a - href={disabled ? undefined : href} - aria-disabled={disabled} - {...props} - > - {children} - </a> - ); +function getURL(to: string): URL { + try { + return new URL(to); + } catch { + let outurl = `${window.location.origin}${ + to.startsWith("/") ? to : "/" + to + }`; + return new URL(outurl); + } +} + +export default function Link({ + to, + children, + disabled, + className, + ...props +}: Props) { + const link = + getURL(to).hostname === window.location.hostname ? ( + <NavLink + to={getURL(to).pathname} + className={classNames({ "pointer-events-none": disabled }, className)} + > + {children} + </NavLink> + ) : ( + <a + href={disabled ? undefined : getURL(to).origin} + aria-disabled={disabled} + {...props} + > + {children} + </a> + ); + return <div>{link}</div>; } From 956109f34ac02ce68f761dd4e5438196ca5e8bab Mon Sep 17 00:00:00 2001 From: Maximus <ten.maksim97@gmail.com> Date: Thu, 8 Sep 2022 11:44:02 +0300 Subject: [PATCH 2/2] updated imports, mock authors and articles request, renamed files --- src/components/Card.tsx | 5 +- ...rticales.tsx => FeaturedArticlesCards.tsx} | 68 +++++++++++++++---- ...edAuthors.tsx => FeaturedAuthorsCards.tsx} | 44 +++++++++--- ...les.tsx => FeaturedArticlesCategories.tsx} | 0 src/components/parts/Footer.tsx | 42 +++++++----- src/components/typography/RouterLink.tsx | 2 +- 6 files changed, 120 insertions(+), 41 deletions(-) rename src/components/{FeaturedArticales.tsx => FeaturedArticlesCards.tsx} (72%) rename src/components/{FeaturedAuthors.tsx => FeaturedAuthorsCards.tsx} (76%) rename src/components/parts/{FeaturedArticles.tsx => FeaturedArticlesCategories.tsx} (100%) diff --git a/src/components/Card.tsx b/src/components/Card.tsx index 49818fc..39cabd7 100644 --- a/src/components/Card.tsx +++ b/src/components/Card.tsx @@ -6,8 +6,7 @@ import React from "react"; /* -------------------------------------------------------------------------- */ import Typography from "./typography/Typography"; import Heading from "./typography/Heading"; -import Link from "./Link"; - +import Link from "./typography/Link"; /* -------------------------------------------------------------------------- */ /* Props */ /* -------------------------------------------------------------------------- */ @@ -102,7 +101,7 @@ Card.CardAction = function CardCardAction({ }: CardActionProps) { return ( <Link - href={href} + to={href} className={classNames([className, "flex items-center gap-2"])} > {children} diff --git a/src/components/FeaturedArticales.tsx b/src/components/FeaturedArticlesCards.tsx similarity index 72% rename from src/components/FeaturedArticales.tsx rename to src/components/FeaturedArticlesCards.tsx index 37eaef6..2052fa0 100644 --- a/src/components/FeaturedArticales.tsx +++ b/src/components/FeaturedArticlesCards.tsx @@ -12,12 +12,56 @@ import Typography from "./typography/Typography"; import SkeletonCard from "./SkeletonCard"; import AspectRatio from "./AspectRatio"; import Card from "./Card"; -import Link from "./Link"; +import Link from "./typography/Link"; /* -------------------------------------------------------------------------- */ -/* Data */ +/* Article mock data */ /* -------------------------------------------------------------------------- */ -import Articales from "./Articales.json"; + +const articles = [ + { + CoverImg: + "https://i.kinja-img.com/gawker-media/image/upload/t_original/ijsi5fzb1nbkbhxa2gc1.png", + Body: "1 ipsum dolor sit amet consectetur adipisicing elit.Consequuntur maxime, adipisicing elit.sit amet consectetur adipisicing elit.Consequuntur ma", + Link: "http://pinterest.com", + }, + { + CoverImg: + "https://i.kinja-img.com/gawker-media/image/upload/t_original/ijsi5fzb1nbkbhxa2gc1.png", + Body: "2 ipsum dolor sit amet consectetur adipisicing elit.Consequuntur maxime, adipisicing elit.", + Link: "http://pinterest.com", + }, + { + CoverImg: + "https://i.kinja-img.com/gawker-media/image/upload/t_original/ijsi5fzb1nbkbhxa2gc1.png", + Body: "2 ipsum dolor sit amet consectetur adipisicing elit.Consequuntur maxime, adipisicing elit.", + Link: "http://pinterest.com", + }, + { + CoverImg: + "https://i.kinja-img.com/gawker-media/image/upload/t_original/ijsi5fzb1nbkbhxa2gc1.png", + Body: "2 ipsum dolor sit amet consectetur adipisicing elit.Consequuntur maxime, adipisicing elit.", + Link: "http://pinterest.com", + }, + { + CoverImg: + "https://i.kinja-img.com/gawker-media/image/upload/t_original/ijsi5fzb1nbkbhxa2gc1.png", + Body: "2 ipsum dolor sit amet consectetur adipisicing elit.Consequuntur maxime, adipisicing elit.", + Link: "http://pinterest.com", + }, + { + CoverImg: + "https://i.kinja-img.com/gawker-media/image/upload/t_original/ijsi5fzb1nbkbhxa2gc1.png", + Body: "2 ipsum dolor sit amet consectetur adipisicing elit.Consequuntur maxime, adipisicing elit.", + Link: "http://pinterest.com", + }, + { + CoverImg: + "https://i.kinja-img.com/gawker-media/image/upload/t_original/ijsi5fzb1nbkbhxa2gc1.png", + Body: "2 ipsum dolor sit amet consectetur adipisicing elit.Consequuntur maxime, adipisicing elit.", + Link: "http://pinterest.com", + }, +]; /* -------------------------------------------------------------------------- */ /* Icons */ @@ -42,22 +86,22 @@ import "swiper/css"; /* -------------------------------------------------------------------------- */ let twoCards: boolean = false; let threeCards: boolean = false; -console.log(`Number of cards ${Articales.length}`); -if (Articales.length == 2) { +console.log(`Number of cards ${articles.length}`); +if (articles.length == 2) { twoCards = true; -} else if (Articales.length == 3) { +} else if (articles.length == 3) { threeCards = true; } SwiperCore.use([Navigation]); -const FeaturedArticales = () => { +const FeaturedArticlesCards = () => { const navigationPrevRef = useRef(null); const navigationNextRef = useRef(null); const paginationRef = useRef(null); return ( - <div className="slider-wrapper Articales"> + <div className="slider-wrapper articles"> <div className="flex justify-end gap-2 my-2"> <div className="prev inline-flex justify-center items-center @@ -80,7 +124,7 @@ const FeaturedArticales = () => { <Swiper slidesPerView={1.25} slidesPerGroup={1} - loop={Articales.length > 4 ? true : false} + loop={articles.length > 4 ? true : false} pagination={{ el: ".pagination", clickable: true }} navigation={{ prevEl: ".prev", @@ -108,7 +152,7 @@ const FeaturedArticales = () => { loopFillGroupWithBlank={true} modules={[Pagination, Navigation]} > - {Articales.map((Articale) => ( + {articles.map((Articale) => ( <SwiperSlide> <Card className="flex-1"> <Card.CardContent> @@ -124,7 +168,7 @@ const FeaturedArticales = () => { </Card.CardContent> <Card.CardAction href={Articale.Link}> - <Link> + <Link to="*"> <Typography className="text-blue-500 font-bold"> Read More </Typography> @@ -185,4 +229,4 @@ const FeaturedArticales = () => { ); }; -export default FeaturedArticales; +export default FeaturedArticlesCards; diff --git a/src/components/FeaturedAuthors.tsx b/src/components/FeaturedAuthorsCards.tsx similarity index 76% rename from src/components/FeaturedAuthors.tsx rename to src/components/FeaturedAuthorsCards.tsx index c81a1d4..9de34fa 100644 --- a/src/components/FeaturedAuthors.tsx +++ b/src/components/FeaturedAuthorsCards.tsx @@ -18,9 +18,33 @@ import "./styles.css"; import "swiper/css"; /* -------------------------------------------------------------------------- */ -/* Authors */ +/* Authors data mock */ /* -------------------------------------------------------------------------- */ -import Authors from "./Authors.json"; +const authors = [ + { + Title: "JSON Three", + Body: "Lorem ipsum dolor sit amet consectetur adipisicing elit.Consequuntur maxime, adipisicing elit.am elit.Consequuntur maxime, adipisicing elit.", + Link: "http://pinterest.com", + }, + { + Title: "JSON Two", + Body: "Lorem ipsum dolor sit amet consectetur adipisicing elit.Consequuntur maxime, adipisicing elit.am elit.Consequuntur maxime, libero est unde sapiente repellendus quam", + Link: "http://pinterest.com", + img: "https://i.kinja-img.com/gawker-media/image/upload/t_original/ijsi5fzb1nbkbhxa2gc1.png", + }, + { + Title: "JSON Two", + Body: "Lorem ipsum dolor sit amet consectetur adipisicing elit.Consequuntur maxime, adipisicing elit.am elit.Consequuntur maxime, libero est unde sapiente repellendus quam", + Link: "http://pinterest.com", + img: "https://i.kinja-img.com/gawker-media/image/upload/t_original/ijsi5fzb1nbkbhxa2gc1.png", + }, + { + Title: "JSON Two", + Body: "Lorem ipsum dolor sit amet consectetur adipisicing elit.Consequuntur maxime, adipisicing elit.am elit.Consequuntur maxime, libero est unde sapiente repellendus quam", + Link: "http://pinterest.com", + img: "https://i.kinja-img.com/gawker-media/image/upload/t_original/ijsi5fzb1nbkbhxa2gc1.png", + }, +]; /* -------------------------------------------------------------------------- */ /* Icons */ @@ -38,17 +62,17 @@ SwiperCore.use([Navigation]); /* -------------------------------------------------------------------------- */ let twoCards: boolean = false; let threeCards: boolean = false; -console.log(`Number of cards ${Authors.length}`); -if (Authors.length == 2) { +console.log(`Number of cards ${authors.length}`); +if (authors.length == 2) { twoCards = true; -} else if (Authors.length == 3) { +} else if (authors.length == 3) { threeCards = true; } /** * Featured authors component to display ... */ -export default function FeaturedAuthors(): JSX.Element { +export default function FeaturedAuthorsCards(): JSX.Element { return ( <div> {/* The Title of Featured Authors section */} @@ -60,7 +84,7 @@ export default function FeaturedAuthors(): JSX.Element { slidesPerView={1.25} slidesPerGroup={1} spaceBetween={25} - loop={Authors.length > 4 ? true : false} + loop={authors.length > 4 ? true : false} loopFillGroupWithBlank={false} breakpoints={{ 768: { @@ -81,7 +105,7 @@ export default function FeaturedAuthors(): JSX.Element { }, }} > - {Authors.map((card) => ( + {authors.map((card) => ( <SwiperSlide> <Card className="flex-1"> <Card.CardContent> @@ -109,7 +133,9 @@ export default function FeaturedAuthors(): JSX.Element { </Card.CardContent> <Card.CardAction href={card.Link}> - <Link className="text-blue-500 font-bold ">See More</Link> + <Link className="text-blue-500 font-bold" to="*"> + See More + </Link> <SVGCaretRight className="fill-blue-500 w-4 h-4" /> </Card.CardAction> </Card> diff --git a/src/components/parts/FeaturedArticles.tsx b/src/components/parts/FeaturedArticlesCategories.tsx similarity index 100% rename from src/components/parts/FeaturedArticles.tsx rename to src/components/parts/FeaturedArticlesCategories.tsx diff --git a/src/components/parts/Footer.tsx b/src/components/parts/Footer.tsx index dcc3331..9697984 100644 --- a/src/components/parts/Footer.tsx +++ b/src/components/parts/Footer.tsx @@ -12,16 +12,26 @@ import Link from "components/typography/Link"; /* -------------------------------------------------------------------------- */ const mainLinks = [ - { label: "account settings", url: "/account/settings", enabled: true }, - { label: "about freeland", url: "/about", enabled: true }, - { label: "help", url: "/help", enabled: true }, - { label: "contact us", url: "/contact-us", enabled: true }, + { label: "account settings", url: "/account/settings", disabled: false }, + { label: "about freeland", url: "/about", disabled: false }, + { label: "help", url: "/help", disabled: false }, + { label: "contact us", url: "/contact-us", disabled: false }, ]; const secondaryLinks = [ - { index: 1, label: "Terms of Use", url: "/terms-of-use", enabled: true }, - { index: 2, label: "Privacy Policy", url: "/privacy-policy", enabled: true }, - { index: 3, label: "Cookies Policy", url: "/cookies-policy", enabled: true }, + { index: 1, label: "Terms of Use", url: "/terms-of-use", disabled: false }, + { + index: 2, + label: "Privacy Policy", + url: "/privacy-policy", + disabled: false, + }, + { + index: 3, + label: "Cookies Policy", + url: "/cookies-policy", + disabled: false, + }, ]; /* -------------------------------------------------------------------------- */ @@ -42,16 +52,16 @@ export function Footer() { const mainLinksPart = useMemo( () => mainLinks.map((link) => ( - <RouterLink + <Link key={link.url} className="py-1 md:py-2 text-gray-900 px-4" - enabled={link.enabled} + disabled={link.disabled} to={link.url} > <Typography className="" fontWeightVariant="semibold" htmlTag="p"> {link.label.toUpperCase()} </Typography> - </RouterLink> + </Link> )), mainLinks ); @@ -61,9 +71,9 @@ export function Footer() { secondaryLinks.map((link) => ( <div className="flex flex-row items-center"> {link.index != 1 && circleDivider} - <RouterLink key={link.url} enabled={link.enabled} to={link.url}> + <Link key={link.url} disabled={link.disabled} to={link.url}> {link.label} - </RouterLink> + </Link> </div> )), secondaryLinks @@ -76,20 +86,20 @@ export function Footer() { <div className="lg:px-12 px-2 sm:px-8 md:px-4 pb-2 md:pt-4 pt-2 lg:pt-5 bg-gray-200"> <section className="w-full grid grid-cols-2 md:grid-rows-2 sm:grid-flow-row-dense sm:grid-rows-2 justify-items-between md:justify-between mb-2 md: items-center md:flex-row md:flex"> <div className="sm:col-span-1"> - <RouterLink to="/"> + <Link to="*"> <Typography className="text-2xl" fontWeightVariant="semibold"> Freeland </Typography> - </RouterLink> + </Link> </div> <div className="order-last md:order-none justify-center justify-items-center items-center flex flex-col col-span-4 sm:flex sm:flex-row text-sm"> {mainLinksPart} </div> <div className="flex flex-row sm:col-span-1 justify-end"> - <Link href="https://www.facebook.com"> + <Link to="https://www.facebook.com"> <SVGFacebook className="w-5 h-5 fill-gray-900 stroke-gray-900 mr-2" /> </Link> - <Link href="https://www.instagram/com"> + <Link to="https://www.instagram/com"> {" "} <SVGInstagram className="w-5 h-5 fill-gray-900 stroke-gray-900 ml-2 " /> </Link> diff --git a/src/components/typography/RouterLink.tsx b/src/components/typography/RouterLink.tsx index 4b32e77..016e2f8 100644 --- a/src/components/typography/RouterLink.tsx +++ b/src/components/typography/RouterLink.tsx @@ -1,5 +1,5 @@ import classNames from "classnames"; -import { NavLink, NavLinkProps, To } from "react-router-dom"; +import { NavLink, NavLinkProps } from "react-router-dom"; type Props = { enabled?: boolean;