Skip to content
16 changes: 3 additions & 13 deletions web/src/components/Verdict/Answer.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,8 @@
import React from "react";
import styled from "styled-components";

import { Answer } from "@kleros/kleros-sdk/src/dataMappings/utils/disputeDetailsTypes";

import { AnswerDescription, AnswerTitle, AnswerTitleAndDescription } from "../DisputePreview/DisputeContext";

const Container = styled.div`
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
gap: 6px;
`;
import { AnswerTitle, AnswerTitleAndDescription } from "../DisputePreview/DisputeContext";

interface IAnswer {
answer?: Answer;
Expand All @@ -24,12 +15,11 @@ const AnswerDisplay: React.FC<IAnswer> = ({ answer, currentRuling }) => {
{answer ? (
<AnswerTitleAndDescription dir="auto">
<AnswerTitle>{answer.title}</AnswerTitle>
<AnswerDescription>{answer.description.trim() ? ` - ${answer.description}` : null}</AnswerDescription>
</AnswerTitleAndDescription>
) : (
<Container>
<AnswerTitleAndDescription>
{currentRuling !== 0 ? <small>Answer 0x{currentRuling}</small> : <small>Refuse to Arbitrate</small>}
</Container>
</AnswerTitleAndDescription>
)}
</>
);
Expand Down
6 changes: 3 additions & 3 deletions web/src/components/Verdict/FinalDecision.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@ const Container = styled.div`

const JuryContainer = styled.div`
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
gap: 5px 7px;
flex: 1;
flex-wrap: wrap;

h3 {
line-height: 21px;
margin-bottom: 0px;
}

> div {
flex: 1;
}
Expand Down
163 changes: 163 additions & 0 deletions web/src/pages/Courts/CourtDetails/TopSearch.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
import React, { useState, useMemo } from "react";
import styled, { css } from "styled-components";

import { useNavigate, useParams } from "react-router-dom";

import { Card, DropdownCascader, Searchbar } from "@kleros/ui-components-library";

import { isKlerosUniversity } from "src/consts";
import { isUndefined } from "utils/index";

import { useCourtTree, rootCourtToItems } from "queries/useCourtTree";

import { responsiveSize } from "styles/responsiveSize";
import { landscapeStyle } from "styles/landscapeStyle";
import { hoverShortTransitionTiming } from "styles/commonStyles";

import { StyledSkeleton } from "components/StyledSkeleton";
import StakeMaintenanceButtons from "../StakeMaintenanceButton";

const Container = styled.div`
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
gap: 8px 16px;
flex-wrap: wrap;
`;

const StyledDropdownCascader = styled(DropdownCascader)`
width: ${responsiveSize(200, 240)};
> button {
width: 100%;
}
`;

const SearchBarContainer = styled.div`
display: flex;
flex-wrap: wrap;
position: relative;
${landscapeStyle(
() => css`
flex: 1;
`
)}
`;

const StyledSearchbar = styled(Searchbar)`
width: 100%;
input {
font-size: 16px;
height: 45px;
padding-top: 0px;
padding-bottom: 0px;
}
`;

const SearchResultsContainer = styled.div`
position: absolute;
margin-top: 45px;
max-height: 400px;
border: 1px solid ${({ theme }) => theme.stroke};
width: 100%;
flex-direction: column;
border-radius: 4px;
overflow-y: auto;
z-index: 1;
background-color: ${({ theme }) => theme.whiteBackground};
`;

const StyledCard = styled(Card)<{ selected: boolean }>`
${hoverShortTransitionTiming}
height: auto;
width: 100%;
padding: ${({ selected }) => (selected ? "16px 13px" : "16px")};
cursor: pointer;
border: none;
border-left: ${({ selected, theme }) => (selected ? `3px solid ${theme.primaryBlue}` : "none")};
background-color: ${({ selected, theme }) => (selected ? theme.mediumBlue : "transparent")};

:hover {
background-color: ${({ theme }) => theme.mediumBlue};
}
`;

const CourtParentSpan = styled.span`
color: ${({ theme }) => theme.secondaryText}EE;
`;

const CourtNameSpan = styled.span`
color: ${({ theme }) => theme.primaryText};
`;

function flattenCourts(court, parent = null) {
const current = {
...court,
parentName: parent?.name ?? null,
};
const children = (court.children || []).flatMap((child) => flattenCourts(child, current));
return [current, ...children];
}

const TopSearch: React.FC = () => {
const { data } = useCourtTree();
const navigate = useNavigate();
const { id: currentCourtId } = useParams();
const items = useMemo(() => !isUndefined(data) && [rootCourtToItems(data.court)], [data]);
const isUniversity = isKlerosUniversity();
const [search, setSearch] = useState("");

const filteredCourts = useMemo(() => {
if (!data?.court) return [];
const courts = flattenCourts(data.court).filter((c) => c.name.toLowerCase().includes(search.toLowerCase()));
const selectedCourt = courts.find((c) => c.id === currentCourtId);
if (!selectedCourt) return courts;

return [selectedCourt, ...courts.filter((c) => c.id !== currentCourtId)];
}, [data, search, currentCourtId]);

return (
<Container>
{items ? (
<>
<StyledDropdownCascader
items={items}
onSelect={(path) => navigate(path.toString())}
placeholder="Select Court"
/>
<SearchBarContainer>
<StyledSearchbar
dir="auto"
type="text"
placeholder="Search"
value={search}
onChange={(e) => setSearch(e.target.value)}
/>
{search && filteredCourts.length > 0 && (
<SearchResultsContainer>
{filteredCourts.map((court) => (
<StyledCard
key={court.id}
selected={court.id === currentCourtId}
onClick={() => {
navigate(`/courts/${court.id}`);
setSearch("");
}}
>
{court.parentName && <CourtParentSpan>{court.parentName} / </CourtParentSpan>}
<CourtNameSpan>{court.name}</CourtNameSpan>
</StyledCard>
))}
</SearchResultsContainer>
)}
</SearchBarContainer>
</>
) : (
<StyledSkeleton width={240} height={42} />
)}
{isUniversity ? null : <StakeMaintenanceButtons />}
</Container>
);
};

export default TopSearch;
2 changes: 2 additions & 0 deletions web/src/pages/Courts/CourtDetails/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { Divider } from "components/Divider";
import Description from "./Description";
import StakePanel from "./StakePanel";
import Stats from "./Stats";
import TopSearch from "./TopSearch";

const Container = styled.div``;

Expand Down Expand Up @@ -113,6 +114,7 @@ const CourtDetails: React.FC = () => {

return (
<Container>
<TopSearch />
<StyledCard>
<CourtHeader>
<CourtInfo>
Expand Down
54 changes: 0 additions & 54 deletions web/src/pages/Courts/TopSearch.tsx

This file was deleted.

2 changes: 0 additions & 2 deletions web/src/pages/Courts/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { responsiveSize } from "styles/responsiveSize";
import { Routes, Route, Navigate } from "react-router-dom";

import CourtDetails from "./CourtDetails";
import TopSearch from "./TopSearch";

const Container = styled.div`
width: 100%;
Expand All @@ -26,7 +25,6 @@ const Container = styled.div`
const Courts: React.FC = () => {
return (
<Container>
<TopSearch />
<Routes>
<Route path="/:id/*" element={<CourtDetails />} />
<Route path="*" element={<Navigate to="1" replace />} />
Expand Down
Loading