import React, { useState, useEffect } from 'react'; import styled from 'styled-components'; // components import { Stack, Button, Text } from '@kiwicom/orbit-components/lib'; import BlackText from '@components/text/BlackText'; import GreySubtleButton from '@components/buttons/GreySubtleButton'; import DonationCard from '@components/card/DonationCard'; import CarouselScrollButton from '@components/buttons/CarouselScrollButton'; import Desktop from '@kiwicom/orbit-components/lib/Desktop'; import { InstantSearch, connectHits, Configure } from 'react-instantsearch-dom'; // constants and utils import { getFormattedDate } from '@api/time'; import { getByCategoryIdAndStatus } from '@utils/algolia/filteringRules'; import { getTopNCategoriesFromAlgolia, sortObjectEntries } from '../../../utils/algoliaHelpers'; import { searchClient } from '@utils/algolia'; import api from '@api'; // hooks import { useRouter } from 'next/router'; const CategoryHeader = styled.div` align-items: center; display: flex; `; const LeftAnchor = styled.div` float: left; margin: 0px auto 0px 0px; `; const RightAnchor = styled.div` float: right; `; const DonationsRow = styled.div` max-width: 1280px; overflow-x: scroll; scroll-behavior: smooth; position: relative; padding: 10px 3px 10px 3px; `; const CarouselContainer = styled.div` position: relative; display: flex; `; const TopDonationCardsContainer = styled.div` width: 100%; `; const TopDonations = ({ numberOfPosts, numberOfCategories }) => { const router = useRouter(); const [topCategories, setTopCategories] = useState([]); useEffect(() => { getTopNCategories().then((categories) => { getTopNCategoriesFromAlgolia('donations').then(({ hits, facets }) => { if (facets['categories.id'] === undefined || Object.keys(facets['categories.id']).length === 0) { return; } const sorted = sortObjectEntries(facets['categories.id']); if (sorted.length >= numberOfCategories) { const topNCategoriesIds = sorted.slice(0, numberOfCategories); const topNCategories = categories.filter((category) => { if (topNCategoriesIds.includes(category.id)) { return true; } return false; }); setTopCategories(topNCategories); } else if (sorted.length > 0 && sorted.length < numberOfCategories) { const topCategories = categories.filter((category) => { if (sorted.includes(category.id)) { return true; } return false; }); setTopCategories(topCategories); } }); }); }, []); const getTopNCategories = async () => { const rawCategories = await api.categories.getAll().catch((err) => console.error(err)); return rawCategories.docs.map((doc) => doc.data()); }; const TopDonationsRow = ({ hits, category }) => { const categoryHref = `/donations/category/${category.id}`; const handleViewAllButton = (event) => { event.preventDefault(); router.push(categoryHref); }; const getScrollableWidth = () => document.getElementById(category.id).clientWidth; const handleScrollLeft = () => (document.getElementById(category.id).scrollLeft -= getScrollableWidth()); const handleScrollRight = () => (document.getElementById(category.id).scrollLeft += getScrollableWidth()); return ( <TopDonationCardsContainer key={category.id}> <CategoryHeader> <LeftAnchor> <Text size="normal" weight="bold"> {category.name} </Text> </LeftAnchor> <RightAnchor> <Button size="small" asComponent={GreySubtleButton} onClick={handleViewAllButton}> <BlackText size="small">View all</BlackText> </Button> </RightAnchor> </CategoryHeader> <CarouselContainer> <Desktop> <CarouselScrollButton direction="left" size="normal" onClickHandler={handleScrollLeft} /> </Desktop> <DonationsRow id={category.id} className="scrollableDonation"> <Stack direction="row" align="start" spacing="extraLoose"> {hits.map((donation) => { const donationPostHref = `/donations/${donation.objectID}`; const profileHref = `/profile/${donation.user.userId}`; const validPeriod = `${getFormattedDate(donation.validPeriodFrom)} - ${getFormattedDate( donation.validPeriodTo )}`; return ( <DonationCard key={`${category.id}-${donation.objectID}`} name={donation.user.userName} title={donation.title} description={donation.description} profileImageUrl={donation.user.profileImageUrl} postedDateTime={donation.postedDateTime} coverImageUrl={donation.coverImageUrl} postHref={donationPostHref} profileHref={profileHref} validPeriod={validPeriod} itemCondition={donation.itemCondition} categoryId={category.id} categoryName={category.name} ></DonationCard> ); })} </Stack> </DonationsRow> <Desktop> <CarouselScrollButton direction="right" size="normal" onClickHandler={handleScrollRight} /> </Desktop> </CarouselContainer> </TopDonationCardsContainer> ); }; const TopCategories = connectHits(TopDonationsRow); return ( <Stack direction="column" align="start" spacing="natural"> {topCategories.map((category) => ( <InstantSearch key={category.id} searchClient={searchClient} indexName="donations"> <TopCategories category={category} /> <Configure filters={getByCategoryIdAndStatus(category.id, 'pending')} hitsPerPage={numberOfPosts} /> </InstantSearch> ))} </Stack> ); }; export default TopDonations;