/ frontend / app / content.tsx
content.tsx
  1  'use client';
  2  import {ConnectButton} from '@rainbow-me/rainbowkit';
  3  
  4  import {useAccount} from 'wagmi';
  5  import { useReadContracts, useConfig } from 'wagmi'
  6  
  7  import abi from "../bloxy-abi.json";
  8  import { useEffect, useState } from 'react';
  9  import { readContract } from '@wagmi/core'
 10  
 11  import { useWriteContract } from 'wagmi'
 12  
 13  
 14  
 15  console.log(abi)
 16  
 17  const contractAddr = "0xfF780774c0eE8f3D9C4611e9c221Aedc30503220";
 18  const DOMAIN = "bloxy.one"
 19  
 20  const Content = () => {
 21      const [tokenIds, setTokenIds] = useState<number[]>([])
 22      const [paymentToken, setPaymentToken] = useState<number>(0)
 23      const [name, setName] = useState<string>()
 24      const [domain, setDomain] = useState<string>()
 25      const [target, setTarget] = useState<string>()
 26  
 27  
 28      const config = useConfig()
 29      const {isConnected, address} = useAccount();
 30      const { data: balance } = useReadContracts({ contracts: [
 31              {
 32                  abi,
 33                  address: contractAddr,
 34                  functionName: 'balanceOf',
 35                  args: [address],
 36              },
 37          ]})
 38  
 39      const [entries, setEntries] = useState([])
 40  
 41      const { writeContract } = useWriteContract()
 42  
 43  
 44      useEffect(() => {
 45      if (!balance) return
 46      
 47      console.log(balance[0].result)
 48      const b = parseInt(balance && balance[0].result > 0 && balance[0].result.toString())
 49      for (var i=0; i<b; i++) {
 50          console.log("Querying...")
 51          readContract(config, {
 52              abi,
 53              address: contractAddr,
 54              functionName: 'tokenOfOwnerByIndex',
 55              args: [address, i],
 56              }).then((tokenId) => {
 57                  console.log(tokenId)
 58                  if (tokenId === null || tokenId === undefined) return
 59                  readContract(config, {
 60                      abi,
 61                      address: contractAddr,
 62                      functionName: 'entries',
 63                      args: [tokenId.toString()],
 64                      }).then(entry => {
 65                      console.log(entry)
 66  
 67                      if (!entry) return
 68                      const e = {tokenId: parseInt(tokenId.toString()) ,name: entry[0], domain: entry[1], target: entry[2], expiry: parseInt(entry[3].toString())*1000}
 69                      console.log(e)
 70                      setEntries(entries => [...entries, e])
 71                  })
 72              })
 73      }
 74  
 75      }, [balance])
 76  
 77      const createEntry = async () => {
 78          const entry = {name: name, domain: domain, target: target, expiry: BigInt(0)}
 79          var value = BigInt(0)
 80  
 81          console.log(value)
 82  
 83          if (paymentToken == 0) {
 84              console.log("Here")
 85              const result = await readContract(config, {
 86                  abi,
 87                  address: contractAddr,
 88                  functionName: 'getPriceETH',
 89                  args: [60*60*24*30],
 90                  })
 91  
 92              console.log(result)
 93              value = (BigInt(result && result.toString()) * BigInt(150)) / BigInt(100)
 94              console.log(value)
 95          } 
 96  
 97          writeContract({
 98              abi,
 99              address: contractAddr,
100              functionName: "newEntry",
101              args: [entry],
102              value: value,
103          })
104      }
105  
106      const deleteEntry = (tokenId: number) => {
107          writeContract({
108              abi,
109              address: contractAddr,
110              functionName: "removeEntry",
111              args: [tokenId],
112          })
113      }
114  
115      return (
116          <main className="max-w-4xl m-auto space-y-7 items-center text-center">
117            <h1 className='text-4xl'>Bloxy Proxy</h1>
118            <div className="m-auto max-w-fit">
119     
120                <ConnectButton  />
121            
122            </div>
123            <div>
124              { isConnected &&
125              <div className='space-y-7'>
126                  <div>
127                      <h2 className='text-2xl'>New Entry</h2>
128                      <div>
129                          Name
130                      </div>
131                      <div>
132                          <input type="text" onChange={(e) => setName(e.target.value)} className="input-md input-primary input" />
133                      </div>
134                      <div>
135                          Domain
136                      </div>
137                      <div>
138                          <input type="text" onChange={(e) => setDomain(e.target.value)} className="input-md input-primary input" />
139                      </div>
140                      <div>
141                          Target
142                      </div>
143                      <div>
144                          <input type="text" onChange={(e) => setTarget(e.target.value)} className="input-md input-primary input" />
145                      </div>
146                      <div>
147                          Pay in
148                      </div>
149                      <div className='max-w-32 m-auto'>
150                          <div>
151                              <label className="label cursor-pointer">
152                                  <span className="label-text">ETH</span>
153                                  <input type="radio" name="paymentToken" checked={paymentToken == 0} onClick={() => setPaymentToken(0)} className='radio radio-primary' />
154                              </label>
155                          </div>
156                          <div>
157                              <label className="label cursor-pointer">
158                                  <span className="label-text">USDC</span>
159                                  <input type="radio" name="paymentToken"  checked={paymentToken == 1} onClick={() => setPaymentToken(1)} className='radio radio-primary' />
160                              </label>
161                          </div>
162                      </div>
163                      <div>
164                          <button className='btn' onClick={() => createEntry()}>Submit</button>
165                      </div>
166                  </div>
167                  <div>
168                      <div className='text-2xl'>Your Entries</div>
169  
170                      {entries.length == 0 ?
171                      <div className='loading loading-spinner'></div>
172                      :
173                      <table className='table table-zebra w-full'>
174                          <thead>
175                              <tr>
176                                  <th>Name</th>
177                                  <th>Domain</th>
178                                  <th>Target</th>
179                                  <th>Expiry</th>
180                              </tr>
181                          </thead>
182                          <tbody>
183                          {entries.map((entry) => 
184                              <tr id={entry.name}>
185                                  <td><a href={`https://${entry.name}.${DOMAIN}`} target='_blank' className='link'>{entry?.name}</a></td>
186                                  <td>{entry?.domain}</td>
187                                  <td>{entry?.target}</td>
188                                  <td>{entry.expiry == 0? "---" : (new Date(entry?.expiry)).toLocaleString()}</td>
189                                  <td><button className='btn btn-sm btn-disabled btn-primary'>Edit</button></td>
190                                  <td>{entry.expiry != 0 &&<button className='btn btn-sm  btn-primary'>Extend</button>}</td>
191                                  <td><button className='btn btn-sm  btn-secondary' onClick={() => deleteEntry(entry.tokenId)}>Delete</button></td>
192                              </tr>
193                          )}
194                          </tbody>
195                      </table>
196                      }
197                  </div>
198              </div>
199              }
200            </div>
201          </main>
202      )
203  }
204  
205  export default Content