From 8b50243bfdb60f491527930f99674a606595762a Mon Sep 17 00:00:00 2001
From: Kinfe Michael Tariku <65047246+Kinfe123@users.noreply.github.com>
Date: Tue, 20 Feb 2024 21:18:28 +0300
Subject: [PATCH] fmt on hero (#31)
* fmt on landing page
* adding cn utils
* adding checkmark for copy
* fmt fix
---
.../_components/copy-to-clipboard.tsx | 13 +++-
src/app/(landing)/_components/hover-card.tsx | 77 +++++++++++++++++++
src/app/(landing)/page.tsx | 21 +----
src/server/db/util.ts | 8 ++
4 files changed, 99 insertions(+), 20 deletions(-)
create mode 100644 src/app/(landing)/_components/hover-card.tsx
diff --git a/src/app/(landing)/_components/copy-to-clipboard.tsx b/src/app/(landing)/_components/copy-to-clipboard.tsx
index ab70ac7..a41ee31 100644
--- a/src/app/(landing)/_components/copy-to-clipboard.tsx
+++ b/src/app/(landing)/_components/copy-to-clipboard.tsx
@@ -2,17 +2,24 @@
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
-import { CopyIcon } from "@radix-ui/react-icons";
+import { cn } from "@/lib/utils";
+import { CopyIcon , CheckIcon} from "@radix-ui/react-icons";
+import { useState } from "react";
import { toast } from "sonner";
export const CopyToClipboard = ({ text }: { text: string }) => {
+
+ const [copied , setCopied] = useState(false)
const copyToClipboard = async () => {
+ setCopied(true)
+ setTimeout(() => {
+ setCopied(false)
+ } , 2000)
await navigator.clipboard.writeText(text);
toast("Copied to clipboard", {
icon: ,
});
};
-
return (
{
className="bg-secondary text-muted-foreground"
/>
);
diff --git a/src/app/(landing)/_components/hover-card.tsx b/src/app/(landing)/_components/hover-card.tsx
new file mode 100644
index 0000000..414219c
--- /dev/null
+++ b/src/app/(landing)/_components/hover-card.tsx
@@ -0,0 +1,77 @@
+'use client';
+import { Card, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
+import React, { type SVGProps, useRef, useState, FC, type ForwardRefExoticComponent, type RefAttributes } from 'react';
+
+
+
+type FeaturesProps = {
+ name: string;
+ description: string;
+ logo: React.ReactNode;
+}
+
+const CardSpotlight = (props: FeaturesProps) => {
+ const divRef = useRef(null);
+ const [isFocused, setIsFocused] = useState(false);
+ const [position, setPosition] = useState({ x: 0, y: 0 });
+ const [opacity, setOpacity] = useState(0);
+
+ const handleMouseMove = (e: React.MouseEvent) => {
+ if (!divRef.current || isFocused) return;
+
+ const div = divRef.current;
+ const rect = div.getBoundingClientRect();
+
+ setPosition({ x: e.clientX - rect.left, y: e.clientY - rect.top });
+ };
+
+ const handleFocus = () => {
+ setIsFocused(true);
+ setOpacity(1);
+ };
+
+ const handleBlur = () => {
+ setIsFocused(false);
+ setOpacity(0);
+ };
+
+ const handleMouseEnter = () => {
+ setOpacity(1);
+ };
+
+ const handleMouseLeave = () => {
+ setOpacity(0);
+ };
+
+ return (
+
+
+
+
+
+ {props.logo}
+
+
+ {props.name}
+ {props.description}
+
+
+
+ );
+};
+
+export default CardSpotlight;
diff --git a/src/app/(landing)/page.tsx b/src/app/(landing)/page.tsx
index 1ca89c6..483dd3c 100644
--- a/src/app/(landing)/page.tsx
+++ b/src/app/(landing)/page.tsx
@@ -16,12 +16,7 @@ import {
StripeLogo,
ReactEmail,
} from "./_components/feature-icons";
-import {
- Card,
- CardDescription,
- CardHeader,
- CardTitle,
-} from "@/components/ui/card";
+import CardSpotlight from "./_components/hover-card";
export const metadata: Metadata = {
title: "Next.js Lucia Auth Starter Template",
@@ -83,14 +78,14 @@ const features = [
const HomePage = () => {
return (
<>
-
+
-
+
Next.js Lucia Auth Starter Template
@@ -128,15 +123,7 @@ const HomePage = () => {
{features.map((feature) => (
-
-
-
-
-
- {feature.name}
- {feature.description}
-
-
+
} />
))}
diff --git a/src/server/db/util.ts b/src/server/db/util.ts
index ca4ebe1..2dd957a 100644
--- a/src/server/db/util.ts
+++ b/src/server/db/util.ts
@@ -1,4 +1,12 @@
import { mysqlTableCreator } from "drizzle-orm/mysql-core";
import { DATABASE_PREFIX as prefix } from "@/lib/constants";
+import { twMerge } from "tailwind-merge";
+import clsx, {type ClassValue } from "clsx";
export const mysqlTable = mysqlTableCreator((name) => `${prefix}_${name}`);
+
+
+export function cn(...inputs: ClassValue[]) {
+ return twMerge(clsx(inputs))
+ }
+
\ No newline at end of file