diff --git a/web-devtools/.eslintrc.json b/web-devtools/.eslintrc.json index a0a6203f8..c443d928b 100644 --- a/web-devtools/.eslintrc.json +++ b/web-devtools/.eslintrc.json @@ -14,6 +14,7 @@ } }, "extends": [ + "next/core-web-vitals", "eslint:recommended", "plugin:react/recommended", "plugin:react-hooks/recommended", @@ -42,16 +43,16 @@ "version": "^16.12.0" }, "import/resolver": { - "parcel": { - "rootDir": "src", + "typescript": { + "alwaysTryTypes": true, + "project": "./tsconfig.json" + }, + "node": { "extensions": [ ".js", ".jsx", ".ts", - ".tsx", - ".svg", - ".png", - ".jpeg" + ".tsx" ] } } diff --git a/web-devtools/.gitignore b/web-devtools/.gitignore index 0d31351f2..bf2363915 100644 --- a/web-devtools/.gitignore +++ b/web-devtools/.gitignore @@ -1,3 +1,4 @@ +# dependencies /.yarn/* !/.yarn/versions !/.yarn/plugins @@ -6,14 +7,15 @@ /.pnp.* node_modules -# Parcel -.parcel-cache +# next.js +/.next/ +/out/ development build dist -parcel-bundle-reports # misc +*.pem .eslintcache .DS_Store .env @@ -35,3 +37,10 @@ generatedNetlifyInfo.json npm-debug.log* yarn-debug.log* yarn-error.log* + +# testing +/coverage + +# typescript +*.tsbuildinfo +next-env.d.ts \ No newline at end of file diff --git a/web-devtools/global.d.ts b/web-devtools/global.d.ts new file mode 100644 index 000000000..09cc2ad78 --- /dev/null +++ b/web-devtools/global.d.ts @@ -0,0 +1,6 @@ +import { DefaultTheme } from "styled-components"; +import { theme } from "styles/Theme"; +declare module "styled-components" { + type Theme = typeof theme; + export interface DefaultTheme extends Theme {} +} diff --git a/web-devtools/next.config.mjs b/web-devtools/next.config.mjs new file mode 100644 index 000000000..bf3376f66 --- /dev/null +++ b/web-devtools/next.config.mjs @@ -0,0 +1,33 @@ +/** @type {import('next').NextConfig} */ +const nextConfig = { + compiler: { + styledComponents: true, + }, + webpack(config) { + // Grab the existing rule that handles SVG imports + const fileLoaderRule = config.module.rules.find((rule) => rule.test?.test?.(".svg")); + + config.module.rules.push( + // Reapply the existing rule, but only for svg imports ending in ?url + { + ...fileLoaderRule, + test: /\.svg$/i, + resourceQuery: /url/, // *.svg?url + }, + // Convert all other *.svg imports to React components + { + test: /\.svg$/i, + issuer: fileLoaderRule.issuer, + resourceQuery: { not: [...fileLoaderRule.resourceQuery.not, /url/] }, // exclude if *.svg?url + use: ["@svgr/webpack"], + } + ); + + // Modify the file loader rule to ignore *.svg, since we have it handled now. + fileLoaderRule.exclude = /\.svg$/i; + + return config; + }, +}; + +export default nextConfig; diff --git a/web-devtools/package.json b/web-devtools/package.json index 43f5314c8..02416fa88 100644 --- a/web-devtools/package.json +++ b/web-devtools/package.json @@ -8,18 +8,30 @@ "license": "MIT", "packageManager": "yarn@4.0.2+sha256.825003a0f561ad09a3b1ac4a3b3ea6207af2796d54f62a9420520915721f5186", "volta": { - "node": "20.11.0" + "node": "20.11.0", + "yarn": "4.3.1" }, "scripts": { - "hi": "echo hello world" + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "next lint" }, "prettier": "@kleros/kleros-v2-prettier-config", "devDependencies": { + "@svgr/webpack": "^8.1.0", + "@types/node": "^20", + "@types/react": "18.2.0", + "@types/react-dom": "^18.2.18", "typescript": "^5.3.3" }, "dependencies": { "@kleros/kleros-sdk": "workspace:^", "@kleros/ui-components-library": "^2.10.0", + "next": "14.2.4", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "styled-components": "^5.3.11", "viem": "^1.21.4", "wagmi": "^1.4.13" } diff --git a/web-devtools/src/app/(main)/ChangeRuler.tsx b/web-devtools/src/app/(main)/ChangeRuler.tsx new file mode 100644 index 000000000..a96f9da76 --- /dev/null +++ b/web-devtools/src/app/(main)/ChangeRuler.tsx @@ -0,0 +1,51 @@ +import React from "react"; +import styled from "styled-components"; + +import { Field } from "@kleros/ui-components-library"; + +import LightButton from "components/LightButton"; + +const Container = styled.div` + border: ${({ theme }) => theme.klerosUIComponentsPrimaryBlue} 1px solid; + border-radius: 4px; + padding: 16px; +`; + +const RulingSettings = styled.div` + display: flex; + flex-direction: column; + gap: 8px; + margin: 16px 0; +`; +const FieldContainer = styled.div` + display: flex; + align-items: center; + width: fit-content; + height: fit-content; + padding-left: 8px; + gap: 8px; + font-size: 14px; + border-radius: 4px; + border: ${({ theme }) => theme.klerosUIComponentsStroke} 1px solid; + color: ${({ theme }) => theme.klerosUIComponentsPrimaryText}; +`; + +const ChangeRuler: React.FC = () => { + return ( +
+

Change Ruler

+ + + + + + + address + + + +
+ ); +}; + +export default ChangeRuler; diff --git a/web-devtools/src/app/(main)/RulingModes.tsx b/web-devtools/src/app/(main)/RulingModes.tsx new file mode 100644 index 000000000..27e4deb0e --- /dev/null +++ b/web-devtools/src/app/(main)/RulingModes.tsx @@ -0,0 +1,74 @@ +import React, { useState } from "react"; +import styled from "styled-components"; + +import { Checkbox, Field } from "@kleros/ui-components-library"; + +import LightButton from "components/LightButton"; + +const Container = styled.div` + display: flex; + flex-wrap: wrap; + gap: 8px; + margin: 16px 0; + border: ${({ theme }) => theme.klerosUIComponentsPrimaryBlue} 1px solid; + border-radius: 4px; + padding: 16px; +`; +const RulingSettings = styled.div` + display: flex; + flex-direction: column; + gap: 8px; + margin: 16px 0; +`; +const FieldContainer = styled.div` + display: flex; + align-items: center; + width: fit-content; + height: fit-content; + padding-left: 8px; + gap: 8px; + font-size: 14px; + border-radius: 4px; + border: ${({ theme }) => theme.klerosUIComponentsStroke} 1px solid; + color: ${({ theme }) => theme.klerosUIComponentsPrimaryText}; +`; + +const RulingModes: React.FC = () => { + const [tie, setTie] = useState(false); + const [overriden, setOverriden] = useState(false); + + return ( +
+

Ruling Mode

+ + + + + ruling + + + + + + + ruling + + + setTie((old) => !old)} /> + + + + setOverriden((old) => !old)} /> + + + + + + + + +
+ ); +}; + +export default RulingModes; diff --git a/web-devtools/src/app/(main)/page.tsx b/web-devtools/src/app/(main)/page.tsx new file mode 100644 index 000000000..e2b62b2ad --- /dev/null +++ b/web-devtools/src/app/(main)/page.tsx @@ -0,0 +1,62 @@ +"use client"; +import React from "react"; +import styled from "styled-components"; + +import { DropdownCascader, Field } from "@kleros/ui-components-library"; + +import { SelectArbitrable } from "utils/dummyData"; + +import ChangeRuler from "./ChangeRuler"; +import RulingModes from "./RulingModes"; + +const Container = styled.div` + min-height: calc(100vh - 160px); + display: flex; + flex-direction: column; + margin: 16px 32px; + align-items: center; +`; +const Arbitrables = styled.div` + display: flex; + flex-wrap: wrap; + gap: 8px; + margin: 16px 0; +`; + +const SettingsPane = styled.div` + display: flex; + flex-wrap: wrap; + gap: 16px; + margin: 16px 0; +`; + +const Home: React.FC = () => { + return ( + +

Ruler

+ + +
+ + { + //todo; + }} + items={SelectArbitrable} + /> +
+
+ + +
+
+ + + + + +
+ ); +}; +export default Home; diff --git a/web-devtools/src/app/favicon.ico b/web-devtools/src/app/favicon.ico new file mode 100644 index 000000000..16a8426ee Binary files /dev/null and b/web-devtools/src/app/favicon.ico differ diff --git a/web-devtools/src/app/layout.tsx b/web-devtools/src/app/layout.tsx new file mode 100644 index 000000000..603954839 --- /dev/null +++ b/web-devtools/src/app/layout.tsx @@ -0,0 +1,34 @@ +import React from "react"; + +import type { Metadata } from "next"; +import { Open_Sans } from "next/font/google"; + +import StyledComponentsProvider from "context/StyledComponentsProvider"; +import StyledComponentsRegistry from "context/StyledComponentsRegistry"; + +import Footer from "layout/Footer"; +import Header from "layout/Header"; + +const font = Open_Sans({ subsets: ["latin"] }); + +export const metadata: Metadata = { + title: "Dev Tools", +}; + +const RootLayout = ({ children }: Readonly<{ children: React.ReactNode }>) => { + return ( + + + + +
+ {children} +