Skip to content

Commit

Permalink
Add qr code & use mouse & improve cursor performances (#35)
Browse files Browse the repository at this point in the history
* ✨ ⚡️ Add useMouse & refacto components

* 🎨 Force component type to have releaseDate

* ⚡️ Improve cursor effects performance & move home page to sever side

* ✨ add QR Code generator component

* 🎨 refacto the other section

* 🔧 Fix Vite CJS Node API deprecated by renaming mts
  • Loading branch information
damien-schneider authored Sep 24, 2024
1 parent 104095e commit 2556584
Show file tree
Hide file tree
Showing 43 changed files with 1,093 additions and 888 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"next": "14.2.3",
"next-themes": "0.3.0",
"path": "0.12.7",
"qrcode.react": "4.0.1",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-frame-component": "5.2.7",
Expand Down
12 changes: 12 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

134 changes: 27 additions & 107 deletions src/app/card.tsx
Original file line number Diff line number Diff line change
@@ -1,123 +1,43 @@
"use client";
import { ArrowUpRightIcon } from "lucide-react";
import Image from "next/image";
import React, { useRef, useEffect, useState } from "react";

import { cn } from "#/src/utils/cn";
import type { CategoryType } from "../lib/types/component";

export const MainMenuCard = ({
className,
category,
target,
nameIfNotCategory: name,
descriptionIfNotCategory: description,
}: {
className?: string;
category?: CategoryType;
target?: "_blank" | "_self";
nameIfNotCategory?: string;
descriptionIfNotCategory?: string;
}) => {
const { x, y, parentRef } = useMousePosition();

return (
<div
ref={parentRef}
style={{
//@ts-ignore : This is a valid css variable
"--x": `${x}px`,
"--y": `${y}px`,
}}
className={cn(
"relative overflow-hidden rounded-[20px] p-2 h-full group ",
className,
)}
>
{target === "_blank" && (
<ArrowUpRightIcon className="absolute top-2 right-2 text-neutral-700 dark:text-neutral-300 size-5 group-hover:opacity-100 group-hover:translate-y-0 opacity-0 translate-y-4 transition-all z-10 transform-gpu" />
)}
if (category?.comingSoonCategory) {
return (
<p className="text-2xl top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 font-semibold text-neutral-800 dark:text-neutral-300 absolute">
Coming Soon
</p>
);
}
if (category?.previewCategory?.previewImage) {
return (
<Image
className="object-cover w-full h-48"
width={600}
height={400}
alt={`${category.name} preview`}
src={category.previewCategory.previewImage}
/>
);
}
if (category?.previewCategory?.component) {
return (
<div
className={cn(
"size-40 rounded-full blur-3xl absolute top-[var(--y)] left-[var(--x)] -translate-x-1/2 -translate-y-1/2 group-hover:scale-[5] scale transition-transform duration-300 transform-gpu",
(x === null || y === null) && "hidden",
"pointer-events-none select-none flex justify-center items-center w-full h-full",
)}
style={{
background:
"linear-gradient(135deg, #3BC4F2, #7A69F9,#F26378,#F5833F)",
transform: `scale(${category.previewCategory?.previewScale ?? 0.75})`,
}}
/>
<div className="absolute inset-px rounded-[19px] dark:bg-neutral-900/70 bg-neutral-100/90" />

{category?.previewCategory?.component || category?.comingSoonCategory ? (
<div className="relative flex items-center justify-center w-full object-cover rounded-2xl bg-white/50 dark:bg-neutral-950/50 h-48 overflow-hidden">
{category.comingSoonCategory ? (
<div className="absolute inset-0 flex items-center justify-center">
<div className="text-2xl font-semibold text-neutral-800 dark:text-neutral-300">
Coming Soon
</div>
</div>
) : category.previewCategory?.previewImage ? (
<Image
className="object-cover w-full h-full"
width={600}
height={400}
alt={`${category.name} preview`}
src={category.previewCategory.previewImage}
/>
) : (
<div
className={cn(
"pointer-events-none select-none flex justify-center items-center w-full h-full",
)}
style={{
transform: `scale(${
category.previewCategory?.previewScale ?? 0.75
})`,
}}
>
{category.previewCategory?.component}
</div>
)}
</div>
) : null}
<div className="relative px-4 pb-2 pt-4">
<h3 className="text-lg font-semibold text-neutral-800 dark:text-neutral-300">
{category?.name ?? name}
</h3>
<p className="mt-2 text-neutral-600 dark:text-neutral-400">
{category?.description ?? description}
</p>
>
{category.previewCategory?.component}
</div>
</div>
);
};

type MousePosition = {
x: number | null;
y: number | null;
};

const useMousePosition = () => {
const [mousePosition, setMousePosition] = useState<MousePosition>({
x: null,
y: null,
});
const parentRef = useRef<HTMLDivElement>(null);

useEffect(() => {
const updateMousePosition = (event: MouseEvent) => {
if (parentRef.current) {
const bounds = parentRef.current.getBoundingClientRect();
const x = event.clientX - bounds.left;
const y = event.clientY - bounds.top;
setMousePosition({ x, y });
}
};
window.addEventListener("mousemove", updateMousePosition);
return () => {
window.removeEventListener("mousemove", updateMousePosition);
};
}, []);

return { ...mousePosition, parentRef };
);
}
};
22 changes: 13 additions & 9 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
"use client";
import Link from "next/link";
// import GradientContainer from "../ui/gradient-container";

import { SectionsList } from "#/src/lib/cuicui-components/sections-list";
import { firstMenuSection } from "#/src/lib/first-menu-section";
import { GradientCard } from "#/src/ui/cuicui/other/cursors/dynamic-cards/gradient-card";
import { MainMenuCard } from "./card";

export default function HomePage() {
Expand All @@ -27,12 +27,11 @@ export default function HomePage() {
href={category.href ?? `/${category.slug}`}
key={category.name}
data-testid={`home-navigation-link-${category.name}`}
className="group hover:scale-[1.01] hover:-translate-y-[2px] transition-all active:scale-95 rounded-[20px] overflow-hidden"
>
<MainMenuCard
nameIfNotCategory={category.name}
descriptionIfNotCategory={category.description}
target={category.href ? "_blank" : "_self"}
<GradientCard
description={category.description}
title={category.name}
withArrow={Boolean(category.href)}
/>
</Link>
);
Expand All @@ -44,15 +43,20 @@ export default function HomePage() {
<div key={section.name} className="space-y-5">
<h3 className="uppercase-title">{section.name}</h3>

<div className="grid grid-cols-1 gap-5 lg:grid-cols-2 transform-gpu">
<div className="grid grid-cols-1 gap-5 lg:grid-cols-2">
{section.categoriesList.map((category) => {
return (
<Link
href={`/${section.slug}/${category.slug}`}
key={category.name}
className="group hover:scale-[1.01] hover:-translate-y-[2px] transition-all active:scale-95 rounded-[20px] overflow-hidden"
>
<MainMenuCard category={category} />
<GradientCard
description={category.description}
title={category.name}
>
<MainMenuCard category={category} />
</GradientCard>
{/* <MainMenuCard category={category} /> */}
</Link>
);
})}
Expand Down
1 change: 1 addition & 0 deletions src/lib/cuicui-components/common-ui-components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export const commonUICategoriesList: CategoryType[] = [
description: "Create simple avatars with different styles",
comingSoonCategory: true,
icon: CircleUserRoundIcon,
releaseDateCategory: new Date(),
componentList: null,
},
{
Expand Down
Loading

0 comments on commit 2556584

Please sign in to comment.