mirror of
https://github.com/fergalmoran/opengifame.git
synced 2025-12-22 09:38:44 +00:00
MagicUI added (undecided for now)
This commit is contained in:
@@ -14,7 +14,6 @@
|
||||
"components": "@/components",
|
||||
"utils": "@/lib/utils",
|
||||
"ui": "@/components/ui",
|
||||
"lib": "@/lib",
|
||||
"hooks": "@/hooks"
|
||||
"magicui": "@/components/magicui"
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@
|
||||
"db:migrate": "drizzle-kit migrate",
|
||||
"db:push": "drizzle-kit push",
|
||||
"db:studio": "drizzle-kit studio",
|
||||
"dev:turbo": "NODE_ENV=development next dev -p 3002 --turbo & local-ssl-proxy --config ./ssl-proxy.json",
|
||||
"dev": "NODE_ENV=development next dev -p 3002 & local-ssl-proxy --config ./ssl-proxy.json",
|
||||
"dev:plain": "next dev",
|
||||
"lint": "next lint",
|
||||
@@ -65,6 +66,7 @@
|
||||
"date-fns": "^4.0.0",
|
||||
"drizzle-orm": "^0.33.0",
|
||||
"embla-carousel-react": "^8.3.0",
|
||||
"framer-motion": "^11.5.4",
|
||||
"geist": "^1.3.1",
|
||||
"http-status-codes": "^2.3.0",
|
||||
"input-otp": "^1.2.4",
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
import React from "react";
|
||||
import { SessionProvider } from "next-auth/react";
|
||||
|
||||
|
||||
79
src/components/magicui/bento-grid.tsx
Normal file
79
src/components/magicui/bento-grid.tsx
Normal file
@@ -0,0 +1,79 @@
|
||||
import { ReactNode } from "react";
|
||||
import { ArrowRightIcon } from "@radix-ui/react-icons";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
||||
const BentoGrid = ({
|
||||
children,
|
||||
className,
|
||||
}: {
|
||||
children: ReactNode;
|
||||
className?: string;
|
||||
}) => {
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"grid w-full auto-rows-[22rem] grid-cols-3 gap-4",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const BentoCard = ({
|
||||
name,
|
||||
className,
|
||||
background,
|
||||
Icon,
|
||||
description,
|
||||
href,
|
||||
cta,
|
||||
}: {
|
||||
name: string;
|
||||
className: string;
|
||||
background: ReactNode;
|
||||
Icon: any;
|
||||
description: string;
|
||||
href: string;
|
||||
cta: string;
|
||||
}) => (
|
||||
<div
|
||||
key={name}
|
||||
className={cn(
|
||||
"group relative col-span-3 flex flex-col justify-between overflow-hidden rounded-xl",
|
||||
// light styles
|
||||
"bg-white [box-shadow:0_0_0_1px_rgba(0,0,0,.03),0_2px_4px_rgba(0,0,0,.05),0_12px_24px_rgba(0,0,0,.05)]",
|
||||
// dark styles
|
||||
"transform-gpu dark:bg-black dark:[border:1px_solid_rgba(255,255,255,.1)] dark:[box-shadow:0_-20px_80px_-20px_#ffffff1f_inset]",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<div>{background}</div>
|
||||
<div className="pointer-events-none z-10 flex transform-gpu flex-col gap-1 p-6 transition-all duration-300 group-hover:-translate-y-10">
|
||||
<Icon className="h-12 w-12 origin-left transform-gpu text-neutral-700 transition-all duration-300 ease-in-out group-hover:scale-75" />
|
||||
<h3 className="text-xl font-semibold text-neutral-700 dark:text-neutral-300">
|
||||
{name}
|
||||
</h3>
|
||||
<p className="max-w-lg text-neutral-400">{description}</p>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={cn(
|
||||
"pointer-events-none absolute bottom-0 flex w-full translate-y-10 transform-gpu flex-row items-center p-4 opacity-0 transition-all duration-300 group-hover:translate-y-0 group-hover:opacity-100",
|
||||
)}
|
||||
>
|
||||
<Button variant="ghost" asChild size="sm" className="pointer-events-auto">
|
||||
<a href={href}>
|
||||
{cta}
|
||||
<ArrowRightIcon className="ml-2 h-4 w-4" />
|
||||
</a>
|
||||
</Button>
|
||||
</div>
|
||||
<div className="pointer-events-none absolute inset-0 transform-gpu transition-all duration-300 group-hover:bg-black/[.03] group-hover:dark:bg-neutral-800/10" />
|
||||
</div>
|
||||
);
|
||||
|
||||
export { BentoCard, BentoGrid };
|
||||
39
src/components/magicui/blur-in.tsx
Normal file
39
src/components/magicui/blur-in.tsx
Normal file
@@ -0,0 +1,39 @@
|
||||
"use client";
|
||||
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
interface BlurIntProps {
|
||||
word: string;
|
||||
className?: string;
|
||||
variant?: {
|
||||
hidden: { filter: string; opacity: number };
|
||||
visible: { filter: string; opacity: number };
|
||||
};
|
||||
duration?: number;
|
||||
}
|
||||
const BlurIn = ({ word, className, variant, duration = 1 }: BlurIntProps) => {
|
||||
const defaultVariants = {
|
||||
hidden: { filter: "blur(10px)", opacity: 0 },
|
||||
visible: { filter: "blur(0px)", opacity: 1 },
|
||||
};
|
||||
const combinedVariants = variant || defaultVariants;
|
||||
|
||||
return (
|
||||
<motion.h1
|
||||
initial="hidden"
|
||||
animate="visible"
|
||||
transition={{ duration }}
|
||||
variants={combinedVariants}
|
||||
className={cn(
|
||||
"font-display text-center text-4xl font-bold tracking-[-0.02em] drop-shadow-sm md:text-7xl md:leading-[5rem]",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
{word}
|
||||
</motion.h1>
|
||||
);
|
||||
};
|
||||
|
||||
export default BlurIn;
|
||||
@@ -1,29 +1,41 @@
|
||||
"use client";
|
||||
import { BellIcon } from "@radix-ui/react-icons";
|
||||
|
||||
import { useState } from "react";
|
||||
import { BentoCard, BentoGrid } from "@/components/magicui/bento-grid";
|
||||
import { api } from "@/trpc/server";
|
||||
|
||||
import { api } from "@/trpc/react";
|
||||
import Image from "next/image";
|
||||
const createGridCard = (
|
||||
key: string,
|
||||
url: string,
|
||||
title: string,
|
||||
description: string,
|
||||
tags: string[],
|
||||
) => {
|
||||
const value = {
|
||||
Icon: BellIcon,
|
||||
name: title,
|
||||
description: description,
|
||||
href: "/",
|
||||
cta: "Learn more",
|
||||
background: <img className="h-128 absolute w-full" src={url} />,
|
||||
className: "col-span-1 row-start-1 row-end-4",
|
||||
};
|
||||
|
||||
export function TrendingImages() {
|
||||
const [latestImages] = api.image.getTrending.useSuspenseQuery();
|
||||
return <BentoCard key={key} {...value} />;
|
||||
};
|
||||
|
||||
export async function TrendingImages() {
|
||||
const latestImages = await api.image.getTrending();
|
||||
return (
|
||||
<div className="w-full max-w-xs">
|
||||
{latestImages ? (
|
||||
latestImages.map((image) => (
|
||||
<Image
|
||||
key={image.id}
|
||||
src={image.url}
|
||||
alt={image.title ?? "An image"}
|
||||
width={320}
|
||||
height={320}
|
||||
/>
|
||||
// <img src={image.url} key={image.id} />
|
||||
))
|
||||
) : (
|
||||
<p>No images yet.</p>
|
||||
<BentoGrid className="lg:grid-rows-3">
|
||||
{latestImages.map((image) =>
|
||||
createGridCard(
|
||||
image.id,
|
||||
image.url,
|
||||
image.title ?? "",
|
||||
image.description ?? "",
|
||||
image.tags ?? [],
|
||||
),
|
||||
)}
|
||||
</div>
|
||||
</BentoGrid>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { clsx, type ClassValue } from "clsx"
|
||||
import { type ClassValue, clsx } from "clsx"
|
||||
import { twMerge } from "tailwind-merge"
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@layer base {
|
||||
:root {
|
||||
--background: 0 0% 100%;
|
||||
@@ -22,13 +23,14 @@
|
||||
--border: 240 5.9% 90%;
|
||||
--input: 240 5.9% 90%;
|
||||
--ring: 240 10% 3.9%;
|
||||
--radius: 0.5rem;
|
||||
--chart-1: 12 76% 61%;
|
||||
--chart-2: 173 58% 39%;
|
||||
--chart-3: 197 37% 24%;
|
||||
--chart-4: 43 74% 66%;
|
||||
--chart-5: 27 87% 67%;
|
||||
--radius: 0.5rem
|
||||
}
|
||||
|
||||
.dark {
|
||||
--background: 240 10% 3.9%;
|
||||
--foreground: 0 0% 98%;
|
||||
@@ -53,9 +55,10 @@
|
||||
--chart-2: 160 60% 45%;
|
||||
--chart-3: 30 80% 55%;
|
||||
--chart-4: 280 65% 60%;
|
||||
--chart-5: 340 75% 55%
|
||||
--chart-5: 340 75% 55%;
|
||||
}
|
||||
}
|
||||
|
||||
@layer base {
|
||||
* {
|
||||
@apply border-border;
|
||||
@@ -63,4 +66,4 @@
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,26 +1,29 @@
|
||||
import { type Config } from "tailwindcss";
|
||||
import type { Config } from "tailwindcss"
|
||||
|
||||
export default {
|
||||
const config = {
|
||||
darkMode: ["class"],
|
||||
content: ["./src/**/*.tsx"],
|
||||
content: [
|
||||
'./pages/**/*.{ts,tsx}',
|
||||
'./components/**/*.{ts,tsx}',
|
||||
'./app/**/*.{ts,tsx}',
|
||||
'./src/**/*.{ts,tsx}',
|
||||
],
|
||||
prefix: "",
|
||||
theme: {
|
||||
extend: {
|
||||
borderRadius: {
|
||||
lg: "var(--radius)",
|
||||
md: "calc(var(--radius) - 2px)",
|
||||
sm: "calc(var(--radius) - 4px)",
|
||||
container: {
|
||||
center: true,
|
||||
padding: "2rem",
|
||||
screens: {
|
||||
"2xl": "1400px",
|
||||
},
|
||||
},
|
||||
extend: {
|
||||
colors: {
|
||||
border: "hsl(var(--border))",
|
||||
input: "hsl(var(--input))",
|
||||
ring: "hsl(var(--ring))",
|
||||
background: "hsl(var(--background))",
|
||||
foreground: "hsl(var(--foreground))",
|
||||
card: {
|
||||
DEFAULT: "hsl(var(--card))",
|
||||
foreground: "hsl(var(--card-foreground))",
|
||||
},
|
||||
popover: {
|
||||
DEFAULT: "hsl(var(--popover))",
|
||||
foreground: "hsl(var(--popover-foreground))",
|
||||
},
|
||||
primary: {
|
||||
DEFAULT: "hsl(var(--primary))",
|
||||
foreground: "hsl(var(--primary-foreground))",
|
||||
@@ -29,6 +32,10 @@ export default {
|
||||
DEFAULT: "hsl(var(--secondary))",
|
||||
foreground: "hsl(var(--secondary-foreground))",
|
||||
},
|
||||
destructive: {
|
||||
DEFAULT: "hsl(var(--destructive))",
|
||||
foreground: "hsl(var(--destructive-foreground))",
|
||||
},
|
||||
muted: {
|
||||
DEFAULT: "hsl(var(--muted))",
|
||||
foreground: "hsl(var(--muted-foreground))",
|
||||
@@ -37,37 +44,28 @@ export default {
|
||||
DEFAULT: "hsl(var(--accent))",
|
||||
foreground: "hsl(var(--accent-foreground))",
|
||||
},
|
||||
destructive: {
|
||||
DEFAULT: "hsl(var(--destructive))",
|
||||
foreground: "hsl(var(--destructive-foreground))",
|
||||
popover: {
|
||||
DEFAULT: "hsl(var(--popover))",
|
||||
foreground: "hsl(var(--popover-foreground))",
|
||||
},
|
||||
border: "hsl(var(--border))",
|
||||
input: "hsl(var(--input))",
|
||||
ring: "hsl(var(--ring))",
|
||||
chart: {
|
||||
"1": "hsl(var(--chart-1))",
|
||||
"2": "hsl(var(--chart-2))",
|
||||
"3": "hsl(var(--chart-3))",
|
||||
"4": "hsl(var(--chart-4))",
|
||||
"5": "hsl(var(--chart-5))",
|
||||
card: {
|
||||
DEFAULT: "hsl(var(--card))",
|
||||
foreground: "hsl(var(--card-foreground))",
|
||||
},
|
||||
},
|
||||
borderRadius: {
|
||||
lg: "var(--radius)",
|
||||
md: "calc(var(--radius) - 2px)",
|
||||
sm: "calc(var(--radius) - 4px)",
|
||||
},
|
||||
keyframes: {
|
||||
"accordion-down": {
|
||||
from: {
|
||||
height: "0",
|
||||
},
|
||||
to: {
|
||||
height: "var(--radix-accordion-content-height)",
|
||||
},
|
||||
from: { height: "0" },
|
||||
to: { height: "var(--radix-accordion-content-height)" },
|
||||
},
|
||||
"accordion-up": {
|
||||
from: {
|
||||
height: "var(--radix-accordion-content-height)",
|
||||
},
|
||||
to: {
|
||||
height: "0",
|
||||
},
|
||||
from: { height: "var(--radix-accordion-content-height)" },
|
||||
to: { height: "0" },
|
||||
},
|
||||
},
|
||||
animation: {
|
||||
@@ -77,4 +75,6 @@ export default {
|
||||
},
|
||||
},
|
||||
plugins: [require("tailwindcss-animate")],
|
||||
} satisfies Config;
|
||||
} satisfies Config
|
||||
|
||||
export default config
|
||||
Reference in New Issue
Block a user