From 1785f66031f312d66d7a80dd113988a46d31061c Mon Sep 17 00:00:00 2001 From: 0xBunzy Date: Thu, 14 Nov 2024 18:12:16 -0800 Subject: [PATCH] added modal --- src/bin/script.ts | 49 ++++ templates/next-app/package.json | 9 +- templates/next-app/src/app/globals.css | 76 ++++++ templates/next-app/src/app/layout.tsx | 12 +- templates/next-app/src/app/page.tsx | 30 ++- .../next-app/src/components/ConnectWallet.tsx | 235 ++++++++++++++++-- .../next-app/src/components/DefaultLayout.tsx | 14 +- .../next-app/src/components/ThemeToggle.tsx | 40 +++ templates/next-app/tailwind.config.ts | 47 +++- 9 files changed, 469 insertions(+), 43 deletions(-) create mode 100644 templates/next-app/src/app/globals.css create mode 100644 templates/next-app/src/components/ThemeToggle.tsx diff --git a/src/bin/script.ts b/src/bin/script.ts index 576a227..2fec9c8 100644 --- a/src/bin/script.ts +++ b/src/bin/script.ts @@ -203,6 +203,7 @@ async function init() { "src/app/layout.tsx", "src/components/DefaultLayout.tsx", "src/components/ConnectWallet.tsx", + "src/components/ThemeToggle.tsx", ]; for (const file of filesToCopy) { @@ -243,6 +244,24 @@ async function init() { throw error; } + console.log("\nInstalling next-themes..."); + await executeCommand( + "npm", + [ + "install", + "next-themes", + "--save", + "--no-fund", + "--no-audit", + "--loglevel=error", + ], + { + cwd: root, + }, + true + ); + console.log(`${pc.green("✓")} next-themes installed!`); + console.log("\nInitializing Shadcn..."); try { await executeCommand( @@ -274,6 +293,36 @@ async function init() { true ); console.log(`${pc.green("✓")} Button component installed!`); + + // Add the dropdown-menu component + console.log("\nAdding dropdown-menu component..."); + await executeCommand( + "npx", + ["shadcn@latest", "add", "dropdown-menu"], + { + cwd: root, + env: { + SKIP_INSTRUCTIONS: "1", + }, + }, + true + ); + console.log(`${pc.green("✓")} Dropdown menu component installed!`); + + // Add the dialog component + console.log("\nAdding dialog component..."); + await executeCommand( + "npx", + ["shadcn@latest", "add", "dialog"], + { + cwd: root, + env: { + SKIP_INSTRUCTIONS: "1", + }, + }, + true + ); + console.log(`${pc.green("✓")} Dialog component installed!`); } catch (error) { console.error("Failed to initialize shadcn/ui:", error); throw error; diff --git a/templates/next-app/package.json b/templates/next-app/package.json index 7d619a0..9f3ff7c 100644 --- a/templates/next-app/package.json +++ b/templates/next-app/package.json @@ -12,7 +12,14 @@ "@omnisat/lasereyes": "latest", "next": "14.1.0", "react": "^18", - "react-dom": "^18" + "react-dom": "^18", + "@radix-ui/react-dialog": "^1.0.5", + "@radix-ui/react-dropdown-menu": "^2.0.6", + "class-variance-authority": "^0.7.0", + "clsx": "^2.1.0", + "lucide-react": "^0.344.0", + "tailwind-merge": "^2.2.1", + "tailwindcss-animate": "^1.0.7" }, "devDependencies": { "@types/node": "^20", diff --git a/templates/next-app/src/app/globals.css b/templates/next-app/src/app/globals.css new file mode 100644 index 0000000..8abdb15 --- /dev/null +++ b/templates/next-app/src/app/globals.css @@ -0,0 +1,76 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +@layer base { + :root { + --background: 0 0% 100%; + --foreground: 222.2 84% 4.9%; + + --card: 0 0% 100%; + --card-foreground: 222.2 84% 4.9%; + + --popover: 0 0% 100%; + --popover-foreground: 222.2 84% 4.9%; + + --primary: 222.2 47.4% 11.2%; + --primary-foreground: 210 40% 98%; + + --secondary: 210 40% 96.1%; + --secondary-foreground: 222.2 47.4% 11.2%; + + --muted: 210 40% 96.1%; + --muted-foreground: 215.4 16.3% 46.9%; + + --accent: 210 40% 96.1%; + --accent-foreground: 222.2 47.4% 11.2%; + + --destructive: 0 84.2% 60.2%; + --destructive-foreground: 210 40% 98%; + + --border: 214.3 31.8% 91.4%; + --input: 214.3 31.8% 91.4%; + --ring: 222.2 84% 4.9%; + + --radius: 0.5rem; + } + + .dark { + --background: 222.2 84% 4.9%; + --foreground: 210 40% 98%; + + --card: 222.2 84% 4.9%; + --card-foreground: 210 40% 98%; + + --popover: 222.2 84% 4.9%; + --popover-foreground: 210 40% 98%; + + --primary: 210 40% 98%; + --primary-foreground: 222.2 47.4% 11.2%; + + --secondary: 217.2 32.6% 17.5%; + --secondary-foreground: 210 40% 98%; + + --muted: 217.2 32.6% 17.5%; + --muted-foreground: 215 20.2% 65.1%; + + --accent: 217.2 32.6% 17.5%; + --accent-foreground: 210 40% 98%; + + --destructive: 0 62.8% 30.6%; + --destructive-foreground: 210 40% 98%; + + --border: 217.2 32.6% 17.5%; + --input: 217.2 32.6% 17.5%; + --ring: 212.7 26.8% 83.9%; + } +} + +@layer base { + * { + @apply border-border; + } + body { + @apply bg-background text-foreground; + } +} diff --git a/templates/next-app/src/app/layout.tsx b/templates/next-app/src/app/layout.tsx index c4235a4..c09d8db 100644 --- a/templates/next-app/src/app/layout.tsx +++ b/templates/next-app/src/app/layout.tsx @@ -1,22 +1,16 @@ -import type { Metadata } from "next"; import { Inter } from "next/font/google"; import "./globals.css"; import DefaultLayout from "@/components/DefaultLayout"; const inter = Inter({ subsets: ["latin"] }); -export const metadata: Metadata = { - title: "Create Next App", - description: "Generated by create next app", -}; - export default function RootLayout({ children, -}: Readonly<{ +}: { children: React.ReactNode; -}>) { +}) { return ( - + {children} diff --git a/templates/next-app/src/app/page.tsx b/templates/next-app/src/app/page.tsx index 2a1eeec..e7039fb 100644 --- a/templates/next-app/src/app/page.tsx +++ b/templates/next-app/src/app/page.tsx @@ -1,23 +1,35 @@ "use client"; -import { useLaserEyes } from "@omnisat/lasereyes"; -import { ConnectWallet } from "@/components/ConnectWallet"; +import { useLaserEyes, LaserEyesLogo } from "@omnisat/lasereyes"; +import ConnectWallet from "@/components/ConnectWallet"; +import { ThemeToggle } from "@/components/ThemeToggle"; export default function Home() { const { address } = useLaserEyes(); return ( -
-

- Welcome to LaserEyes Template -

-
+
+
+ +
+
+ +

+ {address + ? "Welcome To Create LaserEyes." + : "Welcome To The New Way Of Building."} +

+
+
{address && (
-

Connected Address: {address}

+

+ Connected Address:{" "} + {address} +

)}
); -} \ No newline at end of file +} diff --git a/templates/next-app/src/components/ConnectWallet.tsx b/templates/next-app/src/components/ConnectWallet.tsx index 17d41bf..e70d32e 100644 --- a/templates/next-app/src/components/ConnectWallet.tsx +++ b/templates/next-app/src/components/ConnectWallet.tsx @@ -1,30 +1,227 @@ -/** @format */ - "use client"; - -import { useLaserEyes, UNISAT } from "@omnisat/lasereyes"; +import { useState } from "react"; import { Button } from "@/components/ui/button"; +import { ChevronRight } from "lucide-react"; +import Image from "next/image"; -export function ConnectWallet() { - const { connect, disconnect, connected, hasUnisat } = useLaserEyes(); +import { + LEATHER, + MAGIC_EDEN, + OKX, + OYL, + ORANGE, + PHANTOM, + UNISAT, + useLaserEyes, + WalletIcon, + WIZZ, + XVERSE, + SUPPORTED_WALLETS, + LaserEyesLogo, +} from "@omnisat/lasereyes"; +import { + Dialog, + DialogContent, + DialogDescription, + DialogHeader, + DialogTitle, + DialogTrigger, +} from "@/components/ui/dialog"; +import { cn } from "@/lib/utils"; - const handleConnect = async () => { - if (!hasUnisat) { - console.error("Please install Unisat wallet"); - return; +export default function ConnectWallet({ className }: { className?: string }) { + const { + connect, + disconnect, + isConnecting, + address, + provider, + hasUnisat, + hasXverse, + hasOyl, + hasMagicEden, + hasOkx, + hasLeather, + hasPhantom, + hasWizz, + hasOrange, + hasOpNet, + } = useLaserEyes(); + const [isOpen, setIsOpen] = useState(false); + + const hasWallet = { + unisat: hasUnisat, + xverse: hasXverse, + oyl: hasOyl, + [MAGIC_EDEN]: hasMagicEden, + okx: hasOkx, + op_net: hasOpNet, + leather: hasLeather, + phantom: hasPhantom, + wizz: hasWizz, + orange: hasOrange, + }; + + const handleConnect = async ( + walletName: + | typeof UNISAT + | typeof MAGIC_EDEN + | typeof OYL + | typeof ORANGE + | typeof PHANTOM + | typeof LEATHER + | typeof XVERSE + | typeof WIZZ + | typeof OKX + ) => { + if (provider === walletName) { + await disconnect(); + } else { + setIsOpen(false); + await connect(walletName as never); } - await connect(UNISAT); }; return ( -
- + ) : ( + + + + )} + - {connected ? "Disconnect" : "Connect Wallet"} - -
+ + + Connect Wallet + + + +
+ + {Object.values(SUPPORTED_WALLETS).map((wallet) => { + const isConnected = provider === wallet; + const isMissingWallet = !hasWallet[wallet.name]; + return ( + + ); + })} + +
+ +
+
+ + Powered by LaserEyes + +
+
+ + + +
+
+ + ); } diff --git a/templates/next-app/src/components/DefaultLayout.tsx b/templates/next-app/src/components/DefaultLayout.tsx index 3286c78..c43a5ed 100644 --- a/templates/next-app/src/components/DefaultLayout.tsx +++ b/templates/next-app/src/components/DefaultLayout.tsx @@ -1,10 +1,18 @@ -/** @format */ - "use client"; import React, { ReactNode } from "react"; import { LaserEyesProvider } from "@omnisat/lasereyes"; +import { ThemeProvider as NextThemesProvider } from "next-themes"; export default function DefaultLayout({ children }: { children: ReactNode }) { - return {children}; + return ( + + {children} + + ); } diff --git a/templates/next-app/src/components/ThemeToggle.tsx b/templates/next-app/src/components/ThemeToggle.tsx new file mode 100644 index 0000000..8f39542 --- /dev/null +++ b/templates/next-app/src/components/ThemeToggle.tsx @@ -0,0 +1,40 @@ +"use client"; + +import * as React from "react"; +import { Moon, Sun } from "lucide-react"; +import { useTheme } from "next-themes"; + +import { Button } from "@/components/ui/button"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; + +export function ThemeToggle() { + const { setTheme } = useTheme(); + + return ( + + + + + + setTheme("light")}> + Light + + setTheme("dark")}> + Dark + + setTheme("system")}> + System + + + + ); +} diff --git a/templates/next-app/tailwind.config.ts b/templates/next-app/tailwind.config.ts index 35ba2d0..479fdea 100644 --- a/templates/next-app/tailwind.config.ts +++ b/templates/next-app/tailwind.config.ts @@ -1,14 +1,57 @@ import type { Config } from "tailwindcss"; const config: Config = { + darkMode: ["class"], content: [ "./pages/**/*.{js,ts,jsx,tsx,mdx}", "./components/**/*.{js,ts,jsx,tsx,mdx}", "./app/**/*.{js,ts,jsx,tsx,mdx}", ], theme: { - extend: {}, + extend: { + colors: { + border: "hsl(var(--border))", + input: "hsl(var(--input))", + ring: "hsl(var(--ring))", + background: "hsl(var(--background))", + foreground: "hsl(var(--foreground))", + primary: { + DEFAULT: "hsl(var(--primary))", + foreground: "hsl(var(--primary-foreground))", + }, + secondary: { + 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))", + }, + accent: { + DEFAULT: "hsl(var(--accent))", + foreground: "hsl(var(--accent-foreground))", + }, + popover: { + DEFAULT: "hsl(var(--popover))", + foreground: "hsl(var(--popover-foreground))", + }, + card: { + DEFAULT: "hsl(var(--card))", + foreground: "hsl(var(--card-foreground))", + }, + }, + borderRadius: { + lg: "var(--radius)", + md: "calc(var(--radius) - 2px)", + sm: "calc(var(--radius) - 4px)", + }, + }, }, - plugins: [], + plugins: [require("tailwindcss-animate")], }; + export default config;