Skip to content

Commit

Permalink
Merge pull request #1 from RedDuck-Software/feat/game-page
Browse files Browse the repository at this point in the history
feat: random function & min layout
  • Loading branch information
NikiTaysRD authored Jan 9, 2025
2 parents 29f54bc + 948620d commit 838fa5c
Show file tree
Hide file tree
Showing 23 changed files with 754 additions and 168 deletions.
Binary file modified .yarn/install-state.gz
Binary file not shown.
9 changes: 9 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,18 @@ export default tseslint.config(
...react.configs['jsx-runtime'].rules,
'prettier/prettier': ['error'],
'react/prop-types': [2, { ignore: ['className'] }],
'@typescript-eslint/no-misused-promises': [
2,
{
checksVoidReturn: {
attributes: false,
},
},
],
'@typescript-eslint/unbound-method': 'off',
'@typescript-eslint/no-unsafe-member-access': 'off',
'@typescript-eslint/no-unsafe-call': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off',
},
},
);
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"preview": "vite preview"
},
"dependencies": {
"@hookform/resolvers": "^3.10.0",
"@radix-ui/react-dialog": "^1.1.4",
"@radix-ui/react-popover": "^1.1.4",
"@radix-ui/react-slot": "^1.1.1",
Expand All @@ -24,10 +25,12 @@
"lucide-react": "^0.469.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-hook-form": "^7.54.2",
"react-router": "^7.1.1",
"react-toastify": "^11.0.2",
"tailwind-merge": "^2.6.0",
"tailwindcss-animate": "^1.0.7",
"viem": "^2.22.4",
"zod": "^3.24.1",
"zustand": "^5.0.3"
},
Expand Down
8 changes: 6 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { Suspense } from 'react';
import { ToastContainer } from 'react-toastify';

import { Loader } from '@/components/common/Loader';
import { QueryProvider } from '@/providers/query-provider';
import { RouterProvider } from '@/providers/router-provider';
import { SolanaProvider } from '@/providers/solana-provider';
Expand All @@ -8,8 +10,10 @@ function App() {
return (
<SolanaProvider>
<QueryProvider>
<RouterProvider />
<ToastContainer position="bottom-left" />
<Suspense fallback={<Loader />}>
<RouterProvider />
<ToastContainer position="bottom-left" />
</Suspense>
</QueryProvider>
</SolanaProvider>
);
Expand Down
2 changes: 1 addition & 1 deletion src/components/common/Header/connect-wallet-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export const ConnectWalletButton = () => {
<PopoverContent style={{ width: popoverWidth }} className="border-0">
<Button
onClick={() => void handleDisconnect()}
className="h-fit w-full bg-[#d1f93d] px-[26px] py-[15px] text-[20px] uppercase leading-[24px]"
className="h-fit w-full bg-blue-600 px-[26px] py-[15px] text-[20px] uppercase leading-[24px]"
>
LOG OUT
</Button>
Expand Down
7 changes: 7 additions & 0 deletions src/components/common/Loader/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const Loader = () => {
return (
<div>
<h1>Loading...</h1>
</div>
);
};
2 changes: 1 addition & 1 deletion src/components/ui/dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const DialogContent = React.forwardRef<
<DialogPrimitive.Content
ref={ref}
className={cn(
'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-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 sm:rounded-lg',
'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-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-blue-300 p-6 shadow-lg duration-200 sm:rounded-lg',
className,
)}
{...props}
Expand Down
95 changes: 95 additions & 0 deletions src/components/ui/input.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { Slot } from '@radix-ui/react-slot';
import { cva, type VariantProps } from 'class-variance-authority';
import * as React from 'react';
import { ReactNode } from 'react';

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

const inputVariants = cva(
'w-full bg-transparent py-2 md:py-3 pl-3 md:pl-4 pr-1 text-xs font-[600] leading-[30px] text-[#FFFFFF] sm:text-[20px] focus:outline-none',
{
variants: {
variant: {
default: '',
},
sizes: {
default: '',
large: '',
},
},
defaultVariants: {
sizes: 'default',
variant: 'default',
},
},
);

export interface InputProps extends React.InputHTMLAttributes<HTMLInputElement>, VariantProps<typeof inputVariants> {
asChild?: boolean;
error?: ReactNode;
label?: ReactNode;
endAdornment?: ReactNode;
startAdornment?: ReactNode;
wrapperClassName?: string;
}

const Input = React.forwardRef<HTMLInputElement, InputProps>(
(
{
label,
wrapperClassName,
endAdornment,
startAdornment,
error,
className,
variant,
sizes,
asChild = false,
...props
},
ref,
) => {
const Comp = asChild ? Slot : 'input';

if (props.type === 'checkbox') {
return (
<div className="flex flex-col">
<div className="flex flex-row items-center gap-2">
<Comp ref={ref} className={cn(className)} id={props.name} {...props} />
<label htmlFor={props.name}>{label}</label>
</div>
<div className="text-red-400">{error}</div>
</div>
);
}

return (
<div className="flex flex-col gap-2">
{label}
<div
className={cn(
'grid grid-cols-[auto_1fr_auto] items-center rounded-[16px] bg-[#FFFFFF1A] pr-2 text-white md:pr-3',
wrapperClassName,
error ? 'border-red border' : '',
)}
>
{startAdornment ?? <div />}
<Comp
className={cn(
inputVariants({ variant, className, sizes }),
props.disabled ? 'cursor-not-allowed text-white/50' : 'cursor-pointer placeholder:text-white',
)}
ref={ref}
{...props}
/>
{endAdornment ?? <div />}
</div>
{error && <div className="text-red text-[15px]">{error}</div>}
</div>
);
},
);

Input.displayName = 'Input';

export { Input };
4 changes: 2 additions & 2 deletions src/constants/addresses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ export const wSolMint = new PublicKey('So111111111111111111111111111111111111111

// todo change addresses
export const OwnerAddress = {
[WalletAdapterNetwork.Mainnet]: new PublicKey('dBLGG3ERvVsAexwfLeRaPUSzQQryKsabNEFKpuMqQqQ'),
[WalletAdapterNetwork.Devnet]: new PublicKey('dBLGG3ERvVsAexwfLeRaPUSzQQryKsabNEFKpuMqQqQ'),
[WalletAdapterNetwork.Mainnet]: new PublicKey('9L3FxnqEurHxQBANpcZbjgP8tHUNrLFXzGk1pjZVr47x'),
[WalletAdapterNetwork.Devnet]: new PublicKey('9L3FxnqEurHxQBANpcZbjgP8tHUNrLFXzGk1pjZVr47x'),
};
1 change: 1 addition & 0 deletions src/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const env = createEnv({
VITE_API_URL: z.string().optional(),
VITE_PUBLIC_NETWORKS_MODE: z.enum(['testnet', 'mainnet']).default('testnet'),
VITE_PUBLIC_SOLANA_RPC: z.string().optional(),
VITE_DEPOSIT_AMOUNT_SOL: z.string().default('0.01'),
},
runtimeEnv: import.meta.env,
});
33 changes: 33 additions & 0 deletions src/hooks/api/use-submit-cards.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { useWallet } from '@solana/wallet-adapter-react';
import { useMutation } from '@tanstack/react-query';

import { post } from './utils';

import { authClient } from '@/lib/fetcher';
import { TarotCard } from '@/types/tarot';

const useSubmitTarotCards = () => {
const { publicKey } = useWallet();

return useMutation({
async mutationFn({ tarots, hash, question }: { tarots: TarotCard[]; hash: string; question: string }) {
if (!publicKey) {
return;
}

const client = authClient();

return await post<{ response: string }>(client, `tarot/generate-response`, {
tarots,
hash,
question,
});
},

onError(error) {
console.trace(error);
},
});
};

export default useSubmitTarotCards;
52 changes: 52 additions & 0 deletions src/hooks/api/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { Fetcher } from '@/lib/fetcher';

export const get = async <T>(fetcher: Fetcher, method: string) => {
const response = await fetcher.get<T>(method);
if (!(response.status >= 200 && response.status < 300)) {
throw new Error(response.statusText);
}

return response.data;
};

export const put = async <T>(client: Fetcher, method: string, data: Record<string, unknown>) => {
const response = await client.put<T>(method, { data });
if (!(response.status >= 200 && response.status < 300)) {
throw new Error(response.statusText);
}

return response.data;
};

export const post = async <T>(
client: Fetcher,
method: string,
data?: Record<string, unknown>,
signal?: AbortSignal,
) => {
const response = await client.post<T>(method, data, signal);
if (!(response.status >= 200 && response.status < 300)) {
throw new Error(response.error ?? response.statusText);
}

console.log('response', response);
return response.data;
};

export const patch = async <T>(client: Fetcher, method: string, data: Record<string, unknown>) => {
const response = await client.patch<T>(method, data);
if (!(response.status >= 200 && response.status < 300)) {
throw new Error(response.statusText);
}

return response.data;
};

export const deleteOperation = async <T>(client: Fetcher, method: string) => {
const response = await client.delete<T>(method);
if (!(response.status >= 200 && response.status < 300)) {
throw new Error(response.statusText);
}

return response.data;
};
50 changes: 50 additions & 0 deletions src/hooks/contracts/write/use-make-prediction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { useWallet } from '@solana/wallet-adapter-react';
import { Transaction, SystemProgram } from '@solana/web3.js';
import { useMutation } from '@tanstack/react-query';

import { OwnerAddress } from '@/constants/addresses';
import { env } from '@/env';
import useSubmitTarotCards from '@/hooks/api/use-submit-cards';
import { network } from '@/lib/solana';
import { sendAndConfirmTransaction } from '@/lib/solana/utils';
import { getRandomTarotCards, showTxToast } from '@/lib/utils';

const useMakePrediction = () => {
const { publicKey, sendTransaction } = useWallet();
const { mutateAsync: submitCards, data: predictionAnswer } = useSubmitTarotCards();

return useMutation({
async mutationFn(question: string) {
if (!publicKey) {
return;
}

await showTxToast('Making prediction', async () => {
const rawTx = new Transaction();

rawTx.add(
SystemProgram.transfer({
fromPubkey: publicKey,
toPubkey: OwnerAddress[network],
lamports: Number(env.VITE_DEPOSIT_AMOUNT_SOL) * 1e9,
}),
);

const txHash = await sendAndConfirmTransaction(publicKey, rawTx, sendTransaction);
console.log('txHash', txHash);

const tarots = getRandomTarotCards(txHash + publicKey.toBase58());

await submitCards({ tarots, hash: txHash, question });
});

return predictionAnswer;
},

onError(error) {
console.trace(error);
},
});
};

export default useMakePrediction;
41 changes: 0 additions & 41 deletions src/hooks/contracts/write/use-transfer-solana.ts

This file was deleted.

Loading

0 comments on commit 838fa5c

Please sign in to comment.