Merge pull request #7 from Ayush272002/wallet_adapter

fix ui errors + add metamask hook
This commit is contained in:
2024-10-26 10:47:02 +01:00
committed by GitHub
10 changed files with 13748 additions and 83 deletions

View File

@@ -1,4 +1,3 @@
import EventDescription from '@/components/custom/EventDescription';
import Home from './Home';
export default function Page() {

View File

@@ -4,20 +4,12 @@ import { Button } from '@/components/ui/button';
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select';
import { motion } from 'framer-motion';
// Dark theme and animation setup

View File

@@ -0,0 +1,9 @@
import React from 'react'
const WalletAdapter = () => {
return (
<div>WalletAdapter</div>
)
}
export default WalletAdapter

View File

@@ -10,7 +10,6 @@ import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { Separator } from '@/components/ui/separator';
import ImageCarousel from './ImageCarousel';
import BuyTicket from './BuyTicket';
import TicketButton from './TicketButton';
const EventDescription = () => {

View File

@@ -20,7 +20,9 @@ const NumberPicker: React.FC<NumberPickerProps> = ({
if (count < max) {
const newCount = count + 1;
setCount(newCount);
onChange && onChange(newCount);
if (onChange) {
onChange(newCount);
}
}
};
@@ -28,7 +30,9 @@ const NumberPicker: React.FC<NumberPickerProps> = ({
if (count > min) {
const newCount = count - 1;
setCount(newCount);
onChange && onChange(newCount);
if (onChange) {
onChange(newCount);
}
}
};

View File

@@ -1,21 +1,46 @@
'use client';
import React, { useEffect, useState } from 'react';
import { ethers } from 'ethers';
import { useSDK, MetaMaskProvider } from '@metamask/sdk-react';
import { Button } from '@/components/ui/button';
import {
Popover,
PopoverContent,
PopoverTrigger,
} from '@/components/ui/popover';
declare global {
interface Window {
ethereum: ethers.providers.ExternalProvider;
}
function WalletIcon(props: React.SVGProps<SVGSVGElement>) {
return (
<svg
{...props}
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
<path d="M21 12V7H5a2 2 0 0 1 0-4h14v4" />
<path d="M3 5v14a2 2 0 0 0 2 2h16v-5" />
<path d="M18 12a2 2 0 0 0 0 4h4v-4Z" />
</svg>
);
}
const MetaMask = () => {
function formatAddress(address: string | undefined): string {
if (!address) return '';
return `${address.slice(0, 6)}...${address.slice(-4)}`;
}
function MetaMaskConnect() {
const { sdk, connected, connecting, account } = useSDK();
const [metaMaskInstalled, setMetaMaskInstalled] = useState(false);
const [account, setAccount] = useState<string | null>(null);
const isMetaMaskInstalled = () =>
typeof window !== 'undefined' &&
typeof (window as { ethereum?: unknown }).ethereum !== 'undefined';
typeof window !== 'undefined' && typeof window.ethereum !== 'undefined';
useEffect(() => {
if (isMetaMaskInstalled()) {
@@ -23,54 +48,70 @@ const MetaMask = () => {
}
}, []);
const handleConnectWallet = async () => {
if (window.ethereum && window.ethereum.request) {
try {
// Request account access
const accounts = await window.ethereum.request({
method: 'eth_requestAccounts',
});
setAccount(accounts[0]); // Set the first account
} catch (error) {
console.error('Error connecting to MetaMask:', error);
}
} else {
alert(
'MetaMask is not installed. Please install MetaMask and try again.'
);
const connect = async () => {
try {
await sdk?.connect();
} catch (err) {
console.warn(`No accounts found`, err);
}
};
const disconnect = () => {
if (sdk) {
sdk.terminate();
}
};
if (!metaMaskInstalled) {
return (
<Button
onClick={() =>
window.open('https://metamask.io/download.html', '_blank')
}
className="bg-gradient-to-r from-blue-500 to-indigo-700"
>
Install MetaMask
</Button>
);
}
return (
<div className="">
{metaMaskInstalled ? (
<div>
{account ? (
<p className="text-green-500">
Connected: 0x{account.slice(2, 5)}...{account.slice(-3)}
</p>
) : (
<div className="relative">
{connected ? (
<Popover>
<PopoverTrigger asChild>
<Button>{formatAddress(account)}</Button>
</PopoverTrigger>
<PopoverContent className="w-44">
<button
onClick={handleConnectWallet}
className="bg-gradient-to-r from-blue-500 to-indigo-700 text-white px-4 py-1 rounded-full transform transition-transform duration-300 hover:scale-105 shadow-lg hover:shadow-2xl"
onClick={disconnect}
className="w-full px-4 py-2 text-left text-destructive hover:bg-muted"
>
Connect Wallet
Disconnect
</button>
)}
</div>
</PopoverContent>
</Popover>
) : (
<button
// Install Metamask extension if not already installed
onClick={() =>
window.open('https://metamask.io/download.html', '_blank')
}
className="bg-gradient-to-r from-blue-500 to-indigo-700 text-white px-4 py-1 rounded-full transform transition-transform duration-300 hover:scale-105 shadow-lg hover:shadow-2xl"
>
Install MetaMask to connect wallet
</button>
<Button disabled={connecting} onClick={connect}>
<WalletIcon className="mr-2 h-4 w-4" /> Connect Wallet
</Button>
)}
</div>
);
};
}
export default MetaMask;
export default function MetaMaskConnectWrapper() {
return (
<MetaMaskProvider
debug={false}
sdkOptions={{
dappMetadata: {
name: 'My dApp',
url: typeof window !== 'undefined' ? window.location.href : '',
},
}}
>
<MetaMaskConnect />
</MetaMaskProvider>
);
}

View File

@@ -1,25 +1,22 @@
import * as React from 'react';
import { cn } from '@/lib/utils';
export interface InputProps
extends React.InputHTMLAttributes<HTMLInputElement> {}
const Input = React.forwardRef<HTMLInputElement, InputProps>(
({ className, type, ...props }, ref) => {
return (
<input
type={type}
className={cn(
'flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50',
className
)}
ref={ref}
{...props}
/>
);
}
);
const Input = React.forwardRef<
HTMLInputElement,
React.InputHTMLAttributes<HTMLInputElement>
>(({ className, type, ...props }, ref) => {
return (
<input
type={type}
className={cn(
'flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50',
className
)}
ref={ref}
{...props}
/>
);
});
Input.displayName = 'Input';
export { Input };

33
components/ui/popover.tsx Normal file
View File

@@ -0,0 +1,33 @@
'use client';
import * as React from 'react';
import * as PopoverPrimitive from '@radix-ui/react-popover';
import { cn } from '@/lib/utils';
const Popover = PopoverPrimitive.Root;
const PopoverTrigger = PopoverPrimitive.Trigger;
const PopoverAnchor = PopoverPrimitive.Anchor;
const PopoverContent = React.forwardRef<
React.ElementRef<typeof PopoverPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>
>(({ className, align = 'center', sideOffset = 4, ...props }, ref) => (
<PopoverPrimitive.Portal>
<PopoverPrimitive.Content
ref={ref}
align={align}
sideOffset={sideOffset}
className={cn(
'z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
className
)}
{...props}
/>
</PopoverPrimitive.Portal>
));
PopoverContent.displayName = PopoverPrimitive.Content.displayName;
export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor };

13593
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -13,17 +13,15 @@
"@metamask/sdk-react": "^0.30.0",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-label": "^2.1.0",
"@radix-ui/react-popover": "^1.1.2",
"@radix-ui/react-select": "^2.1.2",
"@radix-ui/react-separator": "^1.1.0",
"@radix-ui/react-slot": "^1.1.0",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"embla-carousel-react": "^8.3.0",
"framer-motion": "^11.11.10",
"ethers": "^5.7.2",
"framer-motion": "^11.11.10",
"lucide-react": "^0.446.0",
"next": "14.2.13",
"react": "^18.3.1",