From ec8014f0a02b3d83c7acdfb07227eb3968bbb763 Mon Sep 17 00:00:00 2001 From: alcercu <333aleix333@gmail.com> Date: Fri, 4 Aug 2023 18:07:36 +0200 Subject: [PATCH] feat(web): add dispute template previewer --- web/src/app.tsx | 2 + web/src/components/ReactMarkdown.tsx | 15 +++ web/src/pages/DisputeTemplateView.tsx | 157 ++++++++++++++++++++++++++ 3 files changed, 174 insertions(+) create mode 100644 web/src/components/ReactMarkdown.tsx create mode 100644 web/src/pages/DisputeTemplateView.tsx diff --git a/web/src/app.tsx b/web/src/app.tsx index b99148d1f..a18340484 100644 --- a/web/src/app.tsx +++ b/web/src/app.tsx @@ -11,6 +11,7 @@ import Home from "./pages/Home"; import Cases from "./pages/Cases"; import Dashboard from "./pages/Dashboard"; import Courts from "./pages/Courts"; +import DisputeTemplateView from "./pages/DisputeTemplateView"; const App: React.FC = () => { return ( @@ -24,6 +25,7 @@ const App: React.FC = () => { } /> } /> } /> + } /> Justice not found here ¯\_( ͡° ͜ʖ ͡°)_/¯} /> diff --git a/web/src/components/ReactMarkdown.tsx b/web/src/components/ReactMarkdown.tsx new file mode 100644 index 000000000..71b00cedd --- /dev/null +++ b/web/src/components/ReactMarkdown.tsx @@ -0,0 +1,15 @@ +import React from "react"; +import styled from "styled-components"; +import Reactmkdwn from "react-markdown"; + +const StyledMarkdown = styled(Reactmkdwn)` + font-size: 16px; + *, + ** { + font-size: 16px; + } +`; + +const ReactMarkdown: React.FC<{ children: string }> = ({ children }) => {children}; + +export default ReactMarkdown; diff --git a/web/src/pages/DisputeTemplateView.tsx b/web/src/pages/DisputeTemplateView.tsx new file mode 100644 index 000000000..0376af97b --- /dev/null +++ b/web/src/pages/DisputeTemplateView.tsx @@ -0,0 +1,157 @@ +import React, { useMemo, useState } from "react"; +import styled from "styled-components"; +import Skeleton from "react-loading-skeleton"; +import { Textarea } from "@kleros/ui-components-library"; +import PolicyIcon from "svgs/icons/policy.svg"; +import ReactMarkdown from "components/ReactMarkdown"; +import { isUndefined } from "utils/index"; + +const Wrapper = styled.div` + min-height: calc(100vh - 144px); + margin: 24px; + display: flex; + gap: 12px; +`; + +const StyledTextArea = styled(Textarea)` + width: 50%; + height: calc(100vh - 300px); +`; + +const DisputeTemplateView: React.FC = () => { + const [disputeTemplate, setDisputeTemplate] = useState(""); + const [errorMsg, setErrorMessage] = useState(""); + const parsedDisputeTemplate = useMemo(() => { + try { + const parsed = JSON.parse(disputeTemplate); + setErrorMessage(""); + return parsed; + } catch (e) { + setErrorMessage((e as SyntaxError).message); + return undefined; + } + }, [disputeTemplate]); + const isThereInput = useMemo(() => disputeTemplate !== "", [disputeTemplate]); + return ( + + setDisputeTemplate(e.target.value)} + placeholder="Enter dispute template" + variant={isThereInput && errorMsg !== "" ? "error" : ""} + message={isThereInput ? errorMsg : ""} + /> + + + ); +}; + +const Container = styled.div` + width: 50%; + height: auto; + display: flex; + flex-direction: column; + gap: 16px; + + > h1 { + margin: 0; + } + + > hr { + width: 100%; + } +`; + +const QuestionAndDescription = styled.div` + display: flex; + flex-direction: column; + > * { + margin: 0px; + } +`; + +const VotingOptions = styled(QuestionAndDescription)` + display: flex; + flex-direction: column; + > span { + margin: 0px; + display: flex; + gap: 8px; + } +`; + +const ShadeArea = styled.div` + width: 100%; + padding: 16px; + margin-top: 16px; + background-color: ${({ theme }) => theme.mediumBlue}; + > p { + margin-top: 0; + } +`; + +const StyledA = styled.a` + display: flex; + align-items: center; + gap: 4px; + > svg { + width: 16px; + fill: ${({ theme }) => theme.primaryBlue}; + } +`; + +const LinkContainer = styled.div` + display: flex; + justify-content: space-between; +`; + +const Overview: React.FC<{ disputeTemplate: any }> = ({ disputeTemplate }) => { + return ( + <> + +

+ {isUndefined(disputeTemplate) ? ( + + ) : ( + disputeTemplate?.title ?? "The dispute's template is not correct please vote refuse to arbitrate" + )} +

+ + {disputeTemplate?.question} +

{disputeTemplate?.description}

+
+ {disputeTemplate?.frontendUrl && ( + + Go to arbitrable + + )} + + {disputeTemplate &&

Voting Options

} + {disputeTemplate?.answers?.map((answer: { title: string; description: string }, i: number) => ( + + Option {i + 1}: + + + ))} +
+ +

Make sure you understand the Policies

+ + {disputeTemplate?.policyURI && ( + + + Dispute Policy + + )} + +
+
+ + ); +}; + +export default DisputeTemplateView;