Skip to content

Commit

Permalink
feat(nx-dev): Enhance customer testimonial carousel and icon grid layout
Browse files Browse the repository at this point in the history
  • Loading branch information
ndcunningham committed Jan 7, 2025
1 parent 7c313b3 commit c069087
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 38 deletions.
2 changes: 1 addition & 1 deletion nx-dev/ui-customers/src/lib/customer-icon-grid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ function getBorderClass(index: number, totalIcons: number, columns = 4) {

const CustomerIconGrid: FC<CustomerIconGridProps> = ({ icons }) => {
return (
<div className="grid grid-cols-2 justify-between px-4 md:grid-cols-4">
<div className="grid grid-cols-2 justify-between md:grid-cols-4">
{icons.map((customerIcon, index) => {
const borderClass = getBorderClass(index, icons.length);

Expand Down
57 changes: 47 additions & 10 deletions nx-dev/ui-customers/src/lib/customer-testimonial-carousel.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
'use client';
import { Fragment, useState, useEffect } from 'react';
import { Dialog, Transition } from '@headlessui/react';
import { PlayIcon } from '@heroicons/react/24/outline';
import {
ChevronLeftIcon,
ChevronRightIcon,
PlayIcon,
} from '@heroicons/react/24/outline';
import Image from 'next/image';
import {
CasewareIcon,
Expand Down Expand Up @@ -56,12 +60,21 @@ const testimonials: Testimonial[] = [
{
title: 'Customer story',
subtitle:
'Scaling 700+ projects: How Nx Enterprise became a no-brainer for Caseware',
'Scaling 700+ projects: How Nx Enterprise became a no-brainer for Caseware.',
metrics: [
{ value: '700+', label: 'Monorepo projects scaled effortlessly' },
{
value: 'Efficiency',
label: 'Unified workflows: frontend to backend',
value: 'Massive scale',
label:
'600–700 projects, unifying frontends and backends company wide.',
},
{
value: 'Instant impact',
label: 'Trialing Nx Enterprise cut build times immediately.',
},
{
value: 'Actionable insights',
label:
'Nx Cloud’s metrics uncovered inefficiencies across 10+ year old codebase.',
},
],
company: 'Caseware',
Expand Down Expand Up @@ -167,7 +180,6 @@ export function CustomerTestimonialCarousel(): JSX.Element {
useEffect(() => {
let timer: NodeJS.Timeout;

// Clear the current timer and start a new one
if (!isOpen) {
timer = setInterval(() => {
setCurrentIndex((prevIndex) => {
Expand All @@ -177,7 +189,6 @@ export function CustomerTestimonialCarousel(): JSX.Element {
}, slideLogoTimeOut);
}

// Cleanup on unmount or when dependencies change
return () => {
clearInterval(timer);
};
Expand Down Expand Up @@ -230,7 +241,7 @@ export function CustomerTestimonialCarousel(): JSX.Element {
<div className="flex h-full flex-col justify-center space-y-8">
{currentTestimonial.metrics?.map((metric, index) => (
<div key={index} className="space-y-2">
<div className="text-4xl font-bold text-blue-500 lg:text-5xl">
<div className="text-xl font-bold text-sky-600 lg:text-2xl">
{metric.value}
</div>
<div className="text-base text-slate-500 lg:text-lg dark:text-slate-400">
Expand All @@ -245,6 +256,19 @@ export function CustomerTestimonialCarousel(): JSX.Element {
{/* Right side - Video Card */}
<div className="col-span-2 md:col-span-3">
<div className="flex items-center gap-4">
{/* Prev Button Mobile only */}
<button
disabled={currentIndex === 0}
title={`See ${testimonials[currentIndex - 1]?.company} again!`}
className="flex h-12 w-12 items-center justify-center rounded-full p-2 transition hover:text-slate-950 disabled:pointer-events-none disabled:opacity-0 md:hidden dark:hover:text-white"
onClick={() => {
setCurrentIndex(
(currentIndex - 1 + testimonials.length) % testimonials.length
);
}}
>
<ChevronLeftIcon className="h-8 w-8" />
</button>
<div
className="group relative h-[450px] w-full cursor-pointer self-stretch overflow-hidden rounded-lg xl:shadow-2xl"
onClick={() => setIsOpen(true)}
Expand Down Expand Up @@ -272,6 +296,19 @@ export function CustomerTestimonialCarousel(): JSX.Element {
</button>
</div>
</div>
{/* Next Button - Mobile only */}
<button
className="flex h-12 w-12 items-center justify-center rounded-full p-2 transition hover:text-slate-950 disabled:pointer-events-none disabled:opacity-0 md:hidden dark:hover:text-white"
disabled={currentIndex === testimonials.length - 1}
title={`Next ${testimonials[currentIndex + 1]?.company}!`}
onClick={() => {
setCurrentIndex(
(currentIndex + 1 + testimonials.length) % testimonials.length
);
}}
>
<ChevronRightIcon className="h-8 w-8" />
</button>
</div>

{/* Mobile Navigation display dots */}
Expand All @@ -290,7 +327,7 @@ export function CustomerTestimonialCarousel(): JSX.Element {
</div>
</div>

{/* Carosel Navigation */}
{/* Carosel Navigation - Larger screens */}
<div className="relative mx-auto hidden max-w-7xl grid-cols-6 items-center justify-center px-4 pt-16 md:grid">
{testimonials.map(({ company, logo }, i) => (
<button
Expand All @@ -308,7 +345,7 @@ export function CustomerTestimonialCarousel(): JSX.Element {
className={`${logo.height} ${logo.width} transition-transform duration-300`}
/>

{/* Progress Bar at the Top */}
{/* Progress Bar */}
{i === currentIndex && !isOpen && (
<div className="absolute left-0 top-0 h-[2px] w-full overflow-hidden bg-gray-300/80 transition-all">
<div
Expand Down
2 changes: 1 addition & 1 deletion nx-dev/ui-customers/src/lib/enterprise-customers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ export function EnterpriseCustomers(): JSX.Element {
<div className="mx-auto max-w-7xl">
<CustomerIconGrid icons={secondCustomerIcons} />

<div className="grid-cols grid justify-center gap-4 px-4 py-6 md:grid-cols-3">
<div className="grid-cols grid justify-center gap-4 px-2 py-6 md:grid-cols-3">
<DownloadCaseStudy
title="Financial Institution Case Study"
description="$28B Fortune 500 financial institution reduces CI times by 79% with Nx Cloud."
Expand Down
41 changes: 15 additions & 26 deletions nx-dev/ui-enterprise/src/lib/download-case-study.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import { ButtonLink } from '@nx/nx-dev/ui-common';
import { ReactElement } from 'react';
import {
ArrowDownTrayIcon,
ChevronRightIcon,
} from '@heroicons/react/24/outline';

export interface DownloadCaseStudyProps {
title: string;
Expand All @@ -23,31 +19,24 @@ export function DownloadCaseStudy({
variant = 'primary',
}: DownloadCaseStudyProps): ReactElement {
return (
<div className="border border-slate-100 bg-white shadow-lg sm:rounded-lg dark:border-slate-800/60 dark:bg-slate-950">
<div className="px-4 py-5 sm:p-6">
<div className="flex h-full flex-col border border-slate-100 bg-white shadow-lg sm:rounded-lg dark:border-slate-800/60 dark:bg-slate-950">
<div className="flex flex-1 flex-col px-4 py-5 sm:p-6">
<h3 className="text-base font-semibold leading-6 text-slate-900 dark:text-slate-100">
{title}
</h3>
<div className="mt-2 sm:flex sm:items-start sm:justify-between">
<div className="max-w-xl text-sm">
<p>{description}</p>
</div>
<div className="mt-5 sm:ml-6 sm:mt-0 sm:flex sm:flex-shrink-0 sm:items-center">
<ButtonLink
href={buttonHref}
title={`${buttonCTA} ${title}`}
variant={variant}
target="_blank"
size="small"
>
{buttonText}{' '}
{buttonCTA === 'Read more' ? (
<ChevronRightIcon className="h-4 w-4" />
) : (
<ArrowDownTrayIcon className="h-4 w-4 translate-x-1" />
)}
</ButtonLink>
</div>
<div className="mt-2 max-w-xl flex-1 text-sm">
<p>{description}</p>
</div>
<div className="mt-auto pt-5">
<ButtonLink
href={buttonHref}
title={`${buttonCTA} ${title}`}
variant={variant}
target={buttonCTA === 'Download' ? '_blank' : undefined}
size="small"
>
{buttonText}
</ButtonLink>
</div>
</div>
</div>
Expand Down

0 comments on commit c069087

Please sign in to comment.