diff --git a/.eslintrc b/.eslintrc index 98352ca..d1179aa 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,11 +1,13 @@ { + "parser": "@typescript-eslint/parser", "env": { "browser": true, "es2021": true }, "extends": [ "plugin:react/recommended", - "standard", + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended", "prettier", "next/core-web-vitals" ], @@ -16,7 +18,7 @@ "ecmaVersion": 12, "sourceType": "module" }, - "plugins": ["react"], + "plugins": ["react","@typescript-eslint"], "rules": { "@next/next/no-img-element": "off" } diff --git a/components/InputFieldError.tsx b/components/InputFieldError.tsx new file mode 100644 index 0000000..6cc8bb5 --- /dev/null +++ b/components/InputFieldError.tsx @@ -0,0 +1,9 @@ + +interface InputFieldErrorProps { + message?: string +} + +export const InputFieldError = ({ message }: InputFieldErrorProps) => { + if (!message) return null + return

{message}

+} diff --git a/next-env.d.ts b/next-env.d.ts new file mode 100644 index 0000000..4f11a03 --- /dev/null +++ b/next-env.d.ts @@ -0,0 +1,5 @@ +/// +/// + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/basic-features/typescript for more information. diff --git a/package.json b/package.json index 980070b..161fad3 100644 --- a/package.json +++ b/package.json @@ -6,11 +6,14 @@ "dev": "next dev", "build": "next build", "start": "export PORT=4006 next start", - "lint": "next lint" + "lint": "next lint --fix" }, "dependencies": { "@headlessui/react": "^1.4.2", "@heroicons/react": "^1.0.5", + "@hookform/resolvers": "^2.8.5", + "@openzeppelin/contracts": "^4.4.1", + "@react-hookz/web": "^12.0.4", "@textile/eth-storage": "^1.0.0", "axios": "^0.24.0", "ethers": "^5.5.2", @@ -22,16 +25,27 @@ "nft.storage": "^5.2.0", "react": "^17.0.2", "react-dom": "^17.0.2", + "react-hook-form": "^7.22.5", "react-markdown": "^7.1.1", - "web3modal": "^1.9.4" + "web3modal": "^1.9.4", + "yup": "^0.32.11" }, "devDependencies": { + "@nomiclabs/hardhat-ethers": "^2.0.3", + "@nomiclabs/hardhat-waffle": "^2.0.1", + "@types/react": "^17.0.38", + "@typescript-eslint/eslint-plugin": "^5.8.1", + "@typescript-eslint/parser": "^5.8.1", "autoprefixer": "^10.4.0", - "eslint": "^7.32.0", + "chai": "^4.3.4", + "eslint": "^8.5.0", "eslint-config-next": "^12.0.7", "eslint-config-prettier": "^8.3.0", + "ethereum-waffle": "^3.4.0", + "hardhat": "^2.8.0", "postcss": "^8.4.5", "prettier": "2.5.1", - "tailwindcss": "^3.0.7" + "tailwindcss": "^3.0.7", + "typescript": "^4.5.4" } } diff --git a/pages/create.js b/pages/create.js deleted file mode 100644 index 50bc3cd..0000000 --- a/pages/create.js +++ /dev/null @@ -1,260 +0,0 @@ -import { useState } from "react" -import { ethers } from "ethers" -import { create as ipfsHttpClient } from "ipfs-http-client" -import { useRouter } from "next/router" -import axios from "axios" -import { NFTStorage } from "nft.storage" - -const client = ipfsHttpClient("https://ipfs.infura.io:5001/api/v0") -import { nftaddress, nftmarketaddress } from "../config" - -import NFT from "../artifacts/contracts/NFT.sol/NFT.json" -import Market from "../artifacts/contracts/Market.sol/NFTMarket.json" - -let ethAccount -export default function CreateItem() { - const [publishstate, setPublishstate] = useState("") - const [fileUrl, setFileUrl] = useState(null) - const [afile, setAFile] = useState(null) - const [submitted, setSubmitted] = useState(false) - - const [formInput, updateFormInput] = useState({ - price: "", - name: "", - description: "", - s_tags: "", - names: "", - }) - const router = useRouter() - console.log(router) - if (router.pathname == "/create") { - if (typeof document !== "undefined") { - var els = document.getElementsByClassName("_nav") - Array.prototype.forEach.call(els, function (el) { - el.classList.remove("current") - }) - document.getElementById("_create").classList.add("current") - } - } - - if (typeof window !== "undefined") { - ethAccount = localStorage.getItem("ethAccount") - if (!ethAccount) { - alert("No ETH Account, Please login") - router.push("/articles-all") - } - } - console.log(ethAccount) - - async function onChange(e) { - const file = e.target.files[0] - console.log(file) - console.log("file will be uploaded") - try { - const added = await client.add(file, { - progress: (prog) => console.log(`received: ${prog}`), - }) - alert("file is uploaded!") - const url = `https://ipfs.infura.io/ipfs/${added.path}` - console.log(url) - console.log(added) // added.size file.size - setAFile(file) // file.name file.type "image/png" - setFileUrl(url) - } catch (error) { - console.log("Error uploading file: ", error) - alert("Error uploading file: ", error) - } - } - async function PublishIt(e) { - if (submitted) { - console.log("already submitted") - return - } - setSubmitted(true) - e.preventDefault() - console.log("submitted!") - setPublishstate("ing...") - const { name, description, s_tags, names } = formInput - if (!afile) { - alert("Please upload FEATURED IMAGE") - setPublishstate("") - setSubmitted(false) - return - } - const _filename = afile.name.split(".") - console.log(afile.type, _filename[_filename.length - 1]) - const filetype = afile.type - const filesize = afile.size - const filename = afile.name - if (!name) { - alert("Title is not optional") - setPublishstate("") - setSubmitted(false) - return - } - if (!description) { - alert("Content is not optional") - setPublishstate("") - setSubmitted(false) - return - } - if (!s_tags) { - alert("Tags is not optional") - setPublishstate("") - setSubmitted(false) - return - } - if (!fileUrl) { - alert("Feature Image is not optional") - setPublishstate("") - setSubmitted(false) - return - } - if (!names) { - alert("Authors Name is not optional") - setPublishstate("") - setSubmitted(false) - return - } - if (!ethAccount) { - alert("No ETH Account, Please login") - setPublishstate("") - setSubmitted(false) - return - } - /* first, upload metadata to IPFS */ - const license = "CC-BY-SA" - const license_url = "https://creativecommons.org/licenses/by-sa/4.0/" - const tags = s_tags.split(" ") - const authors = [ - { - name: names, - wallet: { - eth: ethAccount, - }, - }, - ] - const data = JSON.stringify({ - name, - description, - image: fileUrl, - license, - license_url, - filesize, - filename, - filetype, - tags, - authors, - }) - - // const endpoint = 'https://api.nft.storage' // the default - const API_TOKEN = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJnaXRodWJ8MTQ3Mjg1MCIsImlzcyI6Im5mdC1zdG9yYWdlIiwiaWF0IjoxNjE4ODQ0ODAwOTgzLCJuYW1lIjoiZGVmYXVsdCJ9.bdDjCtOaANp49ysENB4-4xpVrhDRbdeqV39t5aVYsjo" // your API key from https://nft.storage/manage - try { - // const store = new NFTStorage({ endpoint, token }) - const client = new NFTStorage({ token: API_TOKEN }) - const cid = await client.storeBlob(new Blob([data])) - const status = await client.status(cid) - console.log(cid) - console.log(status) - } catch (error) { - console.log("Error uploading to nft.storage: ", error) - } - - try { - const added = await client.add(data) - console.log(added) - const url = `https://ipfs.infura.io/ipfs/${added.path}` - // We also store metadata in Dweb Search - console.log(s_tags) - console.log(names) - // const dweb_search_url = `https://dweb-search-api.anwen.cc/add_meta?path=${added.path}ð=${ethAccount}&name=${name}&image=${fileUrl}&tags=${s_tags}&authors=${names}` - const dweb_search_url = `https://dweb-search-api.anwen.cc/add_meta` - console.log(dweb_search_url) - - // ?path=${added.path}ð=${ethAccount}&name=${name}&image=${fileUrl}&tags=${s_tags}&authors=${names}` - - const ret = await axios.post(dweb_search_url, { - path: added.path, - eth: ethAccount, - name: name, - image: fileUrl, - tags: s_tags, - authors: names - }) // TODO - console.log(ret) - if (ret.status == 200 && !('error' in ret.data)) { - router.push("/articles-my") - } else { - let err = ret.data['error'] - console.log(err) - alert(`Sorry! Publish failed, server error: ${err}. We're fixing. You can try later.`) - setPublishstate("") - setSubmitted(false) - return - } - /* after file is uploaded to IPFS, pass the URL to save it on Polygon */ - // createNFT(url) - } catch (error) { - console.log("Error uploading to dweb-search: ", error) - alert("Sorry! Publish failed, server error. we are fixing...") - } - } - - return ( -
-
-

Attention:

-

- - All your published data and metadata is open to public and with{" "} - CC-BY-SA{" "} - License.{" "} -

-

- - They will be on IPFS and Dweb Search Engine too. -

-

- - It’s forbidden to mint anything which doesn’t belong to you. -

- - updateFormInput({ ...formInput, name: e.target.value }) - } - /> -