diff --git a/package.json b/package.json index 9c6023ce..9dd26a85 100644 --- a/package.json +++ b/package.json @@ -1,66 +1,66 @@ { - "name": "juice-defifa-interface", - "version": "0.1.0", - "private": true, - "scripts": { - "dev": "next dev", - "build": "next build", - "start": "next start", - "lint": "next lint", - "ts:compile": "tsc", - "ts:compile:watch": "tsc --watch", - "ts:prune": "ts-prune" - }, - "dependencies": { - "@apollo/client": "^3.7.1", - "@ballkidz/defifa-collection-deployer": "1.0.34", - "@headlessui/react": "^1.7.15", - "@heroicons/react": "^2.0.18", - "@jbx-protocol/juice-721-delegate": "7.0.0", - "@jbx-protocol/juice-contracts-v3": "3.1.2", - "@rainbow-me/rainbowkit": "^0.7.0", - "axios": "^1.1.3", - "bs58": "^4.0.1", - "ethers": "^5.7.1", - "forge-run-parser": "^1.0.3", - "google-spreadsheet": "^3.3.0", - "graphql": "^16.6.0", - "graphql-request": "^5.0.0", - "ipfs-http-client": "^60.0.0", - "lodash": "^4.17.21", - "moment": "^2.29.4", - "next": "12.3.1", - "react": "^18.1.0", - "react-card-flip": "^1.2.0", - "react-confirm-alert": "^3.0.6", - "react-datepicker": "^4.12.0", - "react-dom": "18.2.0", - "react-query": "^3.39.2", - "react-table": "^7.8.0", - "react-tabs": "^6.0.0", - "react-toastify": "^9.1.1", - "reactjs-popup": "^2.0.5", - "sass": "^1.62.1", - "tailwind-merge": "^1.12.0", - "use-google-sheets": "^2.0.0", - "wagmi": "^0.6.7" - }, - "devDependencies": { - "@tailwindcss/forms": "^0.5.3", - "@types/bs58": "^4.0.1", - "@types/lodash": "^4.14.188", - "@types/node": "18.7.19", - "@types/react": "18.0.21", - "@types/react-datepicker": "^4.11.2", - "@types/react-dom": "18.0.6", - "@types/react-slick": "^0.23.10", - "@types/react-table": "^7.7.14", - "autoprefixer": "^10.4.14", - "eslint": "8.24.0", - "eslint-config-next": "12.3.1", - "eslint-config-prettier": "^8.8.0", - "tailwindcss": "^3.3.2", - "ts-prune": "^0.10.3", - "typescript": "4.8.3" - } -} + "name": "juice-defifa-interface", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "next lint", + "ts:compile": "tsc", + "ts:compile:watch": "tsc --watch", + "ts:prune": "ts-prune" + }, + "dependencies": { + "@apollo/client": "^3.7.1", + "@ballkidz/defifa-collection-deployer": "1.0.34", + "@headlessui/react": "^1.7.15", + "@heroicons/react": "^2.0.18", + "@jbx-protocol/juice-721-delegate": "7.0.0", + "@jbx-protocol/juice-contracts-v3": "3.1.2", + "@rainbow-me/rainbowkit": "^0.7.0", + "axios": "^1.1.3", + "bs58": "^4.0.1", + "ethers": "^5.7.1", + "forge-run-parser": "^1.0.3", + "google-spreadsheet": "^3.3.0", + "graphql": "^16.6.0", + "graphql-request": "^5.0.0", + "ipfs-http-client": "^60.0.0", + "lodash": "^4.17.21", + "moment": "^2.29.4", + "next": "12.3.1", + "react": "^18.1.0", + "react-card-flip": "^1.2.0", + "react-confirm-alert": "^3.0.6", + "react-datepicker": "^4.12.0", + "react-dom": "18.2.0", + "react-query": "^3.39.2", + "react-table": "^7.8.0", + "react-tabs": "^6.0.0", + "react-toastify": "^9.1.1", + "reactjs-popup": "^2.0.5", + "sass": "^1.62.1", + "tailwind-merge": "^1.12.0", + "use-google-sheets": "^2.0.0", + "wagmi": "^0.6.7" + }, + "devDependencies": { + "@tailwindcss/forms": "^0.5.3", + "@types/bs58": "^4.0.1", + "@types/lodash": "^4.14.188", + "@types/node": "18.7.19", + "@types/react": "18.0.21", + "@types/react-datepicker": "^4.11.2", + "@types/react-dom": "18.0.6", + "@types/react-slick": "^0.23.10", + "@types/react-table": "^7.7.14", + "autoprefixer": "^10.4.14", + "eslint": "8.24.0", + "eslint-config-next": "12.3.1", + "eslint-config-prettier": "^8.8.0", + "tailwindcss": "^3.3.2", + "ts-prune": "^0.10.3", + "typescript": "4.8.3" + } +} \ No newline at end of file diff --git a/public/assets/404_Airball.png b/public/assets/404_Airball.png new file mode 100644 index 00000000..75ce9329 Binary files /dev/null and b/public/assets/404_Airball.png differ diff --git a/src/components/GameDashboard/GameContainer/RulesContent/RulesContent.tsx b/src/components/GameDashboard/GameContainer/RulesContent/RulesContent.tsx index e60e170f..819c49eb 100644 --- a/src/components/GameDashboard/GameContainer/RulesContent/RulesContent.tsx +++ b/src/components/GameDashboard/GameContainer/RulesContent/RulesContent.tsx @@ -116,8 +116,8 @@ export function RulesContent() { No fees are collected ) : ( <> - {/* */} - + {/* */} + collects a {metadata?.seller_fee_basis_points}% fee on each pick minted. diff --git a/src/components/Mlb/Create/defaultState.ts b/src/components/Mlb/Create/defaultState.ts new file mode 100644 index 00000000..5de706f1 --- /dev/null +++ b/src/components/Mlb/Create/defaultState.ts @@ -0,0 +1,62 @@ +import { getChainData } from "config"; +import { ETH_TOKEN_ADDRESS } from "constants/addresses"; +import { + BALLKIDZ_MULTISIG_ADDRESS, + JUICEBOX_PROJECT_METADATA_DOMAIN, + MINT_PRICE, +} from "constants/constants"; +import { constants } from "ethers"; +import { formatUnits } from "ethers/lib/utils"; +import { DefifaLaunchProjectData } from "types/defifa"; + +const DEFAULT_MINT_DURATION_SECONDS = 60 * 5; // 1 hour +const DEFAULT_REFUND_DURATION_SECONDS = 60 * 0; // 1 hour +const GAME_START_BUFFER_SECONDS = 60 * 1; // 1 minute + +export const createDefaultLaunchProjectData = (): DefifaLaunchProjectData => { + const chainData = getChainData(); + const currentUnixTimestamp = Math.floor(Date.now() / 1000); + + const scoringStartTime = + currentUnixTimestamp + + DEFAULT_MINT_DURATION_SECONDS + + DEFAULT_REFUND_DURATION_SECONDS + + GAME_START_BUFFER_SECONDS; + + return { + name: "", + rules: "", + mintDuration: DEFAULT_MINT_DURATION_SECONDS, + refundDuration: DEFAULT_REFUND_DURATION_SECONDS, + start: scoringStartTime, + votingPeriod: 0, // seconds, 0 to allow ratify as soon as quorum is reached. + votingStartTime: 0, + tiers: [], + splits: [], + token: ETH_TOKEN_ADDRESS, + ballkidzFeeProjectTokenAccount: BALLKIDZ_MULTISIG_ADDRESS, + defaultVotingDelegate: BALLKIDZ_MULTISIG_ADDRESS, + defaultTokenUriResolver: constants.AddressZero, + contractUri: "", + baseUri: "ipfs://", + distributionLimit: 0, + projectMetadata: { + content: "", + domain: JUICEBOX_PROJECT_METADATA_DOMAIN, + }, + terminal: chainData.JBETHPaymentTerminal.address, + store: chainData.JBTiered721DelegateStore.address, + }; +}; + +export const createDefaultTierData = () => { + return { + name: "", + price: formatUnits(MINT_PRICE), + reservedRate: 0, + reservedTokenBeneficiary: constants.AddressZero, + encodedIPFSUri: + "0x0000000000000000000000000000000000000000000000000000000000000000", + shouldUseReservedTokenBeneficiaryAsDefault: false, + }; +}; diff --git a/src/components/Mlb/Create/index.tsx b/src/components/Mlb/Create/index.tsx new file mode 100644 index 00000000..22f66b65 --- /dev/null +++ b/src/components/Mlb/Create/index.tsx @@ -0,0 +1,125 @@ +import React, { useState, useEffect } from 'react'; +import { useCreateGame } from 'hooks/write/useCreateGame'; +import { DefifaLaunchProjectData, DefifaTierParams } from 'types/defifa'; +import { contractUri, projectMetadataUri } from 'uri/contractUri'; +import { createDefaultLaunchProjectData, createDefaultTierData } from './defaultState'; +import { constants } from 'ethers'; +import useScheduleData from '../../../hooks/read/AllMlbGames'; + +const MlbCreate = () => { + const [project, setProject] = useState(createDefaultLaunchProjectData()); + const { tableData, loading, resetTableData } = useScheduleData(); + const [tier, setTier] = useState(createDefaultTierData()); + + console.log('project', project); + + const { write: createTournament, isLoading, isSuccess, transactionData } = useCreateGame(project); + + function addSpacesToWords(str) { + const words = str.split(' '); + let result = ''; + let count = 0; + + for (let i = 0; i < words.length; i++) { + if (count + words[i].length > 10) { + result += ' '; + count = 0; + } + result += words[i] + ' '; + count += words[i].length + 1; + } + + return result.trim(); + } + + + const handleCheckboxClick = (event: React.ChangeEvent, game: any, index: number) => { + const checked = event.target.checked; + console.log('Checkbox clicked on row:', index, 'checked:', checked); + + const awayTeam = addSpacesToWords(game?.teams?.away.team.name) || ''; + const homeTeam = addSpacesToWords(game?.teams?.home.team.name) || ''; + console.log('awayTeam', awayTeam); + console.log('homeTeam', homeTeam); + + const startTime = Math.floor(new Date(game.gameDate).getTime() / 1000); // Convert to Unix epoch time + const now = Math.floor(Date.now() / 1000); // Current Unix epoch time + const oneMinute = 60; // One minute in seconds + const mintDuration = startTime - (now + oneMinute); + const refundDuration = 3600; // 1 hour in seconds + if (now >= startTime - refundDuration) { + console.log('Refund time has passed'); + } + const updatedTiers = [ + { + ...tier, + name: awayTeam, + }, + { + ...tier, + name: homeTeam, + }, + ]; + + const updatedProject: DefifaLaunchProjectData = { + ...project, + name: `${awayTeam} @ ${homeTeam} on ${game?.gameDate}`, + start: startTime, + mintDuration: mintDuration, + refundDuration: refundDuration, + tiers: updatedTiers, + }; + + setProject(updatedProject); + + try { + createTournament(); // Call createTournament function to trigger game creation + } catch (error) { + console.error('Failed to create game:', error); + } + }; + + return ( +
+ {loading ? ( +

Loading...

+ ) : ( + + + + + + + + {/* Add more table header columns as needed */} + + + + {tableData?.map((games, index) => ( + + + + + + {/* Render additional table cells based on your API response */} + + ))} + +
CreateFirst PitchAwayHome
+ handleCheckboxClick(event, games, index)} + /> + + {new Date(games.gameDate).toLocaleString()} + + {games.teams?.away.team.name} + + {games.teams?.home.team.name} +
+ )} +
+ ); +}; + +export default MlbCreate; \ No newline at end of file diff --git a/src/components/Mlb/index.tsx b/src/components/Mlb/index.tsx new file mode 100644 index 00000000..0cd9fadc --- /dev/null +++ b/src/components/Mlb/index.tsx @@ -0,0 +1,15 @@ +import Container from "components/layout/Container"; +import Navbar from "../layout/Navbar"; +import MlbCreate from "./Create"; + +const MlbWrapper = () => { + return ( + + + + + + ); +}; + +export default MlbWrapper; diff --git a/src/hooks/read/AllMlbGames.ts b/src/hooks/read/AllMlbGames.ts new file mode 100644 index 00000000..b47e4f68 --- /dev/null +++ b/src/hooks/read/AllMlbGames.ts @@ -0,0 +1,62 @@ +// useTableData.js + +import React, { useState, useEffect } from 'react'; + +const useScheduleData = () => { + const [tableData, setTableData] = useState([]); + const [loading, setLoading] = useState(true); + + useEffect(() => { + // Fetch API data here + const fetchData = async () => { + try { + // Get the current date + const currentDate = new Date(); + + // Increment the current date by 1 day + const nextDate = new Date(currentDate); + nextDate.setDate(currentDate.getDate() + 1); + + // Format the dates as strings in 'YYYY-MM-DD' format + const startDate = formatDate(currentDate); + const endDate = formatDate(nextDate); + console.log(startDate); + console.log(endDate); + // Make API request and retrieve data for the next day + const response = await fetch(`https://statsapi.mlb.com/api/v1/schedule/games/?sportId=1&startDate=${startDate}&endDate=${endDate}`); + const data = await response.json(); + + // Flatten the array of games from all dates + const games = data.dates.flatMap(date => date.games); + const filteredGames = games.filter(game => { + const gameDate = new Date(game.gameDate); + return gameDate.getTime() >= currentDate.getTime() + 3600000; // 1 hour in milliseconds + }); + + // Update tableData state with filtered games + setTableData(filteredGames); + setLoading(false); + } catch (error) { + console.error('Error fetching table data:', error); + } + }; + + fetchData(); + }, []); + + const resetTableData = () => { + setTableData([]); + setLoading(true); + }; + console.log('this is table date ',tableData); + return { tableData, loading, resetTableData }; +}; +// Helper function to format date as 'YYYY-MM-DD' +const formatDate = (date) => { + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); + const day = String(date.getDate()).padStart(2, '0'); + return `${year}-${month}-${day}`; + }; + +export default useScheduleData; diff --git a/src/pages/404.js b/src/pages/404.js new file mode 100644 index 00000000..f241d8bd --- /dev/null +++ b/src/pages/404.js @@ -0,0 +1,21 @@ +import Link from 'next/link'; + +const Custom404 = () => { + return ( +
+ + + 404 Error + + +

Go back to the homepage

+ +
+ ); +}; + +export default Custom404; diff --git a/src/pages/mlb/index.tsx b/src/pages/mlb/index.tsx new file mode 100644 index 00000000..1ed6edf8 --- /dev/null +++ b/src/pages/mlb/index.tsx @@ -0,0 +1,8 @@ +import { NextPage } from "next"; +import MlbWrapper from "../../components/Mlb"; + +const Mlb: NextPage = () => { + return ; +}; + +export default Mlb;