Skip to content

Commit

Permalink
fmt on hero (#31)
Browse files Browse the repository at this point in the history
* fmt on landing page

* adding cn utils

* adding checkmark for copy

* fmt fix
  • Loading branch information
Kinfe123 authored Feb 20, 2024
1 parent 4f814b8 commit 8b50243
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 20 deletions.
13 changes: 10 additions & 3 deletions src/app/(landing)/_components/copy-to-clipboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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: <CopyIcon className="h-4 w-4" />,
});
};

return (
<div className="flex justify-center gap-3">
<Input
Expand All @@ -21,7 +28,7 @@ export const CopyToClipboard = ({ text }: { text: string }) => {
className="bg-secondary text-muted-foreground"
/>
<Button size="icon" onClick={() => copyToClipboard()}>
<CopyIcon className="h-5 w-5" />
{copied ? <CheckIcon className={cn( copied ? "opacity-100": "opacity-0" , "h-5 w-5 transition-opacity duration-500" )}/>: <CopyIcon className="h-5 w-5" />}
</Button>
</div>
);
Expand Down
77 changes: 77 additions & 0 deletions src/app/(landing)/_components/hover-card.tsx
Original file line number Diff line number Diff line change
@@ -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<HTMLDivElement>(null);
const [isFocused, setIsFocused] = useState(false);
const [position, setPosition] = useState({ x: 0, y: 0 });
const [opacity, setOpacity] = useState(0);

const handleMouseMove = (e: React.MouseEvent<HTMLDivElement>) => {
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 (
<Card
ref={divRef}
onMouseMove={handleMouseMove}
onFocus={handleFocus}
onBlur={handleBlur}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
className='relative overflow-hidden rounded-xl border dark:border-gray-800 bg-white dark:bg-gradient-to-r dark:from-black dark:to-neutral-950 dark:shadow-2xl'
>

<div
className='pointer-events-none absolute -inset-px opacity-0 transition duration-300'
style={{
opacity,
background: `radial-gradient(600px circle at ${position.x}px ${position.y}px, rgba(255,182,255,.1), transparent 40%)`,
}}
/>
<div className="pl-6 pt-6">

{props.logo}
</div>
<CardHeader className="pb-6">
<CardTitle className="text-xl">{props.name}</CardTitle>
<CardDescription>{props.description}</CardDescription>
</CardHeader>

</Card>
);
};

export default CardSpotlight;
21 changes: 4 additions & 17 deletions src/app/(landing)/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -83,14 +78,14 @@ const features = [
const HomePage = () => {
return (
<>
<section className="mx-auto grid min-h-[calc(100vh-80px)] items-center">
<section className="mx-auto grid min-h-[calc(100vh-300px)] max-w-5xl flex-col justify-center gap-4 py-10 md:py-12 text-center items-center">
<div className="p-4">
<div className="mb-10 flex items-center justify-center gap-3">
<NextjsIcon className="h-[52px] w-[52px]" />
<PlusIcon className="h-8 w-8" />
<LuciaAuth className="h-14 w-14" />
</div>
<h1 className="text-balance text-center text-3xl font-bold md:text-4xl lg:text-5xl">
<h1 className="text-balance text-center bg-gradient-to-tr from-black/70 via-black to-black/60 dark:from-zinc-400/10 dark:via-white/90 dark:to-white/20 bg-clip-text text-transparent text-3xl font-bold sm:text-5xl md:text-6xl lg:text-7xl">
Next.js Lucia Auth Starter Template
</h1>
<p className="text-balance mb-10 mt-4 text-center text-muted-foreground md:text-lg lg:text-xl">
Expand Down Expand Up @@ -128,15 +123,7 @@ const HomePage = () => {
</p>
<div className="grid gap-6 sm:grid-cols-2 md:grid-cols-3">
{features.map((feature) => (
<Card key={feature.name}>
<div className="pl-6 pt-6">
<feature.logo className="h-12 w-12" />
</div>
<CardHeader className="pb-6">
<CardTitle className="text-xl">{feature.name}</CardTitle>
<CardDescription>{feature.description}</CardDescription>
</CardHeader>
</Card>
<CardSpotlight name={feature.name} description={feature.description} logo={<feature.logo className='w-12 h-12' />} />
))}
</div>
</div>
Expand Down
8 changes: 8 additions & 0 deletions src/server/db/util.ts
Original file line number Diff line number Diff line change
@@ -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))
}

0 comments on commit 8b50243

Please sign in to comment.