mirror of
https://github.com/0xShay/ticketchain.git
synced 2026-01-11 13:13:25 +00:00
update
This commit is contained in:
7
components/WalletAdapter.tsx
Normal file
7
components/WalletAdapter.tsx
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
const WalletAdapter = () => {
|
||||||
|
return <div>WalletAdapter</div>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default WalletAdapter;
|
||||||
@@ -10,7 +10,6 @@ import { Button } from '@/components/ui/button';
|
|||||||
import { Badge } from '@/components/ui/badge';
|
import { Badge } from '@/components/ui/badge';
|
||||||
import { Separator } from '@/components/ui/separator';
|
import { Separator } from '@/components/ui/separator';
|
||||||
import ImageCarousel from './ImageCarousel';
|
import ImageCarousel from './ImageCarousel';
|
||||||
// import BuyTicket from './BuyTicket';
|
|
||||||
import TicketButton from './TicketButton';
|
import TicketButton from './TicketButton';
|
||||||
|
|
||||||
const EventDescription = () => {
|
const EventDescription = () => {
|
||||||
|
|||||||
@@ -1,21 +1,46 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import React, { useEffect, useState } from 'react';
|
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 {
|
function WalletIcon(props: React.SVGProps<SVGSVGElement>) {
|
||||||
interface Window {
|
return (
|
||||||
ethereum: ethers.providers.ExternalProvider;
|
<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 [metaMaskInstalled, setMetaMaskInstalled] = useState(false);
|
||||||
const [account, setAccount] = useState<string | null>(null);
|
|
||||||
|
|
||||||
const isMetaMaskInstalled = () =>
|
const isMetaMaskInstalled = () =>
|
||||||
typeof window !== 'undefined' &&
|
typeof window !== 'undefined' && typeof window.ethereum !== 'undefined';
|
||||||
typeof (window as { ethereum?: unknown }).ethereum !== 'undefined';
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isMetaMaskInstalled()) {
|
if (isMetaMaskInstalled()) {
|
||||||
@@ -23,54 +48,70 @@ const MetaMask = () => {
|
|||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleConnectWallet = async () => {
|
const connect = async () => {
|
||||||
if (window.ethereum && window.ethereum.request) {
|
try {
|
||||||
try {
|
await sdk?.connect();
|
||||||
// Request account access
|
} catch (err) {
|
||||||
const accounts = await window.ethereum.request({
|
console.warn(`No accounts found`, err);
|
||||||
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 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 (
|
return (
|
||||||
<div className="">
|
<div className="relative">
|
||||||
{metaMaskInstalled ? (
|
{connected ? (
|
||||||
<div>
|
<Popover>
|
||||||
{account ? (
|
<PopoverTrigger asChild>
|
||||||
<p className="text-green-500">
|
<Button>{formatAddress(account)}</Button>
|
||||||
Connected: 0x{account.slice(2, 5)}...{account.slice(-3)}
|
</PopoverTrigger>
|
||||||
</p>
|
<PopoverContent className="w-44">
|
||||||
) : (
|
|
||||||
<button
|
<button
|
||||||
onClick={handleConnectWallet}
|
onClick={disconnect}
|
||||||
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"
|
className="w-full px-4 py-2 text-left text-destructive hover:bg-muted"
|
||||||
>
|
>
|
||||||
Connect Wallet
|
Disconnect
|
||||||
</button>
|
</button>
|
||||||
)}
|
</PopoverContent>
|
||||||
</div>
|
</Popover>
|
||||||
) : (
|
) : (
|
||||||
<button
|
<Button disabled={connecting} onClick={connect}>
|
||||||
// Install Metamask extension if not already installed
|
<WalletIcon className="mr-2 h-4 w-4" /> Connect Wallet
|
||||||
onClick={() =>
|
</Button>
|
||||||
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>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</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>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,25 +1,22 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
|
|
||||||
export interface InputProps
|
const Input = React.forwardRef<
|
||||||
extends React.InputHTMLAttributes<HTMLInputElement> {}
|
HTMLInputElement,
|
||||||
|
React.InputHTMLAttributes<HTMLInputElement>
|
||||||
const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
>(({ className, type, ...props }, ref) => {
|
||||||
({ className, type, ...props }, ref) => {
|
return (
|
||||||
return (
|
<input
|
||||||
<input
|
type={type}
|
||||||
type={type}
|
className={cn(
|
||||||
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',
|
||||||
'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
|
||||||
className
|
)}
|
||||||
)}
|
ref={ref}
|
||||||
ref={ref}
|
{...props}
|
||||||
{...props}
|
/>
|
||||||
/>
|
);
|
||||||
);
|
});
|
||||||
}
|
|
||||||
);
|
|
||||||
Input.displayName = 'Input';
|
Input.displayName = 'Input';
|
||||||
|
|
||||||
export { Input };
|
export { Input };
|
||||||
|
|||||||
33
components/ui/popover.tsx
Normal file
33
components/ui/popover.tsx
Normal 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 };
|
||||||
16840
package-lock.json
generated
Normal file
16840
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -13,17 +13,15 @@
|
|||||||
"@metamask/sdk-react": "^0.30.0",
|
"@metamask/sdk-react": "^0.30.0",
|
||||||
"@radix-ui/react-icons": "^1.3.0",
|
"@radix-ui/react-icons": "^1.3.0",
|
||||||
"@radix-ui/react-label": "^2.1.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-select": "^2.1.2",
|
||||||
"@radix-ui/react-separator": "^1.1.0",
|
"@radix-ui/react-separator": "^1.1.0",
|
||||||
"@radix-ui/react-slot": "^1.1.0",
|
"@radix-ui/react-slot": "^1.1.0",
|
||||||
"class-variance-authority": "^0.7.0",
|
"class-variance-authority": "^0.7.0",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
|
|
||||||
"embla-carousel-react": "^8.3.0",
|
"embla-carousel-react": "^8.3.0",
|
||||||
"framer-motion": "^11.11.10",
|
|
||||||
|
|
||||||
"ethers": "^5.7.2",
|
"ethers": "^5.7.2",
|
||||||
|
"framer-motion": "^11.11.10",
|
||||||
"lucide-react": "^0.446.0",
|
"lucide-react": "^0.446.0",
|
||||||
"next": "14.2.13",
|
"next": "14.2.13",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
|
|||||||
Reference in New Issue
Block a user