Skip to content

Commit

Permalink
feat: wc
Browse files Browse the repository at this point in the history
  • Loading branch information
PaulWeb30 committed Jan 8, 2025
1 parent aff27e7 commit 25afa79
Show file tree
Hide file tree
Showing 13 changed files with 687 additions and 60 deletions.
29 changes: 29 additions & 0 deletions .github/workflows/static-checks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Static Checks

on:
push:
branches:
- main
- staging
pull_request: {}
workflow_dispatch: {}

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '20'
- uses: actions/cache@v3
id: cache
with:
path: '**/node_modules'
key: ${{ runner.os }}-npm-${{ hashFiles('**/yarn.lock') }}
restore-keys: ${{ runner.os }}-npm-
- name: Install project dependencies
if: steps.cache.outputs.cache-hit != 'true'
run: yarn install --frozen-lockfile
- name: Testing
run: yarn tsc --noEmit && yarn lint && yarn build
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
"preview": "vite preview"
},
"dependencies": {
"@radix-ui/react-dialog": "^1.1.4",
"@radix-ui/react-popover": "^1.1.4",
"@radix-ui/react-slot": "^1.1.1",
"@solana/wallet-adapter-react": "^0.15.35",
"@solana/wallet-adapter-wallets": "^0.19.32",
"@solana/web3.js": "^1.98.0",
Expand All @@ -23,7 +26,8 @@
"react-router": "^7.1.1",
"tailwind-merge": "^2.6.0",
"tailwindcss-animate": "^1.0.7",
"zod": "^3.24.1"
"zod": "^3.24.1",
"zustand": "^5.0.3"
},
"devDependencies": {
"@eslint/js": "^9.17.0",
Expand Down
5 changes: 4 additions & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { RouterProvider } from '@/providers/router-provider';
import { SolanaProvider } from '@/providers/solana-provider';
import { QueryProvider } from '@/providers/query-provider';

function App() {
return (
<SolanaProvider>
<RouterProvider />
<QueryProvider>
<RouterProvider />
</QueryProvider>
</SolanaProvider>
);
}
Expand Down
138 changes: 138 additions & 0 deletions src/components/common/Header/connect-wallet-button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import { useCallback, useEffect, useRef, useState } from 'react';
import { WalletReadyState } from '@solana/wallet-adapter-base';
import { useWallet } from '@solana/wallet-adapter-react';
import { PhantomWalletName, SolflareWalletName } from '@solana/wallet-adapter-wallets';

import { SvgComponent } from './progress-bar';
import { Button } from '@/components/ui/button';
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui/dialog';
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
import { shortenAddress } from '@/lib/utils';
import { useWalletModalStore } from '@/store/wallet-modal';

export const ConnectWalletButton = () => {
const { isOpen, setIsOpen } = useWalletModalStore();

const { select, wallets, publicKey, disconnect, connecting, wallet } = useWallet();

const filteredWallets = wallets.filter(
(wallet) => wallet.adapter.name == SolflareWalletName || wallet.adapter.name == PhantomWalletName,
);

const onOpenChange = useCallback(
(open: boolean) => {
setIsOpen(open);
},
[setIsOpen],
);

const buttonRef = useRef<HTMLButtonElement>(null);

const [popoverWidth, setPopoverWidth] = useState<number>();

useEffect(() => {
if (buttonRef.current?.clientWidth) {
setPopoverWidth(buttonRef.current.clientWidth);
}
}, [buttonRef.current?.clientWidth]);

useEffect(() => {
if (publicKey) {
setIsOpen(false);
}
}, [publicKey]);

if (publicKey) {
return (
<Popover>
<PopoverTrigger ref={buttonRef} asChild>
<Button
variant="outline"
ref={buttonRef}
className="h-fit w-full px-[26px] py-[15px] text-[20px] uppercase leading-[24px]"
>
{shortenAddress(publicKey.toBase58())}
</Button>
</PopoverTrigger>
<PopoverContent style={{ width: popoverWidth }} className="border-0">
<Button
onClick={async () => {
await disconnect();
setIsOpen(false);
}}
className="h-fit w-full bg-[#d1f93d] px-[26px] py-[15px] text-[20px] uppercase leading-[24px]"
>
LOG OUT
</Button>
</PopoverContent>
</Popover>
);
}

return (
<Dialog open={isOpen} onOpenChange={onOpenChange}>
<DialogTrigger asChild>
<Button
className="h-fit w-full px-[26px] py-[15px] text-[20px] uppercase leading-[24px]"
variant="outline"
onClick={() => setIsOpen(true)}
>
Connect Wallet
</Button>
</DialogTrigger>
<DialogContent>
{!!wallet && connecting ? (
<div className="flex flex-col items-center justify-center gap-[30px]">
<img
src={wallet.adapter.icon}
alt={wallet.adapter.name}
className="h-[84px] w-[84px]"
height={84}
width={84}
/>
<div className="flex flex-col items-center justify-center gap-[15px] text-center text-[20px] leading-[30px]">
<div>Awaiting Connect Confirmation</div>
<SvgComponent />
</div>
</div>
) : (
<>
<DialogHeader>
<DialogTitle>
<p>Connect Wallet</p>
</DialogTitle>
</DialogHeader>
<div className="grid grid-cols-2 gap-[20px]">
{filteredWallets.map((wallet) => (
<Button
key={wallet.adapter.name}
className="bg-customYellow flex h-full w-full flex-col gap-[15px] p-[15px] text-[18px] leading-[27px]"
onClick={() => {
const selectedWallet = filteredWallets.find((w) => w.adapter.name === wallet.adapter.name);

if (selectedWallet) {
if (selectedWallet.readyState != WalletReadyState.Installed) {
window.open(selectedWallet.adapter.url, '_blank');
}

select(selectedWallet.adapter.name);
}
}}
>
<img
src={wallet.adapter.icon}
alt={wallet.adapter.name}
className="h-[60px] w-[60px]"
height={60}
width={60}
/>
{wallet.adapter.name}
</Button>
))}
</div>
</>
)}
</DialogContent>
</Dialog>
);
};
44 changes: 44 additions & 0 deletions src/components/common/Header/progress-bar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
const RECT_COUNT = 26;

export const SvgComponent = () => {
return (
<>
<svg xmlns="http://www.w3.org/2000/svg" width={267} height={20} fill="none">
<path fill="#2F130F" d="M.5 6h1v8h-1zM1.5 3h1v14h-1z" />
<rect width={261} height={19} x={3} y={0.5} stroke="#2F130F" rx={1.5} />

{new Array(RECT_COUNT).fill(null).map((_, idx) => (
<Rectangle key={idx} x={10 * idx + 4.5} animateId={idx} />
))}

<path fill="#2F130F" d="M264.5 3h1v14h-1zM265.5 6h1v8h-1z" />
</svg>
</>
);
};

const Rectangle = ({ animateId, x }: { animateId: number; x: number }) => {
const beginTime = animateId === 0 ? `0s;rectRepeat.end` : `rect${animateId - 1}.end`;

return (
<rect width={8} height={16} y={2} x={x} fill="#2F130F" rx={1} opacity={0.1}>
<animate
id={`rect${animateId}`}
attributeName="opacity"
values="0.5;1"
begin={beginTime}
dur="0.3s"
fill="freeze"
/>
<animate
id="rectRepeat"
attributeName="opacity"
from="1"
to="0.1"
dur="0.0001s"
begin={`rect${RECT_COUNT - 1}.end`}
fill="freeze"
/>
</rect>
);
};
56 changes: 0 additions & 56 deletions src/components/connect-wallet-button.tsx

This file was deleted.

47 changes: 47 additions & 0 deletions src/components/ui/button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import * as React from 'react';
import { Slot } from '@radix-ui/react-slot';
import { cva, type VariantProps } from 'class-variance-authority';

import { cn } from '@/lib/utils';

const buttonVariants = cva(
'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',
{
variants: {
variant: {
default: 'bg-primary text-primary-foreground hover:bg-primary/90',
destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',
outline: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',
secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
ghost: 'hover:bg-accent hover:text-accent-foreground',
link: 'text-primary underline-offset-4 hover:underline',
},
size: {
default: 'h-10 px-4 py-2',
sm: 'h-9 rounded-md px-3',
lg: 'h-11 rounded-md px-8',
icon: 'h-10 w-10',
},
},
defaultVariants: {
variant: 'default',
size: 'default',
},
},
);

export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean;
}

const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : 'button';
return <Comp className={cn(buttonVariants({ variant, size, className }))} ref={ref} {...props} />;
},
);
Button.displayName = 'Button';

export { Button, buttonVariants };
Loading

0 comments on commit 25afa79

Please sign in to comment.