Skip to content
Open
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
341 changes: 341 additions & 0 deletions apps/core/app/(landing)/_assets/be.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
103 changes: 103 additions & 0 deletions apps/core/app/(landing)/_assets/logo-brand.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
155 changes: 155 additions & 0 deletions apps/core/app/(landing)/become-auther/_components/3d-card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
"use client";

import { cn } from "@repo/ui/lib/utils";

import React, {
createContext,
useState,
useContext,
useRef,
useEffect,
} from "react";

const MouseEnterContext = createContext<
[boolean, React.Dispatch<React.SetStateAction<boolean>>] | undefined
>(undefined);

export const CardContainer = ({
children,
className,
containerClassName,
}: {
children?: React.ReactNode;
className?: string;
containerClassName?: string;
}) => {
const containerRef = useRef<HTMLDivElement>(null);
const [isMouseEntered, setIsMouseEntered] = useState(false);

const handleMouseMove = (e: React.MouseEvent<HTMLDivElement>) => {
if (!containerRef.current) return;
const { left, top, width, height } =
containerRef.current.getBoundingClientRect();
const x = (e.clientX - left - width / 2) / 25;
const y = (e.clientY - top - height / 2) / 25;
containerRef.current.style.transform = `rotateY(${x}deg) rotateX(${y}deg)`;
};

const handleMouseEnter = (e: React.MouseEvent<HTMLDivElement>) => {
setIsMouseEntered(true);
if (!containerRef.current) return;
};

const handleMouseLeave = (e: React.MouseEvent<HTMLDivElement>) => {
if (!containerRef.current) return;
setIsMouseEntered(false);
containerRef.current.style.transform = `rotateY(0deg) rotateX(0deg)`;
};
return (
<MouseEnterContext.Provider value={[isMouseEntered, setIsMouseEntered]}>
<div
className={cn(
"w-full flex items-center justify-center",
containerClassName
)}
style={{
perspective: "1000px",
}}
>
<div
ref={containerRef}
onMouseEnter={handleMouseEnter}
onMouseMove={handleMouseMove}
onMouseLeave={handleMouseLeave}
className={cn(
"flex w-full items-center justify-center relative transition-all duration-200 ease-linear",
className
)}
style={{
transformStyle: "preserve-3d",
}}
>
{children}
</div>
</div>
</MouseEnterContext.Provider>
);
};

export const CardBody = ({
children,
className,
}: {
children: React.ReactNode;
className?: string;
}) => {
return (
<div
className={cn(
"[transform-style:preserve-3d] [&>*]:[transform-style:preserve-3d]",
className
)}
>
{children}
</div>
);
};

export const CardItem = ({
as: Tag = "div",
children,
className,
translateX = 0,
translateY = 0,
translateZ = 0,
rotateX = 0,
rotateY = 0,
rotateZ = 0,
...rest
}: {
as?: React.ElementType;
children: React.ReactNode;
className?: string;
translateX?: number | string;
translateY?: number | string;
translateZ?: number | string;
rotateX?: number | string;
rotateY?: number | string;
rotateZ?: number | string;
[key: string]: any;
Comment on lines +113 to +119
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Handle units consistently for transform values

The component accepts numbers or strings for translation and rotation values, but applies them directly with fixed units (px/deg). This could cause issues if string values already include units.

 const handleAnimations = () => {
   if (!ref.current) return;
   if (isMouseEntered) {
-    ref.current.style.transform = `translateX(${translateX}px) translateY(${translateY}px) translateZ(${translateZ}px) rotateX(${rotateX}deg) rotateY(${rotateY}deg) rotateZ(${rotateZ}deg)`;
+    ref.current.style.transform = `translateX(${typeof translateX === 'number' ? translateX + 'px' : translateX}) translateY(${typeof translateY === 'number' ? translateY + 'px' : translateY}) translateZ(${typeof translateZ === 'number' ? translateZ + 'px' : translateZ}) rotateX(${typeof rotateX === 'number' ? rotateX + 'deg' : rotateX}) rotateY(${typeof rotateY === 'number' ? rotateY + 'deg' : rotateY}) rotateZ(${typeof rotateZ === 'number' ? rotateZ + 'deg' : rotateZ})`;
   } else {
     ref.current.style.transform = `translateX(0px) translateY(0px) translateZ(0px) rotateX(0deg) rotateY(0deg) rotateZ(0deg)`;
   }
 };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
translateX?: number | string;
translateY?: number | string;
translateZ?: number | string;
rotateX?: number | string;
rotateY?: number | string;
rotateZ?: number | string;
[key: string]: any;
const handleAnimations = () => {
if (!ref.current) return;
if (isMouseEntered) {
ref.current.style.transform =
`translateX(${typeof translateX === 'number' ? translateX + 'px' : translateX}) ` +
`translateY(${typeof translateY === 'number' ? translateY + 'px' : translateY}) ` +
`translateZ(${typeof translateZ === 'number' ? translateZ + 'px' : translateZ}) ` +
`rotateX(${typeof rotateX === 'number' ? rotateX + 'deg' : rotateX}) ` +
`rotateY(${typeof rotateY === 'number' ? rotateY + 'deg' : rotateY}) ` +
`rotateZ(${typeof rotateZ === 'number' ? rotateZ + 'deg' : rotateZ})`;
} else {
ref.current.style.transform =
`translateX(0px) translateY(0px) translateZ(0px) ` +
`rotateX(0deg) rotateY(0deg) rotateZ(0deg)`;
}
};
🤖 Prompt for AI Agents
In apps/core/app/(landing)/become-auther/_components/3d-card.tsx around lines
113 to 119, the transform props accept both numbers and strings but apply fixed
units (px for translate, deg for rotate) without checking if the string already
includes units. To fix this, update the code to detect if a string value already
contains units and use it as-is; if the value is a number, append the
appropriate unit (px for translate, deg for rotate). This ensures consistent and
correct unit handling for all transform values.

}) => {
const ref = useRef<HTMLDivElement>(null);
const [isMouseEntered] = useMouseEnter();

useEffect(() => {
handleAnimations();
}, [isMouseEntered]);

const handleAnimations = () => {
if (!ref.current) return;
if (isMouseEntered) {
ref.current.style.transform = `translateX(${translateX}px) translateY(${translateY}px) translateZ(${translateZ}px) rotateX(${rotateX}deg) rotateY(${rotateY}deg) rotateZ(${rotateZ}deg)`;
} else {
ref.current.style.transform = `translateX(0px) translateY(0px) translateZ(0px) rotateX(0deg) rotateY(0deg) rotateZ(0deg)`;
}
};

Comment on lines +124 to +136
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Consider dependencies in useEffect

The useEffect dependency array only includes isMouseEntered, but the effect calls handleAnimations() which depends on all the transform props. If those props change, the effect won't run.

 useEffect(() => {
   handleAnimations();
- }, [isMouseEntered]);
+ }, [isMouseEntered, translateX, translateY, translateZ, rotateX, rotateY, rotateZ]);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
useEffect(() => {
handleAnimations();
}, [isMouseEntered]);
const handleAnimations = () => {
if (!ref.current) return;
if (isMouseEntered) {
ref.current.style.transform = `translateX(${translateX}px) translateY(${translateY}px) translateZ(${translateZ}px) rotateX(${rotateX}deg) rotateY(${rotateY}deg) rotateZ(${rotateZ}deg)`;
} else {
ref.current.style.transform = `translateX(0px) translateY(0px) translateZ(0px) rotateX(0deg) rotateY(0deg) rotateZ(0deg)`;
}
};
useEffect(() => {
handleAnimations();
}, [isMouseEntered, translateX, translateY, translateZ, rotateX, rotateY, rotateZ]);
🤖 Prompt for AI Agents
In apps/core/app/(landing)/become-auther/_components/3d-card.tsx around lines
124 to 136, the useEffect hook depends only on isMouseEntered but calls
handleAnimations which uses multiple transform-related props like translateX,
translateY, translateZ, rotateX, rotateY, and rotateZ. To fix this, include all
these transform props in the useEffect dependency array so the effect runs
whenever any of them change, ensuring the animation updates correctly.

return (
<Tag
ref={ref}
className={cn(" transition duration-200 ease-linear", className)}
{...rest}
>
{children}
</Tag>
);
};

// Create a hook to use the context
export const useMouseEnter = () => {
const context = useContext(MouseEnterContext);
if (context === undefined) {
throw new Error("useMouseEnter must be used within a MouseEnterProvider");
}
return context;
};
Loading