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
5 changes: 1 addition & 4 deletions web/src/app/blogs/BlogsClient.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,7 @@ export default function BlogsClient({
/>

{/* Blogs Grid */}
<div
ref={gridRef}
className="mt-12 grid w-full max-w-7xl grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3"
>
<div ref={gridRef} className="mt-12 w-full max-w-7xl">
{filteredBlogs.map((blog) => (
<BlogCard
key={blog.slug}
Expand Down
96 changes: 5 additions & 91 deletions web/src/app/blogs/components/BlogCard.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client';

import React, { useRef, useEffect } from 'react';

Check warning on line 3 in web/src/app/blogs/components/BlogCard.tsx

View workflow job for this annotation

GitHub Actions / build

'useRef' is defined but never used. Allowed unused vars must match /^_/u
import Link from 'next/link';
import gsap from 'gsap';

Expand All @@ -19,103 +19,17 @@
excerpt,
tags,
}: BlogCardProps) => {
const cardRef = useRef<HTMLDivElement>(null);

const glowRef = useRef<HTMLDivElement>(null);

useEffect(() => {
const card = cardRef.current;

const glow = glowRef.current;

if (!card || !glow) return;

const handleMouseMove = (e: MouseEvent) => {
const rect = card.getBoundingClientRect();

const x = e.clientX - rect.left;

const y = e.clientY - rect.top;

const rotateX = (y / rect.height - 0.5) * -10;

const rotateY = (x / rect.width - 0.5) * 10;

// Card tilt
gsap.to(card, {
rotateX,
rotateY,
duration: 0.4,
ease: 'power2.out',
transformPerspective: 1000,
});

// Glow follows mouse exactly
gsap.to(glow, {
x,
y,
duration: 0.25,
ease: 'power3.out',
});
};

const handleMouseEnter = () => {
gsap.to(glow, {
opacity: 0.12,
scale: 1,
duration: 0.3,
});
};

const handleMouseLeave = () => {
gsap.to(card, {
rotateX: 0,
rotateY: 0,
duration: 0.5,
ease: 'power2.out',
});

gsap.to(glow, {
opacity: 0,
scale: 0.8,
duration: 0.4,
ease: 'power2.out',
});
};

card.addEventListener('mousemove', handleMouseMove);

card.addEventListener('mouseenter', handleMouseEnter);

card.addEventListener('mouseleave', handleMouseLeave);

return () => {
card.removeEventListener('mousemove', handleMouseMove);

card.removeEventListener('mouseenter', handleMouseEnter);

card.removeEventListener('mouseleave', handleMouseLeave);
};
}, []);

return (
<Link href={`blogs/${slug}`} className="group block perspective-[1200px]">
<Link
href={`blogs/${slug}`}
className="group mt-25 block perspective-[1200px]"
>
<div
ref={cardRef}
className="glass premium-shadow hover:border-foreground relative flex flex-col gap-4 overflow-hidden rounded-2xl border-r border-b p-6 transition-colors will-change-transform"
className="glass premium-shadow border-foreground/20 relative flex flex-col gap-4 overflow-hidden border-b pb-5"
style={{
transformStyle: 'preserve-3d',
}}
>
{/* Moving Glow Ball */}
<div
ref={glowRef}
className="bg-foreground pointer-events-none absolute top-0 left-0 z-0 h-40 w-40 rounded-full opacity-0"
style={{
transform: 'translate(-50%, -50%)',
}}
/>

<div className="relative z-10 flex items-center justify-between">
<span className="bg-foreground text-background rounded-full px-3 py-1 text-xs font-medium">
{category}
Expand Down
Loading