Files
reui-blocks/blocks/feature249.tsx
T

151 lines
4.5 KiB
TypeScript

"use client";
import type { MotionValue } from "motion/react";
import { motion, useScroll, useTransform } from "motion/react";
import React, { useRef } from "react";
import { AuroraText } from "@/components/magicui/aurora-text";
import { cn } from "@/lib/utils";
interface Feature249Props {
className?: string;
}
const Feature249 = ({ className }: Feature249Props) => {
return (
<section dir="rtl" lang="fa" className={cn("py-32", className)}>
<div className="container">
<ContainerScroll
titleComponent={
<>
<p className="mx-auto mb-4 text-pretty text-muted-foreground md:text-xl">
با یادآورهای هوشمند و اولویت‌بندی سرنخ، زمان تیم روی معاملات با احتمال بیشتر صرف می‌شود و چرخه فروش کوتاه‌تر می‌شود.
</p>
<h1 className="text-2xll font-semibold tracking-tighter text-balance md:text-8xl xl:text-[10rem]">
<span className="pe-6 text-muted-foreground/40">پیش‌بینی درآمد را دقیق‌تر کنید</span>
<AuroraText
colors={["#ff6449", "#ff6449", "#6248fe", "#6248fe"]}
>
چرخه فروش را از سرنخ تا قرارداد در یک مسیر مشخص پیش ببرید. مدیران می‌توانند گلوگاه‌ها را ببینند و تیم‌ها با اولویت درست روی معاملات ارزشمند تمرکز کنند.
</AuroraText>
</h1>
</>
}
>
<img
src="/block-media/shadcnblocks/block/dashboard/admin-dashboard-1.png"
alt="صف اولویت سرنخ‌ها"
height={720}
width={1400}
className="mx-auto size-full rounded-2xl object-cover object-start-top"
draggable={false}
/>
</ContainerScroll>
</div>
</section>
);
};
export { Feature249 };
// Below is the modified component from Aceternity UI
// Original source: npx shadcn@latest add https://ui.aceternity.com/registry/container-scroll-animation.json
// Modified to follow our coding standards and design system
// We respect copyright and attribution to the original creators
export const ContainerScroll = ({
titleComponent,
children,
}: {
titleComponent: string | React.ReactNode;
children: React.ReactNode;
}) => {
const containerRef = useRef<HTMLDivElement>(null);
const { scrollYProgress } = useScroll({
target: containerRef,
});
const [isMobile, setIsMobile] = React.useState(false);
React.useEffect(() => {
const checkMobile = () => {
setIsMobile(window.innerWidth <= 768);
};
checkMobile();
window.addEventListener("resize", checkMobile);
return () => {
window.removeEventListener("resize", checkMobile);
};
}, []);
const scaleDimensions = () => {
return isMobile ? [0.7, 0.9] : [1.05, 1];
};
const rotate = useTransform(scrollYProgress, [0, 1], [20, 0]);
const scale = useTransform(scrollYProgress, [0, 1], scaleDimensions());
const translate = useTransform(scrollYProgress, [0, 1], [0, -100]);
return (
<div
className="relative flex h-[60rem] items-center justify-center"
ref={containerRef}
>
<div
className="relative w-full"
style={{
perspective: "1000px",
}}
>
<Header translate={translate} titleComponent={titleComponent} />
<Card rotate={rotate} translate={translate} scale={scale}>
{children}
</Card>
</div>
</div>
);
};
export const Header = ({
translate,
titleComponent,
}: {
translate: MotionValue<number>;
titleComponent: React.ReactNode;
}) => {
return (
<motion.div
style={{
translateY: translate,
}}
className="div mx-auto max-w-5xl text-center"
>
{titleComponent}
</motion.div>
);
};
export const Card = ({
rotate,
scale,
children,
}: {
rotate: MotionValue<number>;
scale: MotionValue<number>;
translate: MotionValue<number>;
children: React.ReactNode;
}) => {
return (
<motion.div
style={{
rotateX: rotate,
scale,
}}
className="-4 mx-auto -mt-12 h-[30rem] w-full max-w-5xl rounded-[30px] p-2 shadow-2xl md:h-[40rem] md:p-6"
>
<div className="size-full overflow-hidden rounded-2xl bg-gray-100 md:rounded-2xl md:p-4 dark:bg-zinc-900">
{children}
</div>
</motion.div>
);
};