| { | { | ||||
| "name": "frontend", | "name": "frontend", | ||||
| "version": "1.3.4", | |||||
| "version": "1.3.5", | |||||
| "private": true, | "private": true, | ||||
| "dependencies": { | "dependencies": { | ||||
| "@faceless-ui/slider": "^1.1.14", | "@faceless-ui/slider": "^1.1.14", |
| import React from 'react' | |||||
| import React from 'react'; | |||||
| import { strapiApiBuilder } from './../utils/strapiApiBuilder'; | import { strapiApiBuilder } from './../utils/strapiApiBuilder'; | ||||
| import useFetchCollections from './../hooks/useFetchCollections'; | import useFetchCollections from './../hooks/useFetchCollections'; | ||||
| import { formatDate } from './../utils/formatDate'; | import { formatDate } from './../utils/formatDate'; | ||||
| const api_url = process.env.REACT_APP_API_URL; | const api_url = process.env.REACT_APP_API_URL; | ||||
| const strapiPopulate = [ | |||||
| 'AuthorImage', | |||||
| 'ArticleImage', | |||||
| 'article_category', | |||||
| ]; | |||||
| const strapiPopulate = ['AuthorImage', 'ArticleImage', 'article_category']; | |||||
| const LatestArticles = () => { | const LatestArticles = () => { | ||||
| const strapi = strapiApiBuilder('articles', strapiPopulate, '?sort[0]=date&pagination[pageSize]=3'); | |||||
| const strapi = strapiApiBuilder( | |||||
| 'articles', | |||||
| strapiPopulate, | |||||
| '&sort[0]=Date:DESC&pagination[pageSize]=3', | |||||
| ); | |||||
| const [{ data, isLoading, isError }, doFetch] = useFetchCollections(strapi); | |||||
| const [{ data, isLoading, isError }, doFetch] = useFetchCollections(strapi); | |||||
| return ( | return ( | ||||
| <div className='col-span-1 md:col-span-2 flex flex-col gap-4'> | |||||
| <h4 className='text-n-subhead font-semibold text-dark-gray mb-8'>Latest Blog Posts</h4> | |||||
| {data && data.length > 0 && data.map((element,index) => ( | |||||
| <div className="col-span-1 md:col-span-2 flex flex-col gap-4"> | |||||
| <h4 className="text-n-subhead font-semibold text-dark-gray mb-8"> | |||||
| Latest Blog Posts | |||||
| </h4> | |||||
| {data && | |||||
| data.length > 0 && | |||||
| data.map((element, index) => ( | |||||
| <a | <a | ||||
| key={index} | |||||
| className={'card box flex flex-col items-center justify-between gap-[24px]'} | |||||
| href={`/articles/${element.attributes.Slug}`} | |||||
| > | |||||
| <div className="flex flex-col gap-[4px]"> | |||||
| {element.attributes.AuthorTitle && | |||||
| <div className="flex gap-2"> | |||||
| key={index} | |||||
| className={'card box flex flex-col items-center justify-between gap-[24px]'} | |||||
| href={`/articles/${element.attributes.Slug}`} | |||||
| > | |||||
| <div className="flex flex-col gap-[4px]"> | |||||
| {element.attributes.AuthorTitle && ( | |||||
| <div className="flex gap-2"> | |||||
| <img | |||||
| className="max-h-[36px] object-fit rounded-full" | |||||
| src={api_url + element.attributes.AuthorImage.data.attributes.url} | |||||
| alt={ | |||||
| api_url + | |||||
| element.attributes.AuthorImage.data.attributes.alternativeText | |||||
| } | |||||
| /> | |||||
| <div className="flex flex-col items-start"> | |||||
| <p className="paragraph">{element.attributes.Author}</p> | |||||
| <p className="text-small-subhead text-gray-400 leading-normal"> | |||||
| {element.attributes.AuthorTitle} | |||||
| </p> | |||||
| </div> | |||||
| </div> | |||||
| )} | |||||
| <div className="text-left flex flex-col gap-[8px]"> | |||||
| <h2 className="n-paragraph-title text-dark-gray leading-normal"> | |||||
| {element.attributes.ArticleTitle} | |||||
| </h2> | |||||
| </div> | |||||
| </div> | |||||
| <img | <img | ||||
| className="max-h-[36px] object-fit rounded-full" | |||||
| src={api_url + element.attributes.AuthorImage.data.attributes.url} | |||||
| alt={api_url + element.attributes.AuthorImage.data.attributes.alternativeText} | |||||
| src={api_url + element.attributes.ArticleImage.data.attributes.url} | |||||
| alt={ | |||||
| api_url + element.attributes.ArticleImage.data.attributes.alternativeText | |||||
| } | |||||
| /> | /> | ||||
| <div className="flex flex-col items-start"> | |||||
| <p className="paragraph">{element.attributes.Author}</p> | |||||
| <p className="text-small-subhead text-gray-400 leading-normal"> | |||||
| {element.attributes.AuthorTitle} | |||||
| </p> | |||||
| </div> | |||||
| </div> | |||||
| } | |||||
| <div className='text-left flex flex-col gap-[8px]'> | |||||
| <h2 className="n-paragraph-title text-dark-gray leading-normal">{element.attributes.ArticleTitle}</h2> | |||||
| </div> | |||||
| </div> | |||||
| <img | |||||
| src={api_url + element.attributes.ArticleImage.data.attributes.url} | |||||
| alt={api_url + element.attributes.ArticleImage.data.attributes.alternativeText} | |||||
| /> | |||||
| </a> | |||||
| ))} | |||||
| </a> | |||||
| ))} | |||||
| </div> | </div> | ||||
| ) | |||||
| } | |||||
| ); | |||||
| }; | |||||
| export default LatestArticles; | |||||
| export default LatestArticles; |
| const Image = ({data}) => { | const Image = ({data}) => { | ||||
| return ( | return ( | ||||
| <img src={api_url + data.data.attributes.url} alt={data.data.attributes.alternativeText} className='rounded-md w-full pb-4' /> | |||||
| <img src={api_url + data.data.attributes.url} alt={data.data.attributes.alternativeText} className='rounded-md w-full' /> | |||||
| ) | ) | ||||
| } | } | ||||
| import React, { useEffect, useState } from 'react'; | |||||
| import React, { Fragment, useEffect, useState } from 'react'; | |||||
| import { useNavigate } from 'react-router-dom'; | import { useNavigate } from 'react-router-dom'; | ||||
| import { formatDate } from './../../utils/formatDate'; | import { formatDate } from './../../utils/formatDate'; | ||||
| import CategoryNugget from './CategoryNugget'; | import CategoryNugget from './CategoryNugget'; | ||||
| const ArticleCard = ({ data }) => { | const ArticleCard = ({ data }) => { | ||||
| return ( | return ( | ||||
| <a | |||||
| className={ | |||||
| 'card box my-2 flex flex-col md:flex-row items-center justify-between gap-[72px]' | |||||
| } | |||||
| href={`/articles/${data.Slug}`} | |||||
| > | |||||
| <div className="flex flex-col gap-[18px]"> | |||||
| {data.Author && ( | |||||
| <div className="flex gap-4"> | |||||
| <img | |||||
| className="max-h-[45px] object-fit rounded-full" | |||||
| src={api_url + data.AuthorImage.data.attributes.url} | |||||
| alt={data.AuthorImage.data.attributes.alternativeText} | |||||
| /> | |||||
| <div className="flex flex-col items-start"> | |||||
| <p className="paragraph">{data.Author}</p> | |||||
| <p className="text-small-subhead text-gray-400 leading-normal text-left"> | |||||
| {data.AuthorTitle} | |||||
| </p> | |||||
| </div> | |||||
| </div> | |||||
| )} | |||||
| <Fragment> | |||||
| {data && ( | |||||
| <a | |||||
| className={ | |||||
| 'card box my-2 flex flex-col md:flex-row items-center justify-between gap-[72px]' | |||||
| } | |||||
| href={`/articles/${data.Slug}`} | |||||
| > | |||||
| <div className="flex flex-col gap-[18px]"> | |||||
| {data.Author && ( | |||||
| <div className="flex gap-4"> | |||||
| <img | |||||
| className="max-h-[45px] object-fit rounded-full" | |||||
| src={api_url + data.AuthorImage.data.attributes.url} | |||||
| alt={data.AuthorImage.data.attributes.alternativeText} | |||||
| /> | |||||
| <div className="flex flex-col items-start"> | |||||
| <p className="paragraph">{data.Author}</p> | |||||
| <p className="text-small-subhead text-gray-400 leading-normal text-left"> | |||||
| {data.AuthorTitle} | |||||
| </p> | |||||
| </div> | |||||
| </div> | |||||
| )} | |||||
| <div className="text-left flex flex-col gap-[8px]"> | |||||
| <h2 className="n-h3-heading text-dark-gray">{data.ArticleTitle}</h2> | |||||
| <p className="n-paragraph w-full md:w-[450px]">{data.ArticleDescription}</p> | |||||
| </div> | |||||
| <div className="text-left flex flex-col gap-[8px]"> | |||||
| <h2 className="n-h3-heading text-dark-gray">{data.ArticleTitle}</h2> | |||||
| <p className="n-paragraph w-full md:w-[450px]">{data.ArticleDescription}</p> | |||||
| </div> | |||||
| <div className="flex gap-4 items-center"> | |||||
| <p className="text-small-subhead text-gray-400 leading-normal"> | |||||
| {formatDate(data.Date)} | |||||
| </p> | |||||
| {data.article_category.data && ( | |||||
| <CategoryNugget data={data.article_category.data.attributes.Name} /> | |||||
| )} | |||||
| </div> | |||||
| </div> | |||||
| <div className="w-full md:w-[450px] rounded-8 overflow-hidden"> | |||||
| <img | |||||
| src={api_url + data.ArticleImage.data.attributes.url} | |||||
| alt={data.ArticleImage.data.attributes.alternativeText} | |||||
| /> | |||||
| </div> | |||||
| <div className="flex gap-4 items-center"> | |||||
| {data.Date && ( | |||||
| <p className="text-small-subhead text-gray-400 leading-normal"> | |||||
| {formatDate(data.Date)} | |||||
| </p> | |||||
| )} | |||||
| {/* <img src={api_url + data.img} alt={api_url + data.alt} className={'mb-12 mx-auto self-center'}></img> */} | |||||
| </a> | |||||
| {data.article_category.data && ( | |||||
| <CategoryNugget data={data.article_category.data.attributes.Name} /> | |||||
| )} | |||||
| </div> | |||||
| </div> | |||||
| <div className="w-full md:w-[450px] rounded-8 overflow-hidden"> | |||||
| <img | |||||
| src={api_url + data.ArticleImage.data.attributes.url} | |||||
| alt={data.ArticleImage.data.attributes.alternativeText} | |||||
| /> | |||||
| </div> | |||||
| </a> | |||||
| )} | |||||
| </Fragment> | |||||
| ); | ); | ||||
| }; | }; | ||||
| const api_url = process.env.REACT_APP_API_URL; | const api_url = process.env.REACT_APP_API_URL; | ||||
| const strapiPopulate = [ | |||||
| 'AuthorImage', | |||||
| 'ArticleImage', | |||||
| 'article_category', | |||||
| ]; | |||||
| const strapiPopulate = ['AuthorImage', 'ArticleImage', 'article_category']; | |||||
| const BlogArticlesDataWrapper = () => { | const BlogArticlesDataWrapper = () => { | ||||
| const strapi = strapiApiBuilder('articles', strapiPopulate, ''); | |||||
| const strapi = strapiApiBuilder('articles', strapiPopulate, '&sort=Date:desc'); | |||||
| const [{ data, isLoading, isError }, doFetch] = useFetchCollections(strapi); | const [{ data, isLoading, isError }, doFetch] = useFetchCollections(strapi); | ||||
| console.log(data); | |||||
| if (isLoading) { | if (isLoading) { | ||||
| return ( | return ( | ||||
| </div> | </div> | ||||
| ); | ); | ||||
| } else { | } else { | ||||
| return <>{data && <Wrapper> | |||||
| <ArticlesGrid> | |||||
| {data.map((element,index) => ( | |||||
| <div key={index}> | |||||
| <ArticleCard data={element.attributes} /> | |||||
| </div> | |||||
| ) | |||||
| )} | |||||
| </ArticlesGrid> | |||||
| </Wrapper>}</>; | |||||
| return ( | |||||
| <> | |||||
| {data && ( | |||||
| <Wrapper> | |||||
| <ArticlesGrid> | |||||
| {data.map((element, index) => ( | |||||
| <div key={index}> | |||||
| <ArticleCard data={element.attributes} /> | |||||
| </div> | |||||
| ))} | |||||
| </ArticlesGrid> | |||||
| </Wrapper> | |||||
| )} | |||||
| </> | |||||
| ); | |||||
| } | } | ||||
| }; | }; | ||||
| export default BlogArticlesDataWrapper; | export default BlogArticlesDataWrapper; |
| const [{ data, isLoading, isError }, doFetch] = useDataApi(strapi); | const [{ data, isLoading, isError }, doFetch] = useDataApi(strapi); | ||||
| useAnalytics('Blog'); | useAnalytics('Blog'); | ||||
| useEffect(() => { | useEffect(() => { |
| alt={ | alt={ | ||||
| data[0].attributes.BackgroundImage.data?.attributes.alternativeText | data[0].attributes.BackgroundImage.data?.attributes.alternativeText | ||||
| } | } | ||||
| className="text-center z-0 m-auto object-cover h-full lg:w-full" | |||||
| className="text-center z-0 m-auto object-cover h-full lg:w-full opacity-20" | |||||
| /> | /> | ||||
| </div> | </div> | ||||
| <div className="my-8 flex flex-col md:flex-row justify-start items-center w-full max-w-custom px-8 xl:px-0 z-10"> | <div className="my-8 flex flex-col md:flex-row justify-start items-center w-full max-w-custom px-8 xl:px-0 z-10"> |