Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/assets/lang/es/relational-links.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@
"link": "/pricing"
},
{
"cta": "Almacenamiento privado en la nube",
"cta": "Almacenamiento privado\n en la nube",
"link": "/private-cloud-storage-solutions"
},
{
"cta": "Nube de almacenamiento de código abierto",
"cta": "Nube de almacenamiento\n de código abierto",
"link": "/open-source"
},
{
Expand Down
2 changes: 1 addition & 1 deletion src/components/comparison/HeroSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const HeroSection = ({ textContent, percentage, competitor }: HeroSection
<div className="absolute left-8 right-8 top-0 h-[1px] bg-neutral-35 lg:left-32 lg:right-32"></div>
<div className="hidden h-auto w-full justify-between lg:flex lg:h-min">
<div className="flex h-full flex-col items-start justify-center gap-5 text-start lg:h-min lg:w-1/2 lg:text-start">
<h1 className="whitespace-pre-line text-30 font-semibold text-gray-95 lg:text-5xl">
<h1 className="flex 2xl:whitespace-pre-line text-30 font-semibold text-gray-95 lg:text-5xl">
<HighlightText text={parseText(textContent.title)} />
</h1>

Expand Down
6 changes: 3 additions & 3 deletions src/components/drive/components/LinkTo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ interface LinkTo {

export const LinkTo = ({ text, linkToRedirect }: LinkTo) => {
return (
<Link href={linkToRedirect} className="flex flex-row items-center space-x-1 text-primary">
<p className="text-base font-medium">{text}</p>
<ArrowUpRight size={20} weight="bold" />
<Link href={linkToRedirect} className="flex flex-row items-start justify-start gap-2 text-primary">
<p className="text-base font-medium w-max">{text}</p>
<ArrowUpRight size={20} weight="bold" className="flex flex-nowrap pt-1" />
</Link>
);
};
146 changes: 130 additions & 16 deletions src/components/shared/sections/RelationalLinks.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import React, { useEffect, useState } from 'react';
import React, { useEffect, useState, useRef } from 'react';
import { useRouter } from 'next/router';
import { LinkTo } from '../../drive/components/LinkTo';
import { CaretLeft, CaretRight } from '@phosphor-icons/react';

interface Card {
cta: string;
Expand All @@ -24,30 +26,142 @@

const RelationalLinks = ({ textContent }: RelationalLinksProps) => {
const [cards, setCards] = useState<Card[]>([]);
const router = useRouter();

const scrollContainerRef = useRef<HTMLDivElement>(null);
const [scrollState, setScrollState] = useState({
canGoLeft: false,
canGoRight: true,
});
const [isMobile, setIsMobile] = useState(false);

useEffect(() => {
const checkIsMobile = () => {
setIsMobile(window.innerWidth < 1024);
};
checkIsMobile();
window.addEventListener('resize', checkIsMobile);
return () => window.removeEventListener('resize', checkIsMobile);
}, []);

useEffect(() => {
if (textContent?.links) {
const shuffledLinks = shuffleData(textContent.links);
setCards(shuffledLinks.slice(0, 3));
const filteredLinks = textContent.links.filter((link) => link.link !== router.asPath);
const shuffledLinks = shuffleData(filteredLinks);
setCards(shuffledLinks.slice(0, 9));
}
}, [textContent]);
}, [textContent, router.asPath]);

const updateScrollButtons = () => {
if (scrollContainerRef.current === null) return;
const { scrollLeft, scrollWidth, clientWidth } = scrollContainerRef.current;

const maxScrollLeft = scrollWidth - clientWidth;

setScrollState({
canGoLeft: scrollLeft > 2,
canGoRight: scrollLeft < maxScrollLeft - 2,
});
};

const getScrollAmount = () => {
const cardWidth = isMobile ? 300 : 350;
const gap = 24; // gap-6 refers to 1.5rem which is 24px
return cardWidth + gap;
};

const scrollLeft = () => {
if (scrollContainerRef.current === null) return;
scrollContainerRef.current.scrollBy({
left: -getScrollAmount(),
behavior: 'smooth',
});
};

const scrollRight = () => {
if (scrollContainerRef.current === null) return;
scrollContainerRef.current.scrollBy({
left: getScrollAmount(),
behavior: 'smooth',
});
};

useEffect(() => {
const scrollContainer = scrollContainerRef.current;
if (scrollContainer === null) return;

updateScrollButtons();
scrollContainer.addEventListener('scroll', updateScrollButtons);

const resizeObserver = new ResizeObserver(updateScrollButtons);
resizeObserver.observe(scrollContainer);

return () => {
scrollContainer.removeEventListener('scroll', updateScrollButtons);
resizeObserver.disconnect();
};
}, [isMobile, cards]);

if (cards.length === 0) return null;

return (
<section className="mx-auto flex max-w-7xl flex-col items-center justify-center px-6 py-20 lg:px-0">
<h2 className="mb-14 text-center text-4xl font-semibold text-gray-100 lg:text-5xl">
{textContent.title}
</h2>
<div className="grid grid-cols-1 items-stretch gap-6 md:grid-cols-2 lg:grid-cols-3">
{cards.map((card) => (
<div
key={card.link}
className="flex w-full max-w-[350px] flex-col justify-between whitespace-pre-wrap rounded-2xl bg-gray-1 p-10"
>
<LinkTo linkToRedirect={card.link} text={card.cta} />
<section className="flex w-full flex-col items-center justify-center overflow-hidden py-20">
<div className="mx-auto w-full max-w-7xl px-6 lg:px-0">
<p className="mb-8 text-center text-4xl font-semibold text-gray-100 lg:mb-14 lg:text-5xl">
{textContent.title}
</p>
</div>

<div className="flex w-full flex-col items-center gap-6 lg:gap-8">
<div
ref={scrollContainerRef}
className="scrollbar-hide flex w-full flex-row gap-6 overflow-x-auto scroll-smooth"
style={{
scrollbarWidth: 'none',
msOverflowStyle: 'none',
paddingLeft: isMobile ? '24px' : 'max(24px, calc((100vw - 1280px) / 2))',
paddingRight: isMobile ? '24px' : 'max(24px, calc((100vw - 1280px) / 2))',
}}
>
{cards.map((card) => (
<div
key={card.link}
className="flex-shrink-0"
style={{
width: isMobile ? '300px' : '350px',
}}
>
<div className="flex h-full w-full flex-col justify-between whitespace-pre-wrap rounded-2xl bg-gray-1 p-10 transition-colors hover:bg-neutral-20">
<LinkTo linkToRedirect={card.link} text={card.cta} />
</div>
</div>
))}
</div>

<div className="mx-auto flex w-full max-w-7xl justify-end px-6 lg:px-0">
<div className="flex w-[120px] justify-between">
<button
onClick={scrollLeft}
disabled={!scrollState.canGoLeft}
className={`flex h-[48px] w-[48px] items-center justify-center rounded-full border border-primary bg-transparent transition-all hover:bg-primary/10 ${
!scrollState.canGoLeft ? 'cursor-not-allowed opacity-30' : 'cursor-pointer'

Check warning on line 147 in src/components/shared/sections/RelationalLinks.tsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unexpected negated condition.

See more on https://sonarcloud.io/project/issues?id=internxt_website&issues=AZzctPP50di0VR8G9IfF&open=AZzctPP50di0VR8G9IfF&pullRequest=1835
}`}
aria-label="Anterior"
>
<CaretLeft className="text-primary" size={24} />
</button>
<button
onClick={scrollRight}
disabled={!scrollState.canGoRight}
className={`flex h-[48px] w-[48px] items-center justify-center rounded-full border border-primary bg-transparent transition-all hover:bg-primary/10 ${
!scrollState.canGoRight ? 'cursor-not-allowed opacity-30' : 'cursor-pointer'

Check warning on line 157 in src/components/shared/sections/RelationalLinks.tsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unexpected negated condition.

See more on https://sonarcloud.io/project/issues?id=internxt_website&issues=AZzctPP50di0VR8G9IfG&open=AZzctPP50di0VR8G9IfG&pullRequest=1835
}`}
aria-label="Siguiente"
>
<CaretRight className="text-primary" size={24} />
</button>
</div>
))}
</div>
</div>
</section>
);
Expand Down
Loading