Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: bunch of bug fixes, style impros, arrangement impros, refactors #1774

Merged
merged 11 commits into from
Dec 6, 2024

Conversation

kemuru
Copy link
Contributor

@kemuru kemuru commented Dec 6, 2024

PR-Codex overview

This PR focuses on enhancing the UI components and functionality of the courts and disputes sections in the application. It includes styling adjustments, refactoring components, and improving user feedback.

Detailed summary

  • Updated gap values in various styled components.
  • Changed error message in routing from "Justice not found here" to "Page not found."
  • Refactored SimulatorPopup to Simulator with adjustments in props and calculations.
  • Improved styling for buttons and links in the navigation bar.
  • Added black color to the theme.
  • Enhanced AnswerDisplay component with better layout and styling.
  • Introduced unbeautifyStatNumber function for number formatting.
  • Updated Stats component to include subtext with dynamic values.
  • Modified Policies component layout for better presentation.
  • Cleaned up code by removing unused variables and imports.

✨ Ask PR-Codex anything about this PR by commenting with /codex {your question}

Summary by CodeRabbit

Release Notes

  • New Features

    • Enhanced user experience with clearer error messages for undefined routes.
    • Introduced a new styled component for displaying "No cases found."
    • Added new statistics for "PNK for 1 Vote" with tooltips for user guidance.
    • Added a new black color property to both light and dark themes.
  • Improvements

    • Simplified layout and styling for various components, improving visual organization.
    • Enhanced mobile navigation support across several components.
    • Added functionality for conditional rendering in the CourtDetails page to redirect users when data is missing.
    • Introduced a function for converting formatted numbers back to numeric form.
    • Improved the presentation of voting options and dispute details.
  • Bug Fixes

    • Improved routing logic for handling missing data in the CourtDetails page.
  • Style

    • Adjusted margins and gaps for better layout consistency.
  • Chores

    • Streamlined code by removing unused imports and unnecessary complexity in components.

Copy link
Contributor

coderabbitai bot commented Dec 6, 2024

Walkthrough

The changes in this pull request involve updates to various components across the application, focusing on enhancing user experience and styling. Key modifications include simplifying fallback messages in routing, introducing new styled components, and refining layout structures. Additionally, utility functions for number formatting have been added, and several components have undergone structural changes to improve clarity and consistency in presentation.

Changes

File Path Change Summary
web/src/app.tsx Updated fallback message for catch-all route from humorous to simple "Page not found".
web/src/components/CasesDisplay/index.tsx Introduced StyledLabel for "No cases found" message; modified props handling for dispute counts.
web/src/components/DisputePreview/Policies.tsx Renamed ShadeArea to Container, updated styling, and streamlined JSX structure.
web/src/components/DisputeView/DisputeInfo/DisputeInfoCard.tsx Removed unused imports, simplified props, and eliminated court branch field logic.
web/src/components/DisputeView/DisputeInfo/DisputeInfoList.tsx Added StyledField and truncateText function for improved field item rendering.
web/src/components/DisputeView/DisputeInfo/index.tsx Simplified court info display logic by removing dependency on isOverview.
web/src/components/Field.tsx Modified FieldContainer to enhance link styling based on props.
web/src/components/LightButton.tsx Updated StyledButton to accept isMobileNavbar prop for conditional styling.
web/src/components/Verdict/Answer.tsx Introduced Container and AnswerDescription styled components for improved layout.
web/src/components/Verdict/FinalDecision.tsx Changed layout of JuryContainer from column to row with adjusted spacing.
web/src/components/Verdict/VerdictBanner.tsx Removed responsive margin behavior, setting a fixed margin-bottom.
web/src/layout/Header/navbar/Explore.tsx Updated StyledLink to include isMobileNavbar prop for responsive styling.
web/src/layout/Header/navbar/Menu/index.tsx Added IMenu interface with isMobileNavbar prop to enhance menu adaptability.
web/src/layout/Header/navbar/index.tsx Enhanced mobile navigation support by passing isMobileNavbar prop to multiple components.
web/src/pages/Cases/CaseDetails/Overview/index.tsx Reduced gap property in Container styled component.
web/src/pages/Courts/CourtDetails/Description.tsx Modified routing logic to conditionally render or redirect based on policy?.summary.
web/src/pages/Courts/CourtDetails/StakePanel/Simulator/index.tsx Renamed interface and component for clarity, removed case-related logic.
web/src/pages/Courts/CourtDetails/StakePanel/index.tsx Updated component import and rendering to reflect renaming.
web/src/pages/Courts/CourtDetails/Stats.tsx Enhanced statistics display with new formatting functions and updated timeframedStats.
web/src/pages/Courts/CourtDetails/index.tsx Updated styling and rendering conditions for breadcrumb navigation based on item length.
web/src/styles/themes.ts Added black property to both lightTheme and darkTheme.
web/src/utils/beautifyStatNumber.ts Introduced unbeautifyStatNumber function for converting formatted strings back to numeric values.
web/src/components/DisputePreview/DisputeContext.tsx Removed StyledReactMarkDown, replaced with ReactMarkdown, and added AnswersHeader styled component.

Possibly related PRs

  • feat(web): extra statistic on homepage #1671: The changes in the main PR regarding the App component's fallback content for a catch-all route relate to the introduction of additional statistics in the homepage, which may involve similar user interface considerations.
  • feat: UX & UI impros in various places (evidence cards, voting cards, case overview, top jurors) #1754: The UX improvements in various components, including the addition of error handling and user feedback mechanisms, are related to the main PR's changes that enhance user experience through clearer messaging.
  • feat: UX improvements #1760: The introduction of the ScrollTop component across multiple pages to manage scroll behavior complements the main PR's focus on improving navigation and user experience.
  • Feat/error page #1770: The updates to error handling and the introduction of the ErrorFallback component in this PR align with the main PR's objective of enhancing user experience through better error management.

Suggested labels

Type: Bug :bug:, Type: Enhancement :sparkles:, Type: UX

Suggested reviewers

  • alcercu
  • Harman-singh-waraich

Poem

🐰 In the land of code where rabbits play,
Changes hop in, brightening the day.
Messages clearer, styles so neat,
A joyful journey, oh what a treat!
With every tweak, our app takes flight,
Hopping along, everything feels right! 🌟


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 8c2d861 and 6e5113c.

📒 Files selected for processing (2)
  • web/src/components/DisputePreview/DisputeContext.tsx (4 hunks)
  • web/src/components/Verdict/Answer.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • web/src/components/Verdict/Answer.tsx
  • web/src/components/DisputePreview/DisputeContext.tsx

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai or @coderabbitai title anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

netlify bot commented Dec 6, 2024

Deploy Preview for kleros-v2-university ready!

Name Link
🔨 Latest commit 6e5113c
🔍 Latest deploy log https://app.netlify.com/sites/kleros-v2-university/deploys/675315ebe49ccd0008ec13fc
😎 Deploy Preview https://deploy-preview-1774--kleros-v2-university.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link

netlify bot commented Dec 6, 2024

Deploy Preview for kleros-v2-testnet-devtools failed. Why did it fail? →

Name Link
🔨 Latest commit 6e5113c
🔍 Latest deploy log https://app.netlify.com/sites/kleros-v2-testnet-devtools/deploys/675315ebf074e60008e244e6

Copy link

netlify bot commented Dec 6, 2024

Deploy Preview for kleros-v2-testnet ready!

Name Link
🔨 Latest commit 6e5113c
🔍 Latest deploy log https://app.netlify.com/sites/kleros-v2-testnet/deploys/675315eb4078860008f57184
😎 Deploy Preview https://deploy-preview-1774--kleros-v2-testnet.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link

netlify bot commented Dec 6, 2024

Deploy Preview for kleros-v2-neo ready!

Name Link
🔨 Latest commit 6e5113c
🔍 Latest deploy log https://app.netlify.com/sites/kleros-v2-neo/deploys/675315ebc984cb000891e7d9
😎 Deploy Preview https://deploy-preview-1774--kleros-v2-neo.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Outside diff range and nitpick comments (19)
web/src/components/Field.tsx (2)

Line range hint 71-106: Consider these architectural improvements

  1. The boolean props (isOverview, isJurorBalance, displayAsList) could be consolidated into a variant prop using a discriminated union:
type FieldVariant = 'default' | 'overview' | 'jurorBalance' | 'list';

interface IField {
  variant?: FieldVariant;
  // ... other props
}
  1. The click handler's purpose should be documented, as stopPropagation() usage isn't immediately obvious:
 <StyledInternalLink
   to={link}
+  // Prevent click events from bubbling up to parent containers
+  // This is necessary when the Field is used within clickable containers
   onClick={(event) => {
     event.stopPropagation();
   }}
 >

These changes would improve maintainability and make the component's behavior more explicit.


Line range hint 93-106: Enhance accessibility attributes

Consider adding these accessibility improvements:

  1. Add aria-label to the icon for screen readers
  2. Ensure proper color contrast for the link text (especially with the new font-weight)

Example implementation:

 <FieldContainer isList={displayAsList} {...{ isOverview, isJurorBalance, width, className }}>
-  <Icon />
+  <Icon aria-label={`${name} icon`} />
   {(!displayAsList || isOverview || isJurorBalance) && <label>{name}:</label>}
web/src/components/DisputePreview/Policies.tsx (1)

66-83: Consider refactoring for improved maintainability

The conditional rendering logic could be simplified and the URL construction could be extracted to reduce repetition.

Consider this refactor:

export const Policies: React.FC<IPolicies> = ({ disputePolicyURI, courtId, attachment }) => {
+ const renderPolicyLink = (
+   to: string,
+   Icon: typeof StyledPolicyIcon | typeof StyledPaperclipIcon,
+   label: string
+ ) => (
+   <StyledInternalLink to={to}>
+     <Icon />
+     {label}
+   </StyledInternalLink>
+ );

  return (
    <Container>
      <StyledP>Policy documents:</StyledP>
-     {!isUndefined(attachment) && !isUndefined(attachment.uri) ? (
-       <StyledInternalLink to={`attachment/?url=${getIpfsUrl(attachment.uri)}`}>
-         <StyledPaperclipIcon />
-         {attachment.label ?? "Attachment"}
-       </StyledInternalLink>
-     ) : null}
+     {attachment?.uri && renderPolicyLink(
+       `attachment/?url=${getIpfsUrl(attachment.uri)}`,
+       StyledPaperclipIcon,
+       attachment.label ?? "Attachment"
+     )}
-     {isUndefined(disputePolicyURI) ? null : (
-       <StyledInternalLink to={`policy/attachment/?url=${getIpfsUrl(disputePolicyURI)}`}>
-         <StyledPolicyIcon />
-         Dispute Policy
-       </StyledInternalLink>
-     )}
+     {disputePolicyURI && renderPolicyLink(
+       `policy/attachment/?url=${getIpfsUrl(disputePolicyURI)}`,
+       StyledPolicyIcon,
+       "Dispute Policy"
+     )}
-     {isUndefined(courtId) ? null : (
-       <StyledInternalLink to={`/courts/${courtId}/policy?section=description`}>
-         <StyledPolicyIcon />
-         Court Policy
-       </StyledInternalLink>
-     )}
+     {courtId && renderPolicyLink(
+       `/courts/${courtId}/policy?section=description`,
+       StyledPolicyIcon,
+       "Court Policy"
+     )}
    </Container>
  );
};
web/src/components/LightButton.tsx (1)

16-16: Consider extracting theme colors to constants

The fill color logic could be more maintainable by extracting the theme colors and opacity values into named constants.

+ const DESKTOP_FILL = (theme) => `${theme.white}BF`;
+ const DESKTOP_HOVER_FILL = (theme) => theme.white;
+ const MOBILE_FILL = (theme) => theme.secondaryText;
+ const MOBILE_HOVER_FILL = (theme) => theme.primaryText;

  .button-svg {
-   fill: ${({ theme, isMobileNavbar }) => (isMobileNavbar ? theme.secondaryText : `${theme.white}BF`)} !important;
+   fill: ${({ theme, isMobileNavbar }) => (isMobileNavbar ? MOBILE_FILL(theme) : DESKTOP_FILL(theme))} !important;
  }

  &:hover {
    .button-svg {
-     fill: ${({ theme, isMobileNavbar }) => (isMobileNavbar ? theme.primaryText : `${theme.white}`)} !important;
+     fill: ${({ theme, isMobileNavbar }) => (isMobileNavbar ? MOBILE_HOVER_FILL(theme) : DESKTOP_HOVER_FILL(theme))} !important;
    }
  }

Also applies to: 21-21

web/src/layout/Header/navbar/Explore.tsx (1)

38-38: Consider extracting style conditions to styled-components helper functions

The conditional styling logic could be more maintainable by using styled-components helper functions.

+ const getFontWeight = ({ isActive, isMobileNavbar }) => 
+   isMobileNavbar && isActive ? "600" : "normal";

+ const getHoverColor = ({ theme, isMobileNavbar }) => 
+   isMobileNavbar ? theme.primaryText : theme.white;

- font-weight: ${({ isActive, isMobileNavbar }) => (isMobileNavbar && isActive ? "600" : "normal")};
+ font-weight: ${getFontWeight};

  &:hover {
-   color: ${({ theme, isMobileNavbar }) => (isMobileNavbar ? theme.primaryText : theme.white)} !important;
+   color: ${getHoverColor} !important;
  }

Also applies to: 43-43

web/src/layout/Header/navbar/index.tsx (2)

Line range hint 26-36: Consider using CSS variables for transitions.

The styled components use hardcoded values for transitions. Consider moving these to CSS variables for better maintainability.

const Wrapper = styled.div<{ isOpen: boolean }>`
  visibility: ${({ isOpen }) => (isOpen ? "visible" : "hidden")};
  position: absolute;
  top: 100%;
  left: 0;
  width: 100vw;
  height: 100vh;
  z-index: 1;
+ transition: visibility var(--transition-speed) ease;
`;

Line range hint 135-142: Consider using a dedicated modal/dialog component.

The popup handling logic could benefit from using a dedicated modal component that handles overlay, accessibility, and keyboard interactions.

Consider using a modal component from your UI library or implementing one that:

  • Handles keyboard events (Esc to close)
  • Manages focus trap
  • Provides proper ARIA attributes
  • Handles click outside behavior consistently
web/src/utils/beautifyStatNumber.ts (1)

24-45: Consider enhancing input validation and error handling

The implementation is functional but could be more robust. Consider these improvements:

 export function unbeautifyStatNumber(value: string): number {
   const multiplierMap: Record<string, number> = {
     B: 1e9,
     M: 1e6,
     K: 1e3,
   };
 
-  const match = value.match(/^([\d,\.]+)([BMK]?)$/);
+  const match = value.match(/^(-?[\d,]+\.?\d*?)([BMK]?)$/);
 
   if (!match) {
-    throw new Error("Invalid formatted number string");
+    throw new Error(
+      "Invalid formatted number string. Expected format: optional negative sign, digits with optional commas and decimal point, optional suffix (K/M/B)"
+    );
   }
 
   const [, numericPart, unit] = match;
+  if (numericPart.split(".").length > 2) {
+    throw new Error("Invalid number format: multiple decimal points found");
+  }
   const numericValue = parseFloat(numericPart.replace(/,/g, ""));
 
   if (unit && multiplierMap[unit]) {
     return numericValue * multiplierMap[unit];
   }
 
   return numericValue;
 }

The improvements include:

  1. Support for negative numbers
  2. More precise decimal number validation
  3. More descriptive error messages
  4. Prevention of multiple decimal points
web/src/pages/Courts/CourtDetails/Stats.tsx (1)

265-271: Consider extracting common USD conversion logic

The getSubtext implementations contain similar patterns for USD conversion.

Consider extracting the common logic:

const calculateUSDValue = (pnkAmount: number, coinPrice?: number) => {
  if (!pnkAmount) return "N/A";
  return formatUSD(unbeautifyStatNumber(beautifyStatNumber(pnkAmount, true)) * (coinPrice ?? 0));
};

Then use it in the getSubtext methods:

getSubtext: (data, coinPrice) => {
  const treeExpectedRewardPerPnk = data?.treeExpectedRewardPerPnk;
  const ethPriceUSD = pricesData ? pricesData[CoinIds.ETH]?.price : undefined;
  if (!ethPriceUSD || !treeExpectedRewardPerPnk) return "N/A";
  const pnkNeeded = treeExpectedRewardPerPnk * ethPriceUSD;
  return calculateUSDValue(pnkNeeded, coinPrice);
}

Also applies to: 288-293

web/src/components/Verdict/Answer.tsx (1)

18-22: Consider semantic HTML implications

Using h4 for description text might not be semantically correct. Consider using p or span with appropriate styling instead, as this content appears to be descriptive rather than a heading.

-const AnswerDescription = styled.h4`
+const AnswerDescription = styled.p`
   margin: 0;
   font-size: 15px;
   color: ${({ theme }) => theme.primaryText};
 `;
web/src/components/DisputeView/DisputeInfo/DisputeInfoList.tsx (2)

Line range hint 38-43: Consider improving the truncateText utility

The truncation function could be enhanced in several ways:

  1. Handle null/undefined input gracefully
  2. Make the ellipsis character configurable
  3. Consider word boundaries to avoid cutting words in the middle
-const truncateText = (text: string, limit: number) => {
+const truncateText = (text: string | undefined | null, limit: number, ellipsis = '...') => {
+  if (!text) return '';
   if (text && text.length > limit) {
-    return text.substring(0, limit) + "...";
+    const truncated = text.substring(0, limit).trim();
+    return truncated + ellipsis;
   }
   return text;
 };

Line range hint 51-57: Consider selective truncation based on field type

The current implementation truncates all field values to 20 characters. Consider:

  1. Making the truncation limit configurable per field
  2. Excluding certain field types (numbers, dates) from truncation
-value={truncateText(item.value, 20)}
+value={item.skipTruncate ? item.value : truncateText(item.value, item.truncateLimit ?? 20)}
web/src/components/CasesDisplay/index.tsx (1)

27-29: Consider using responsiveSize for font-size

The font-size is hardcoded to 16px. Consider using the responsiveSize utility for consistent responsive behavior across the application.

const StyledLabel = styled.label`
-  font-size: 16px;
+  font-size: ${responsiveSize(14, 16)};
`;
web/src/components/DisputeView/DisputeInfo/index.tsx (1)

Line range hint 98-98: Remove unused dependency from useMemo

The isOverview dependency is no longer used in the fieldItems calculation but is still included in the dependencies array. This could cause unnecessary re-renders.

    ],
-    [category, court, courtId, date, displayAsList, isOverview, period, rewards, round]
+    [category, court, courtId, date, displayAsList, period, rewards, round]
  );
web/src/app.tsx (1)

98-98: Consider using a styled error page component

While the message is now more professional, consider creating a dedicated styled component for the 404 page to:

  • Maintain consistent styling with the rest of the application
  • Provide better user experience with potential navigation options
  • Keep the error message accessible and visually appealing

Example implementation:

const NotFound = styled.div`
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: ${responsiveSize(24, 32)};
  
  h1 {
    margin-bottom: ${responsiveSize(16, 24)};
  }
`;

// Usage
<Route path="*" element={
  <NotFound>
    <h1>Page not found</h1>
    <StyledArrowLink to="/">Return to home</StyledArrowLink>
  </NotFound>
} />
web/src/pages/Courts/CourtDetails/Description.tsx (1)

84-93: LGTM! Consider extracting the fallback path logic.

The conditional rendering with fallback navigation is a good improvement for handling missing policy summaries. However, the fallback path filteredTabs.length > 0 ? filteredTabs[0].path : "" is duplicated in both routes.

Consider extracting the fallback path logic to improve maintainability:

+ const defaultPath = filteredTabs.length > 0 ? filteredTabs[0].path : "";
  <Routes>
    <Route path="purpose" element={formatMarkdown(policy?.description)} />
    <Route path="skills" element={<p>{policy?.requiredSkills}</p>} />
    <Route
      path="policy"
      element={
        policy?.summary ? (
          formatMarkdown(policy?.summary)
        ) : (
-         <Navigate to={filteredTabs.length > 0 ? filteredTabs[0].path : ""} replace />
+         <Navigate to={defaultPath} replace />
        )
      }
    />
-   <Route path="*" element={<Navigate to={filteredTabs.length > 0 ? filteredTabs[0].path : ""} replace />} />
+   <Route path="*" element={<Navigate to={defaultPath} replace />} />
  </Routes>
web/src/pages/Courts/CourtDetails/StakePanel/Simulator/index.tsx (3)

Line range hint 122-156: Consider memoizing complex data transformations.

While the hooks usage is correct, consider memoizing the following transformations to prevent unnecessary recalculations:

  • jurorStakeData finding
  • stake calculations
+ const jurorStakeData = useMemo(
+   () => stakeData?.jurorTokensPerCourts?.find(({ court }) => court.id === id),
+   [stakeData, id]
+ );

+ const { jurorCurrentEffectiveStake, jurorCurrentSpecificStake } = useMemo(
+   () => ({
+     jurorCurrentEffectiveStake: address && jurorStakeData ? Number(formatEther(jurorStakeData.effectiveStake)) : 0,
+     jurorCurrentSpecificStake: address && jurorStakeData ? Number(formatEther(jurorStakeData.staked)) : 0,
+   }),
+   [address, jurorStakeData]
+ );

Line range hint 157-167: Enhance type safety in calculations.

The calculations are correct, but consider using TypeScript's nullish coalescing operator and type guards to improve type safety and readability:

- const { votes: totalVotes, rewards: totalRewards } = totals;
+ const { votes: totalVotes = 0, rewards: totalRewards = 0 } = totals ?? {};

  const courtFutureEffectiveStake = !isUndefined(courtCurrentEffectiveStake)
    ? Math.max(isStaking ? courtCurrentEffectiveStake + amountToStake : courtCurrentEffectiveStake - amountToStake, 0)
    : undefined;

- const futureTreeVotesPerPnk =
-   !isUndefined(courtFutureEffectiveStake) && !isUndefined(totalVotes)
-     ? totalVotes / courtFutureEffectiveStake
-     : undefined;
+ const futureTreeVotesPerPnk = courtFutureEffectiveStake
+   ? totalVotes / courtFutureEffectiveStake
+   : undefined;

Case-related calculations have been partially removed, but some references remain

The code still contains case-related references that should be addressed:

  • currentTreeDisputesPerPnk is still being used in the component
  • There's a cases calculation in the totals object that depends on currentTreeDisputesPerPnk
  • The cases value is calculated but never used in the component's UI
🔗 Analysis chain

Line range hint 157-167: Verify complete removal of case-related calculations.

The AI summary mentions removal of case-related calculations. Let's verify that all references have been properly removed.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining case-related references in the codebase
rg -i "case" --type ts --type tsx "web/src/pages/Courts/CourtDetails/StakePanel"

# Search for any imports or uses of removed case-related functions
rg "TreeDisputesPerPnk|totalCases|currentExpectedCases|futureExpectedCases" --type ts --type tsx "web/src/pages/Courts"

Length of output: 254


Script:

#!/bin/bash
# Search for any remaining case-related references in the codebase, without file type restrictions
rg -i "case" "web/src/pages/Courts/CourtDetails/StakePanel"

# Search for any imports or uses of removed case-related functions
rg "TreeDisputesPerPnk|totalCases|currentExpectedCases|futureExpectedCases" "web/src/pages/Courts"

# Additional search to find any case-related calculations in the specific file
cat "web/src/pages/Courts/CourtDetails/StakePanel/Simulator/index.tsx"

Length of output: 10428

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 0e582ae and 4473dc3.

📒 Files selected for processing (22)
  • web/src/app.tsx (1 hunks)
  • web/src/components/CasesDisplay/index.tsx (2 hunks)
  • web/src/components/DisputePreview/Policies.tsx (2 hunks)
  • web/src/components/DisputeView/DisputeInfo/DisputeInfoCard.tsx (2 hunks)
  • web/src/components/DisputeView/DisputeInfo/DisputeInfoList.tsx (1 hunks)
  • web/src/components/DisputeView/DisputeInfo/index.tsx (1 hunks)
  • web/src/components/Field.tsx (1 hunks)
  • web/src/components/LightButton.tsx (3 hunks)
  • web/src/components/Verdict/Answer.tsx (2 hunks)
  • web/src/components/Verdict/FinalDecision.tsx (2 hunks)
  • web/src/components/Verdict/VerdictBanner.tsx (1 hunks)
  • web/src/layout/Header/navbar/Explore.tsx (4 hunks)
  • web/src/layout/Header/navbar/Menu/index.tsx (3 hunks)
  • web/src/layout/Header/navbar/index.tsx (2 hunks)
  • web/src/pages/Cases/CaseDetails/Overview/index.tsx (1 hunks)
  • web/src/pages/Courts/CourtDetails/Description.tsx (1 hunks)
  • web/src/pages/Courts/CourtDetails/StakePanel/Simulator/index.tsx (4 hunks)
  • web/src/pages/Courts/CourtDetails/StakePanel/index.tsx (2 hunks)
  • web/src/pages/Courts/CourtDetails/Stats.tsx (6 hunks)
  • web/src/pages/Courts/CourtDetails/index.tsx (3 hunks)
  • web/src/styles/themes.ts (2 hunks)
  • web/src/utils/beautifyStatNumber.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • web/src/pages/Cases/CaseDetails/Overview/index.tsx
🧰 Additional context used
📓 Learnings (1)
web/src/components/DisputeView/DisputeInfo/DisputeInfoList.tsx (1)
Learnt from: nikhilverma360
PR: kleros/kleros-v2#1632
File: web/src/components/DisputeView/DisputeInfo/DisputeInfoList.tsx:37-42
Timestamp: 2024-11-12T04:49:43.234Z
Learning: `useMemo` is used in `DisputeInfoList` to optimize the rendering of `FieldItems` based on changes in `fieldItems`, ensuring that the mapping and truncation operation are only performed when necessary.
🔇 Additional comments (22)
web/src/components/Field.tsx (1)

51-53: LGTM: Styling changes are well-implemented

The addition of font-weight styling for anchor elements is properly scoped and consistent with the component's existing styling patterns.

web/src/components/DisputePreview/Policies.tsx (2)

14-19: Well-structured styling improvements!

The new flex layout with responsive gap and simplified margins creates a more maintainable and responsive design. The use of flex-wrap ensures good mobile compatibility.

Also applies to: 26-26


64-84: Clean and semantic implementation!

The component structure is well-organized with consistent conditional rendering and proper null checks.

web/src/components/LightButton.tsx (1)

7-7: LGTM! Clean implementation of mobile navigation support

The addition of the isMobileNavbar prop and its implementation is clean and consistent. The changes properly handle both mobile and desktop contexts.

Also applies to: 43-43, 46-47

web/src/layout/Header/navbar/Menu/index.tsx (1)

51-53: LGTM! Clean interface composition and prop handling

The addition of the IMenu interface and its integration with existing interfaces is well-structured. The prop passing to LightButton is implemented cleanly.

Also applies to: 55-55, 84-84

web/src/layout/Header/navbar/Explore.tsx (1)

32-32: LGTM! Well-structured mobile navigation enhancements

The implementation of mobile-specific styling through the isMobileNavbar prop is clean and consistent. The interface definition and prop handling are well-structured.

Also applies to: 62-64, 66-66, 78-78

web/src/styles/themes.ts (1)

7-7: Verify if this color addition is necessary.

The addition of black: "#000000" might be redundant if:

  1. The base component library themes (componentsLightTheme/componentsDarkTheme) already include this color
  2. The color is only used in limited places where an existing color property could be used instead

Also applies to: 56-56

✅ Verification successful

The black color property is necessary and correctly used

The verification shows that:

  1. The theme.black color itself isn't directly used, but its derivative blackLowOpacity (which uses the same hex value with opacity) is used in multiple components:
    • Header/navbar
    • Overlay component
    • DesktopHeader

The color serves as a base for the blackLowOpacity variable (#00000080), making it a foundational color that should be explicitly defined in the theme rather than relying on potential inherited values from the component library.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if the black color is already defined in the component library
# and where the new black color is being used

# Search for black color usage in the codebase
rg -B 2 -A 2 'theme\.black'

# Search for potential hardcoded #000000 values that could be replaced
rg -B 2 -A 2 '#000000'

Length of output: 3853

web/src/pages/Courts/CourtDetails/Stats.tsx (2)

238-250: LGTM! Well-structured stat component with clear user guidance

The implementation includes a helpful tooltip and proper number formatting.


339-346: Verify null safety in the mapping function

The code assumes coinIds[coinId!] will always be valid.

Consider adding a type guard:

-const coinPrice = !isUndefined(pricesData) ? pricesData[coinIds[coinId!]]?.price : undefined;
+const coinPrice = !isUndefined(pricesData) && coinId !== undefined ? pricesData[coinIds[coinId]]?.price : undefined;
✅ Verification successful

The non-null assertion is safe to use here

The code inspection reveals that coinId is always defined in the timeframedStats array with specific numeric values (0 or 1). All entries in the array have an explicit coinId property set, making the non-null assertion operator (!) safe to use in this context. The interface shows coinId as optional (coinId?: number), but the actual implementation always provides it.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if coinId is always defined in timeframedStats
ast-grep --pattern 'const timeframedStats: ITimeframedStat[] = [
  $$$
  {
    $$$
    coinId: $_,
    $$$
  }
  $$$
]'

Length of output: 121


Script:

#!/bin/bash
# Let's try to find the timeframedStats definition with a simpler pattern
rg "timeframedStats.*=" -A 20

Length of output: 3335


Script:

#!/bin/bash
# Let's also check the interface definition
rg "interface ITimeframedStat"

Length of output: 180


Script:

#!/bin/bash
# Check for any usage of coinId in the file
rg "coinId" "web/src/pages/Courts/CourtDetails/Stats.tsx"

Length of output: 742

web/src/components/Verdict/Answer.tsx (1)

6-12: LGTM! Clean and responsive layout implementation

The Container component implements a flexible and responsive layout with proper spacing. The implementation handles both answer present and absent cases well.

Also applies to: 32-37

web/src/components/Verdict/VerdictBanner.tsx (1)

10-10: Verify the fixed margin impact across screen sizes

The change from a responsive margin (16-24px) to a fixed 8px might affect the visual hierarchy and spacing on larger screens. Consider if this reduction in margin is intentional and test across different viewport sizes.

web/src/components/DisputeView/DisputeInfo/DisputeInfoCard.tsx (2)

56-56: LGTM! Clean props interface update

The removal of court-related props simplifies the component interface while maintaining type safety.


Line range hint 56-65: Verify the impact of removed court functionality

The removal of court-related functionality might affect features depending on this information. Let's verify there are no remaining references to the removed props.

web/src/components/DisputeView/DisputeInfo/DisputeInfoList.tsx (1)

33-36: LGTM: StyledField implementation

The styled component implementation follows best practices by extending the Field component and providing flexible styling options.

web/src/components/DisputeView/DisputeInfo/index.tsx (1)

79-79: LGTM: Simplified court display logic

The simplified condition for displaying court information improves code readability while maintaining the same functionality.

web/src/components/Verdict/FinalDecision.tsx (2)

33-35: LGTM: Improved responsive layout

The changes to JuryContainer enhance the component's responsive behavior by:

  • Using row layout with wrap support for better space utilization
  • Properly aligning items in the center

51-51: LGTM: Consistent spacing using responsiveSize

Good use of responsiveSize utility for dynamic margin scaling between 16px and 24px based on viewport size.

web/src/pages/Courts/CourtDetails/StakePanel/index.tsx (1)

16-16: LGTM! Verify SimulatorPopup to Simulator rename impact.

The component rename from SimulatorPopup to Simulator is implemented correctly here.

Let's verify no remaining references to SimulatorPopup exist:

Also applies to: 102-102

✅ Verification successful

Component rename from SimulatorPopup to Simulator is complete

The verification confirms that the rename was done correctly and completely:

  • All references now use "Simulator" instead of "SimulatorPopup"
  • The component is properly defined in StakePanel/Simulator/index.tsx
  • No lingering references to "SimulatorPopup" exist in the codebase
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining references to SimulatorPopup
# Test: Search for SimulatorPopup. Expect: No results as component was renamed.
rg -i "simulatorpopup"

Length of output: 22


Script:

#!/bin/bash
# Let's try a more thorough search for any references to SimulatorPopup
# 1. Search for files containing "simulator" to understand the scope
fd -t f -e tsx -e ts -e js -e jsx | xargs rg -i "simulator"

# 2. Check git history for the rename to ensure completeness
git log -p --all -S "SimulatorPopup" --since="1 month ago"

# 3. Look for any potential component definitions
ast-grep --pattern 'const SimulatorPopup = $_'

Length of output: 2184

web/src/pages/Courts/CourtDetails/index.tsx (2)

41-41: LGTM! Style improvements enhance visual hierarchy.

The increased margin-bottom for CourtHeader and reduced gap in CourtInfo create better visual spacing and hierarchy.

Also applies to: 49-49


90-90: Verify the breadcrumb visibility logic change.

The new breadcrumb visibility logic (items.length > 1 && items[0]?.value !== 1) appears to hide navigation for the top-level court. While this makes sense, we should ensure this doesn't affect user navigation expectations.

Let's verify the court hierarchy structure:

Also applies to: 104-104

✅ Verification successful

Let me gather more specific information about the court hierarchy and breadcrumb implementation.


Let me check the complete breadcrumb implementation and court path logic to understand the navigation flow better.


Let me check the court path utility implementation to understand how the hierarchy is constructed.


Based on the code analysis, I can now provide a final response about the breadcrumb visibility logic.

The breadcrumb visibility logic is correctly implemented and safe to use

The implementation shows that:

  1. The breadcrumb is hidden only when there's a single item (no hierarchy) or when viewing the root court (id=1)
  2. The getCourtsPath utility correctly builds the court hierarchy path by recursively traversing the court tree
  3. The breadcrumb items are properly constructed from the court path, preserving the navigation structure

This change maintains proper navigation while avoiding redundant breadcrumbs for top-level views, which is a good UX practice.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check court hierarchy implementation
# Test: Search for court hierarchy related code to understand the structure
ast-grep --pattern 'interface $interface {
  $$$
  id: $type
  $$$
}'

# Also check for any court-related tests
rg -l "court.*test"

Length of output: 1994


Script:

#!/bin/bash
# Check the court details component and breadcrumb implementation
rg -A 5 "items\s*=\s*\[\]" web/src/pages/Courts/CourtDetails/

# Look for court hierarchy related code
ast-grep --pattern 'const $var = useParams<{ courtId: string }>();'

# Check for any court navigation related components
rg -l "Breadcrumb|breadcrumb"

Length of output: 603


Script:

#!/bin/bash
# Get the complete context of breadcrumb implementation
rg -B 10 -A 10 "const items = \[\]" web/src/pages/Courts/CourtDetails/index.tsx

# Check for courtPath implementation
ast-grep --pattern 'const courtPath = $$$'

# Look for any court navigation related hooks or utils
rg -l "useCourt|useCourtPath|getCourtPath"

Length of output: 1496


Script:

#!/bin/bash
# Find and check the getCourtsPath implementation
rg -A 20 "getCourtsPath" 

# Check the court tree hook implementation
rg -A 10 "useCourtTree" web/src/hooks/queries/useCourtTree.ts

# Look for any breadcrumb navigation components
rg -A 5 "Breadcrumb" web/src/components/

Length of output: 3896

web/src/pages/Courts/CourtDetails/StakePanel/Simulator/index.tsx (2)

117-120: LGTM! Interface rename and definition are appropriate.

The interface rename from ISimulatorPopup to ISimulator better reflects the component's purpose, and the props are well-typed.


Line range hint 213-269: Well-structured rendering logic with good UX considerations.

The simulator items implementation is clean with:

  • Clear tooltips for complex concepts
  • Appropriate loading states
  • Good handling of edge cases (zero amount)

web/src/layout/Header/navbar/index.tsx Show resolved Hide resolved
web/src/components/CasesDisplay/index.tsx Show resolved Hide resolved
coderabbitai[bot]
coderabbitai bot previously approved these changes Dec 6, 2024
@kemuru kemuru requested a review from alcercu December 6, 2024 13:05
coderabbitai[bot]
coderabbitai bot previously approved these changes Dec 6, 2024
coderabbitai[bot]
coderabbitai bot previously approved these changes Dec 6, 2024
coderabbitai[bot]
coderabbitai bot previously approved these changes Dec 6, 2024
coderabbitai[bot]
coderabbitai bot previously approved these changes Dec 6, 2024
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (1)
web/src/components/DisputePreview/DisputeContext.tsx (1)

74-74: Consider enhancing accessibility for content sections

While the implementation is functionally correct, consider adding ARIA attributes to improve accessibility:

  • Add aria-label to the markdown sections to describe their purpose
  • Ensure error messages are properly announced to screen readers

Example implementation:

- <ReactMarkdown>{disputeDetails?.question}</ReactMarkdown>
+ <div aria-label="Dispute Question">
+   <ReactMarkdown>{disputeDetails?.question}</ReactMarkdown>
+ </div>

- <ReactMarkdown>{disputeDetails?.description}</ReactMarkdown>
+ <div aria-label="Dispute Description">
+   <ReactMarkdown>{disputeDetails?.description}</ReactMarkdown>
+ </div>

- <AnswersHeader>Voting Options</AnswersHeader>
+ <AnswersHeader aria-label="Available voting options">Voting Options</AnswersHeader>

Also applies to: 77-78, 87-87

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 875fcad and 00f56b5.

📒 Files selected for processing (1)
  • web/src/components/DisputePreview/DisputeContext.tsx (4 hunks)
🔇 Additional comments (2)
web/src/components/DisputePreview/DisputeContext.tsx (2)

30-31: LGTM: Styling adjustment for consistent spacing

The margin adjustment helps maintain consistent spacing in the component.


45-47: LGTM: Clean styled component implementation

The new AnswersHeader styled component follows the established pattern of zero margins and uses semantic HTML (h3).

coderabbitai[bot]
coderabbitai bot previously approved these changes Dec 6, 2024
coderabbitai[bot]
coderabbitai bot previously approved these changes Dec 6, 2024
coderabbitai[bot]
coderabbitai bot previously approved these changes Dec 6, 2024
coderabbitai[bot]
coderabbitai bot previously approved these changes Dec 6, 2024
Copy link

codeclimate bot commented Dec 6, 2024

Code Climate has analyzed commit 6e5113c and detected 10 issues on this pull request.

Here's the issue category breakdown:

Category Count
Complexity 1
Duplication 6
Style 3

View more on Code Climate.

Copy link

sonarcloud bot commented Dec 6, 2024

Copy link
Contributor

@alcercu alcercu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants