Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev #59

Merged
merged 119 commits into from
Oct 15, 2024
Merged

Dev #59

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
119 commits
Select commit Hold shift + click to select a range
0aaa207
Merge pull request #21 from JetonDAO/emit-private-card
arssly Sep 15, 2024
dd7babd
add shuffle animation
mhzrerfani Sep 17, 2024
ae130ef
Add some flavor to homepage and main menu
mhzrerfani Sep 19, 2024
b311f8e
Merge branch 'dev' into style/setup
mhzrerfani Sep 19, 2024
485baf9
Remove unused login route and modal
mhzrerfani Sep 20, 2024
0026e94
Dancing with aligators
mhzrerfani Sep 20, 2024
cf4de44
Merge pull request #23 from JetonDAO/style/setup
arssly Sep 20, 2024
9145995
WIP: all betting logic in Game
arssly Sep 17, 2024
b5def77
WIP: untested betting logic
arssly Sep 20, 2024
b57c4fb
Add tests and debug
arssly Sep 22, 2024
7245aab
Merge pull request #24 from JetonDAO/initial-betting-round
arssly Sep 22, 2024
763a3f0
fix template format
arssly Sep 22, 2024
6e89447
Merge pull request #25 from JetonDAO/fix-service-worker
arssly Sep 22, 2024
c97bc28
add aptos connect id
Sep 22, 2024
c603af0
Merge pull request #27 from JetonDAO/aptos-connect-id
farzaamam Sep 22, 2024
8a04d08
Change aptosconnect.txt file
Sep 23, 2024
d292471
Merge pull request #28 from JetonDAO/fix-aptosconnect-text-file
farzaamam Sep 23, 2024
81071cc
Fix aptosconnect.txt content
Sep 23, 2024
5c2a095
Merge pull request #29 from JetonDAO/fix-aptos-id-content-file
farzaamam Sep 23, 2024
4e3ef42
Add mizu wallet and Sign create table transaction
Sep 23, 2024
60f1886
setup env and ci for env variables, Refactor create table transaction…
Sep 23, 2024
652a61c
Merge pull request #30 from JetonDAO/create-table-onchain-mizu-integrate
arssly Sep 24, 2024
1eb1fef
Read base url hardcoded for mizu
Sep 24, 2024
bd860bd
Merge pull request #32 from JetonDAO/fix-base-url-
farzaamam Sep 24, 2024
b4d8ad1
WIP: rest of decryption and betting
arssly Sep 22, 2024
dcacee9
Merge pull request #33 from JetonDAO/decrypt-public-cards
arssly Sep 24, 2024
ef35d81
Add states to web app
arssly Sep 25, 2024
42293e0
Merge pull request #34 from JetonDAO/add-events-to-app
arssly Sep 25, 2024
6caec89
wip: Add some transitions
mhzrerfani Sep 25, 2024
09c21bd
Fetch Tables and table info, and contract events and methods
Sep 25, 2024
ede233f
Merge pull request #35 from JetonDAO/fetch-onchain-data
arssly Sep 25, 2024
101f662
Delete apps/web/src/app/@modal/(.)join/join/page.tsx
mhzrerfani Sep 25, 2024
75c32bf
WIP: polling stuff
arssly Sep 25, 2024
2ec471c
Merge pull request #36 from JetonDAO/mystical-styles
arssly Sep 26, 2024
1eab6fe
getTable list and refactor interaction with contract
Sep 26, 2024
e5589d5
Merge branch 'dev' into polling
farzaamam Sep 26, 2024
6e92e38
Revert Changes
Sep 26, 2024
05fa8f4
remove unused code
Sep 26, 2024
4e71a7d
Remove unused field from tableInfo
Sep 26, 2024
bfb2b78
Remove waitingBlock field
Sep 26, 2024
2c9468f
Merge pull request #39 from JetonDAO/polling
farzaamam Sep 26, 2024
540d949
Implement jubjub curve in move
ArmanMazdaee Sep 17, 2024
24635bd
Refactor zk-deck
ArmanMazdaee Sep 23, 2024
c0ed7ed
implement zk-deck contracts
ArmanMazdaee Sep 26, 2024
88b590c
Add base for texas_holdem contract
ArmanMazdaee Sep 26, 2024
60a700e
Fix zk-deck breaking changes
ArmanMazdaee Sep 26, 2024
672a19e
Fix aptos cli issue on cicd
ArmanMazdaee Sep 26, 2024
bc6d2e2
Add check_out logic to contracts
ArmanMazdaee Sep 27, 2024
2cff6ee
Merge pull request #37 from JetonDAO/implement-smart-contracts
arssly Sep 27, 2024
18a3086
Add dealing card game state to ui
mhzrerfani Sep 26, 2024
6667871
WIP: fix sdk bugs
arssly Sep 26, 2024
9324738
some changes
mhzrerfani Sep 27, 2024
4fea57f
Fix export issue
mhzrerfani Sep 27, 2024
837b95d
Add dealing card and bet animations
mhzrerfani Sep 28, 2024
e45c077
Refactor
mhzrerfani Sep 30, 2024
ff9cece
Add some improvements
mhzrerfani Oct 3, 2024
6372706
Optimize images
mhzrerfani Oct 4, 2024
894f71a
Add loading spinner
mhzrerfani Oct 4, 2024
05f7726
Merge pull request #41 from JetonDAO/mystical-styles
arssly Oct 5, 2024
3677e3c
WIP: polling stuff
arssly Sep 26, 2024
858bbf3
WIP
arssly Sep 27, 2024
838c6e4
create Jeton
arssly Sep 29, 2024
a1fad33
Update Jeton context usage
arssly Oct 5, 2024
8ff9176
Fix tests
arssly Oct 5, 2024
ac82671
Add getTablesInfo to OnChainDataSource
arssly Oct 5, 2024
103a906
WIP
arssly Oct 10, 2024
609cfbe
Toff: fix create bug
arssly Oct 11, 2024
aa236d9
Toff: fix create bug
arssly Oct 11, 2024
9993c44
fix form values
arssly Oct 11, 2024
e14a31b
Merge pull request #42 from JetonDAO/polling
farzaamam Oct 11, 2024
c9ad599
Add check in and other stuff
mhzrerfani Oct 12, 2024
3240493
Merge pull request #43 from JetonDAO/feat/check-in
arssly Oct 12, 2024
d844a30
WIP: add card decryption logic
arssly Oct 11, 2024
6ad0ec1
Download game assets before game starts
arssly Oct 12, 2024
a59a3b1
Fix card decrypt shares
arssly Oct 12, 2024
e1166e0
Merge pull request #44 from JetonDAO/polling
farzaamam Oct 12, 2024
ecefc06
Complete bet logic
arssly Oct 12, 2024
ae0cc65
Fix player
arssly Oct 12, 2024
c7d3425
Add some good stuff, new shuffling animation and a little improvement…
mhzrerfani Oct 13, 2024
045e4d0
Fix: awaiting bet event not called at the start of betting round
arssly Oct 13, 2024
d9b411e
Merge pull request #46 from JetonDAO/good-stuff
arssly Oct 13, 2024
a5d8566
Merge pull request #45 from JetonDAO/bet-logic
arssly Oct 13, 2024
e6a5854
Add winner animation and other good stuff
mhzrerfani Oct 13, 2024
4002508
Merge branch 'dev' into good-stuff
arssly Oct 13, 2024
92bad10
Merge pull request #47 from JetonDAO/good-stuff
arssly Oct 13, 2024
69b85f0
show down
arssly Oct 13, 2024
8b56f56
Merge branch 'dev' into show-down
arssly Oct 13, 2024
e165a28
Merge pull request #48 from JetonDAO/show-down
arssly Oct 14, 2024
ca08248
Add great stuff, jeton is responsive now
mhzrerfani Oct 14, 2024
cac145d
Fix style issues
mhzrerfani Oct 14, 2024
bcf0dbc
Fix table height
mhzrerfani Oct 14, 2024
328ffb5
Fix modal style issue
mhzrerfani Oct 14, 2024
ef6ac76
Faster shuffle
mhzrerfani Oct 14, 2024
40bb51e
Merge pull request #49 from JetonDAO/great-stuff
arssly Oct 14, 2024
feea785
Implement new onchain structure
arssly Oct 14, 2024
8651fb6
fix my cards issue
mhzrerfani Oct 14, 2024
8af1646
Fix dealer badge issue
mhzrerfani Oct 14, 2024
0e09805
Merge pull request #50 from JetonDAO/show-down
arssly Oct 14, 2024
c9f35fc
Merge branch 'dev' into fix/my-cards
arssly Oct 14, 2024
dfea645
Merge pull request #51 from JetonDAO/fix/my-cards
arssly Oct 14, 2024
4e691fe
in app wallet
arssly Oct 14, 2024
f238a85
Merge pull request #52 from JetonDAO/in-app-wallet
arssly Oct 14, 2024
7c8734a
fix show down bugs
arssly Oct 14, 2024
34a1e68
Merge pull request #53 from JetonDAO/show-down-bugs
farzaamam Oct 14, 2024
c2e9a92
Switch decrypt card share to serialize
arssly Oct 14, 2024
fd4de03
Merge pull request #54 from JetonDAO/show-down-bugs
arssly Oct 15, 2024
653f2b5
add winning and betting animations
mhzrerfani Oct 15, 2024
567dbb7
Fix seat players ref issue
mhzrerfani Oct 15, 2024
7aee108
fix in app wallet submit type issue
mhzrerfani Oct 15, 2024
c568c27
Add description to download modal
mhzrerfani Oct 15, 2024
16d3814
Merge pull request #55 from JetonDAO/late-stuff
arssly Oct 15, 2024
54a0c3f
Too late to add transactions
arssly Oct 15, 2024
1e7d93f
Merge pull request #56 from JetonDAO/show-tnx
arssly Oct 15, 2024
6c5646c
Implement holdem smart contracts
ArmanMazdaee Oct 15, 2024
a1ec4c6
fix avatars
mhzrerfani Oct 15, 2024
3fe96a3
Add project-overview.md
ArmanMazdaee Oct 15, 2024
22e48cd
Merge pull request #58 from JetonDAO/fix/avatars
arssly Oct 15, 2024
61243f4
Merge pull request #57 from JetonDAO/implement-smart-contracts
arssly Oct 15, 2024
ee33588
Merge branch 'main' into dev
arssly Oct 15, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/actions/deploy/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ inputs:
piesocket-api-key:
description: "PieSocket API Key"
required: true
base-url:
description: "Base URL for WebApp"
required: true
contracts-addr:
description: "Contracts Address"
required: true
outputs:
cloudflare-preview-url:
description: "Couldflare Preview URL"
Expand All @@ -20,6 +26,8 @@ runs:
shell: bash
env:
PIESOCKET_API_KEY: ${{ inputs.piesocket-api-key }}
NEXT_PUBLIC_BASE_URL: ${{ inputs.base-url }}
NEXT_PUBLIC_CONTRACTS_ADDR: ${{ inputs.contracts-addr }}
run: npm run build
- name: Deploy To Cloudflare
id: deploy
Expand Down
9 changes: 7 additions & 2 deletions .github/actions/setup/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,20 @@ runs:
- name: Cache Turbo Build Setup
uses: actions/cache@v4
with:
path: .turbo
path: |
~/.cargo
.turbo
key: ${{ runner.os }}-release-job-${{ github.sha }}
restore-keys: |
${{ runner.os }}-release-job-
- name: Insall circom
shell: bash
run: cargo install --git https://github.com/iden3/circom.git --tag v2.1.9
- name: Setup Node.js Environment
uses: actions/setup-node@v4
with:
node-version: 20
cache: "npm"
- name: Install Dependencies
shell: bash
run: npm install
run: npm ci
2 changes: 2 additions & 0 deletions .github/workflows/cicd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ jobs:
with:
cloudflare-api-token: ${{ secrets.CLOUDFLARE_API_TOKEN }}
piesocket-api-key: ${{ secrets.PIESOCKET_API_KEY }}
base-url: ${{ secrets.BASE_URL }}
contracts-addr: ${{ secrets.CONTRACTS_ADDR }}
- name: Comment Preview URL
uses: actions/github-script@v7
if: github.event_name == 'pull_request'
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -148,3 +148,7 @@ dist
# Misc
.DS_Store
*.pem

# Aptos
.aptos

26 changes: 22 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
# jeton
# Jeton: A Decentralized and Trustless Poker Platform

Decentralized poker protocol enabling trustless, transparent, and community-governed gameplay – powered by JatonDAO.
Jeton is a decentralized poker platform designed to ensure fairness and transparency in online poker games. Built on the Aptos blockchain, Jeton eliminates the need for players to trust a central authority by leveraging zk-SNARKs (Zero-Knowledge Succinct Non-Interactive Arguments of Knowledge) and Elgamal encryption. These cryptographic techniques guarantee that the cards are shuffled, encrypted, and dealt fairly without revealing any information to players or the platform itself.

The platform utilizes Elgamal encryption on the JubJub elliptic curve to securely encrypt cards and zk-SNARK circuits to verify both the shuffle and decryption processes. Each player participates in shuffling the deck and generating decryption shares, ensuring no individual player or entity can manipulate the outcome. Smart contracts on the Aptos blockchain handle the game logic and verify cryptographic proofs, providing a fully decentralized and tamper-proof environment for online poker.

For a more detailed explanation of the algorithms, security considerations, and cryptographic methods used in Jeton, you can read the [full project overview](project-overview.md).

## What's inside?

This Turborepo includes the following packages/apps:

### Apps and Packages

- `web`: a [Next.js](https://nextjs.org/) app
- `web`: the web application of the jeton protocol, implemented in [Next.js](https://nextjs.org/)
- `@jeton/zk-deck`: a package containing Move, TypeScript, and Circom code, for implementing zero knowledge based playing decks
- `@jeton/smart-contracts`: a Move package responsible for on chain game logic
- `@jeton/ts-sdk`:
- `@jeton/ui`: a React component library shared by `web` application
- `@jeton/tailwindcss-config`:
- `@jeton/typescript-config`: `tsconfig.json`s used throughout the monorepo
Each package/app is 100% [TypeScript](https://www.typescriptlang.org/).

Expand All @@ -30,7 +38,17 @@ Make sure you have the correct versions of Node.js and npm installed:
- **Node.js**: v20.16 or later
- **npm**: v10.8 or later

You can use [NVM](https://github.com/nvm-sh/nvm) to install the required version of node and npm.
You can use [NVM](https://github.com/nvm-sh/nvm) to install the required version
of node and npm.

Also you need rustc and cargo install. It is recommended to use
[rustup](https://rustup.rs/) to install them.

After that you need to also install circom using:

```shell
cargo install --git https://github.com/iden3/circom.git --tag v2.1.9
```

### Cloning the Repository

Expand Down
3 changes: 3 additions & 0 deletions apps/web/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,6 @@ yarn-error.log*
# typescript
*.tsbuildinfo
next-env.d.ts

#generated service worker file
public/sw.js
11 changes: 11 additions & 0 deletions apps/web/addCacheUrls.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { readFileSync, writeFileSync } from "fs";
import { decryptCardShareZkey, shuffleEncryptDeckZkey } from "@jeton/zk-deck";

const SWFile = readFileSync("./src/sw.template.js", "utf-8");

const modifiedSWFile = SWFile.replace(
'"<urlPlaceHolder>"',
`"${decryptCardShareZkey}", "${shuffleEncryptDeckZkey}"`,
);

writeFileSync("./public/sw.js", modifiedSWFile, "utf-8");
26 changes: 25 additions & 1 deletion apps/web/next.config.mjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,31 @@
import { setupDevPlatform } from "@cloudflare/next-on-pages/next-dev";

/** @type {import('next').NextConfig} */
const nextConfig = {};
const nextConfig = {
webpack(config) {
config.module.rules.push({
test: /\.(mp3|ogg)$/i,
use: [
{
loader: "file-loader",
options: {
name: "[path][name].[ext]",
publicPath: "/_next/static/audio/",
outputPath: "static/audio/",
},
},
],
});
config.module.rules.push({
test: /\.wasm/,
type: "asset/resource",
});
// config.externals.push({
// "node:crypto": "crypto",
// });
return config;
},
};

if (process.env.NODE_ENV === "development") {
await setupDevPlatform();
Expand Down
18 changes: 15 additions & 3 deletions apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,30 @@
"private": true,
"scripts": {
"dev": "next dev",
"dev:service-worker": "tsx ./addCacheUrls.mts",
"build:service-worker": "tsx ./addCacheUrls.mts",
"build": "next build",
"next-on-pages": "npx @cloudflare/next-on-pages",
"start": "next start"
},
"dependencies": {
"@jeton/ts-sdk": "*",
"@jeton/ui": "*",
"@aptos-labs/ts-sdk": "^1.29.1",
"@aptos-labs/wallet-adapter-ant-design": "^3.0.13",
"@aptos-labs/wallet-adapter-react": "^3.6.2",
"@jeton/ts-sdk": "*",
"@jeton/ui": "*",
"@jeton/zk-deck": "*",
"@legendapp/state": "^3.0.0-alpha.29",
"clsx": "^2.1.1",
"framer-motion": "^11.6.0",
"graphql": "^16.9.0",
"graphql-request": "^7.1.0",
"nes.css": "^2.2.1",
"next": "^14.2.8",
"react": "^18.3.1",
"react-dom": "^18.3.1"
"react-dom": "^18.3.1",
"tailwind-merge": "^2.5.2",
"tsx": "^4.19.1"
},
"devDependencies": {
"@cloudflare/next-on-pages": "^1.13.2",
Expand All @@ -28,6 +39,7 @@
"@types/react-dom": "^18",
"autoprefixer": "^10.4.20",
"postcss": "^8.4.41",
"postcss-import": "^16.1.0",
"tailwindcss": "^3.4.10",
"typescript": "^5"
}
Expand Down
5 changes: 3 additions & 2 deletions apps/web/postcss.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
"postcss-import": {}, // Import CSS files first
tailwindcss: {}, // Then apply TailwindCSS
autoprefixer: {}, // Lastly, add vendor prefixes
},
};
1 change: 1 addition & 0 deletions apps/web/public/aptosconnect.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
b76e8b1d-3fe8-442a-b254-47b2dcff3f2a
Binary file added apps/web/public/images/card-back.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/web/public/images/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/web/public/images/pixel-wooden-pattern.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/web/public/images/wood-pattern-light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions apps/web/public/mizuwallet-connect-manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"url": "https://dev.jeton.pages.dev",
"name": "Test Login with mizu",
"iconUrl": "https://dev.jeton.pages.dev/images/logo.png"
}
11 changes: 11 additions & 0 deletions apps/web/public/register-service-worker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
function registerServiceWorker() {
if (typeof window !== "undefined") {
if ("serviceWorker" in navigator) {
navigator.serviceWorker.register("/sw.js").catch((e) => {
console.log("service worker installation error", e);
});
}
}
}

registerServiceWorker();
137 changes: 137 additions & 0 deletions apps/web/src/app/@modal/(.)create/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
"use client";

import { useWallet } from "@aptos-labs/wallet-adapter-react";
import { ChipUnits, type TableInfo } from "@jeton/ts-sdk";
import Modal from "@src/components/Modal";
import { usePathname, useRouter } from "next/navigation";
import React, { useState, type ChangeEvent, type FormEvent, useContext, useEffect } from "react";

export const runtime = "edge";

type FormValues = Omit<TableInfo, "id">;

import { decryptCardShareZkey, shuffleEncryptDeckZkey } from "@jeton/zk-deck";
//@ts-ignore
import decryptCardShareWasm from "@jeton/zk-deck/wasm/decrypt-card-share.wasm";
//@ts-ignore
import shuffleEncryptDeckWasm from "@jeton/zk-deck/wasm/shuffle-encrypt-deck.wasm";
import CheckIn from "@src/components/CheckIn";
import { Input } from "@src/components/Input";
import { JetonContext } from "@src/components/JetonContextProvider";
import useCheckIn from "@src/hooks/useCheckIn";
import type { SignAndSubmitTransaction } from "@src/types/SignAndSubmitTransaction";
import { finalAddressAndSignFunction } from "@src/utils/inAppWallet";

const INITIAL_FORM_VALUES: FormValues = {
smallBlind: 1,
numberOfRaises: 2,
minPlayers: 2,
minBuyIn: 100,
maxBuyIn: 1000,
maxPlayers: 9,
waitingTimeout: 3600,
chipUnit: ChipUnits.apt,
};

const INPUT_FIELDS = [
{ label: "Small Blind", name: "smallBlind" },
{ label: "Number of Raises", name: "numberOfRaises" },
{ label: "Minimum Players", name: "minPlayers" },
{ label: "Minimum Buy-in", name: "minBuyIn" },
{ label: "Maximum Buy-in", name: "maxBuyIn" },
];

export default function GameCreateModal() {
const [loading, setLoading] = useState(false);
const [formValues, setFormValues] = useState<FormValues>(INITIAL_FORM_VALUES);
const { account, signAndSubmitTransaction } = useWallet();
const { checkIn, submitCheckIn } = useCheckIn();
const [isCreating, setIsCreating] = useState(false);

const { createTable } = useContext(JetonContext);
const router = useRouter();

const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target;
setFormValues((prev) => ({
...prev,
[name]: Number.parseInt(value),
}));
};

const handleSubmit = async (event: FormEvent<HTMLFormElement>) => {
event.preventDefault();
setLoading(true);

try {
if (!createTable) throw new Error("create Table must exist");
if (!checkIn) throw new Error("Check in you must do");

const TIMEOUT = 300; // 5 minutes
const [finalAddress, finalSignAndSubmit] = finalAddressAndSignFunction(
account!.address,
signAndSubmitTransaction as SignAndSubmitTransaction,
);

const jeton = await createTable(
formValues.smallBlind,
formValues.numberOfRaises,
formValues.minPlayers,
formValues.minBuyIn,
formValues.maxBuyIn,
TIMEOUT,
formValues.chipUnit,
checkIn,
finalAddress,
finalSignAndSubmit,
{
decryptCardShareWasm,
shuffleEncryptDeckWasm,
decryptCardShareZkey,
shuffleEncryptDeckZkey,
},
);

router.push(`/games/${jeton.tableInfo.id}`);
} finally {
setLoading(false);
}
};

return (
<Modal className="animate-scaleUp max-w-md">
{isCreating ? (
<form onSubmit={handleSubmit}>
<div className="text-white text-lg mb-5">Create a New Game</div>
<div className="flex flex-col gap-3">
{INPUT_FIELDS.map(({ label, name }) => (
<Input
key={name}
label={label}
type="number"
value={formValues[name as keyof FormValues]}
name={name}
onChange={handleChange}
/>
))}
</div>
<button
className="nes-btn is-primary rounded-lg w-full py-2 px-4 mt-3"
type="submit"
disabled={loading}
>
{loading ? "Creating..." : "Create Game"}
</button>
</form>
) : (
<CheckIn
onSubmit={(value) =>
submitCheckIn(value, () => {
setIsCreating(true);
})
}
/>
)}
</Modal>
);
}
Loading