-
Notifications
You must be signed in to change notification settings - Fork 43
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(web): extra statistic on homepage #1671
base: dev
Are you sure you want to change the base?
Conversation
WalkthroughThe recent changes introduce several components and hooks that enhance the home page by providing additional statistics related to court activities. Key additions include the Changes
Assessment against linked issues
Possibly related issues
Poem
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
✅ Deploy Preview for kleros-v2-testnet ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
✅ Deploy Preview for kleros-v2-neo ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
❌ Deploy Preview for kleros-v2-university failed. Why did it fail? →
|
Quality Gate failedFailed conditions See analysis details on SonarCloud Catch issues before they fail your Quality Gate with our IDE extension SonarLint |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files ignored due to path filters (1)
web/src/assets/svgs/icons/long-arrow-up.svg
is excluded by!**/*.svg
Files selected for processing (8)
- web/src/components/ExtraStatsDisplay.tsx (1 hunks)
- web/src/hooks/queries/useHomePageBlockQuery.ts (1 hunks)
- web/src/hooks/queries/useHomePageExtraStats.ts (1 hunks)
- web/src/hooks/queries/useHomePageQuery.ts (1 hunks)
- web/src/hooks/useBlockByTimestamp.tsx (1 hunks)
- web/src/pages/Home/CourtOverview/ExtraStats.tsx (1 hunks)
- web/src/pages/Home/CourtOverview/index.tsx (2 hunks)
- web/src/utils/date.ts (1 hunks)
Additional comments not posted (20)
web/src/pages/Home/CourtOverview/index.tsx (2)
5-5
: Import statement forExtraStats
looks good.The import path appears to be correct and consistent with the project structure.
19-19
: Integration ofExtraStats
component looks good.The
ExtraStats
component is correctly rendered within theCourtOverview
component.web/src/hooks/queries/useHomePageBlockQuery.ts (3)
1-7
: Import statements look good.The necessary imports for
useQuery
,useGraphqlBatcher
,graphql
, andHomePageBlockQuery
are correctly included.
9-19
: GraphQL query definition looks good.The query is correctly defined to fetch court data based on a block number and includes all necessary fields.
21-37
: Custom hookuseHomePageBlockQuery
implementation looks good.The hook is correctly implemented and uses
useQuery
to fetch data based on the block number. The query logic and error handling are properly managed.web/src/hooks/queries/useHomePageQuery.ts (1)
22-27
: GraphQL query modifications look good.The query now includes sorting parameters and additional fields
feeForJuror
andstake
, which are correctly added.web/src/components/ExtraStatsDisplay.tsx (5)
1-5
: Imports look good.The imported modules are appropriate for the functionality provided in the file.
6-31
: Styled components are well-defined.The styled components
Container
,SVGContainer
, andTextContainer
are well-defined and follow best practices.
33-37
: Interface definition is well-defined.The interface
IExtraStatsDisplay
ensures type safety for the props of theExtraStatsDisplay
component.
39-49
: Functional component is well-defined.The
ExtraStatsDisplay
component is well-defined and follows best practices. It conditionally rendersStyledSkeleton
iftext
is null.
51-51
: Export statement is appropriate.The
ExtraStatsDisplay
component is appropriately exported as the default export.web/src/pages/Home/CourtOverview/ExtraStats.tsx (4)
1-13
: Imports look good.The imported modules are appropriate for the functionality provided in the file.
14-27
: Styled component is well-defined.The styled component
StyledCard
is well-defined and follows best practices.
29-33
: Interface definition is well-defined.The interface
IStat
ensures type safety for the stats configuration.
35-51
: Stats configuration is well-defined.The
stats
array contains the configuration for the stats to be displayed and follows best practices.web/src/hooks/queries/useHomePageExtraStats.ts (3)
1-13
: Imports look good.All necessary imports are correctly included.
14-38
: Type definitions look good.The type definitions are correctly defined and necessary for the hook's functionality.
16-32
: Utility functions look good.The utility functions are correctly implemented and optimized for performance.
web/src/hooks/useBlockByTimestamp.tsx (2)
1-7
: Imports look good.All necessary imports are correctly included.
8-12
: State and effect hooks look good.The state and effect hooks are correctly implemented.
There was a problem hiding this 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/consts/averageBlockTimeInSeconds.ts (1)
3-3
: Consider fetching the block times dynamically.While hardcoding the average block times provides a simple solution, it might require manual updates if the values change in the future. Consider implementing a mechanism to fetch the block times dynamically from a reliable source to ensure the values remain up-to-date.
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (5)
- web/src/components/ExtraStatsDisplay.tsx (1 hunks)
- web/src/consts/averageBlockTimeInSeconds.ts (1 hunks)
- web/src/hooks/queries/useHomePageExtraStats.ts (1 hunks)
- web/src/pages/Home/CourtOverview/ExtraStats.tsx (1 hunks)
- web/src/pages/Home/CourtOverview/Header.tsx (1 hunks)
Files skipped from review as they are similar to previous changes (3)
- web/src/components/ExtraStatsDisplay.tsx
- web/src/pages/Home/CourtOverview/ExtraStats.tsx
- web/src/pages/Home/CourtOverview/Header.tsx
Additional comments not posted (8)
web/src/consts/averageBlockTimeInSeconds.ts (1)
1-3
: LGTM!The code is well-structured and provides a clear way to access average block times for specific networks. The use of a constant object and importing the network IDs from the
viem
library ensures consistency and maintainability.web/src/hooks/queries/useHomePageExtraStats.ts (7)
1-13
: LGTM!The imports are relevant and necessary for the functionality implemented in this file.
14-14
: LGTM!The type alias
Court
is correctly defined and improves code readability by providing a semantic name for the type.
16-24
: LGTM!The function
getCourtWithMaxDifference
correctly calculates the court with the maximum difference in the number of disputes between the two arrays ofCourt
objects.
26-28
: LGTM!The function
getCourtWithMaxReward
correctly returns the court with the maximum fee for jurors from the given array ofCourt
objects.
30-32
: LGTM!The function
getCourtWithMaxChance
correctly returns the court with the maximum stake from the given array ofCourt
objects.
34-38
: LGTM!The interface
HomePageExtraStatsType
correctly defines the structure of the object returned by theuseHomePageExtraStats
hook.
40-70
: LGTM!The
useHomePageExtraStats
hook is well-implemented and correctly calculates the additional statistics for the homepage. It uses theuseHomePageContext
anduseHomePageBlockQuery
hooks to fetch the necessary data, performs the calculations using helper functions, and memoizes the results for optimal performance. The returned object matches theHomePageExtraStatsType
interface.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
Outside diff range and nitpick comments (2)
web/src/hooks/queries/useHomePageExtraStats.ts (1)
3-4
: Consider importingDEFAULT_CHAIN
from a more generic location.The constant
DEFAULT_CHAIN
is imported fromconsts/chains
. To improve reusability and maintainability, consider moving this constant to a more generic location, such as aconfig
orconstants
directory at the root level of the project. This will make it easier to access and modify the default chain value across different parts of the application.web/src/hooks/queries/useHomePageBlockQuery.ts (1)
35-50
: Consider adding error handling and loading state management.The
useHomePageBlockQuery
hook utilizes theuseQuery
hook from the@tanstack/react-query
library, which is a good practice for data fetching and caching. However, consider adding error handling and loading state management to improve the user experience and handle potential issues gracefully.You can destructure the
error
andisLoading
properties from theusedQuery
object and handle them accordingly in the component that consumes this hook. For example:const { data, error, isLoading } = useHomePageBlockQuery(blockNumber); if (isLoading) { return <LoadingSpinner />; } if (error) { return <ErrorMessage error={error} />; }
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (3)
- web/src/hooks/queries/useHomePageBlockQuery.ts (1 hunks)
- web/src/hooks/queries/useHomePageExtraStats.ts (1 hunks)
- web/src/pages/Home/CourtOverview/ExtraStats.tsx (1 hunks)
Files skipped from review as they are similar to previous changes (1)
- web/src/pages/Home/CourtOverview/ExtraStats.tsx
Additional comments not posted (7)
web/src/hooks/queries/useHomePageExtraStats.ts (4)
1-2
: Verify the imported dependencies are used.The imported dependencies
useEffect
,useState
,useBlockNumber
, andaverageBlockTimeInSeconds
are being used correctly within the hook. No unused imports detected.Also applies to: 6-7
9-12
: LGTM!The hook initializes the state variable
oneWeekAgoBlockNumber
and retrieves the current block number using theuseBlockNumber
hook from thewagmi
library. The usage of theDEFAULT_CHAIN
constant as thechainId
parameter ensures consistency in fetching the block number for the desired chain.
1-23
: Ensure proper error handling.The hook
useHomePageExtraStats
is well-implemented, but consider adding error handling for the data fetching logic to improve robustness.
13-18
: Verify the calculation ofoneWeekInBlocks
.The
useEffect
hook calculates the number of blocks equivalent to one week using theaverageBlockTimeInSeconds
constant. This calculation appears to be correct, as it converts the duration of one week in seconds to the corresponding number of blocks based on the average block time for the specified chain.To verify the calculation, run the following script:
Verification successful
Calculation of
oneWeekInBlocks
is correct and flexibleThe implementation correctly calculates
oneWeekInBlocks
using the formula:Math.floor((7 * 24 * 3600) / averageBlockTimeInSeconds[DEFAULT_CHAIN])This calculation is flexible and adapts to the current chain:
- For Arbitrum (production): ~2,338,461 blocks
- For Arbitrum Sepolia (non-production): ~2,268,656 blocks
The use of
DEFAULT_CHAIN
ensures the correct average block time is used based on the deployment environment.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify the calculation of `oneWeekInBlocks` is correct. # Test: Check if the calculation matches the expected value. expected_value=$(echo "scale=0; (7 * 24 * 3600) / $(jq -r ".\"$DEFAULT_CHAIN\"" consts/averageBlockTimeInSeconds.json)" | bc) if [[ $(rg -o $'oneWeekInBlocks = (\d+)' -r '$1' web/src/hooks/queries/useHomePageExtraStats.ts) -eq $expected_value ]]; then echo "Calculation is correct" else echo "Calculation is incorrect" fiLength of output: 444
Script:
#!/bin/bash # View the contents of useHomePageExtraStats.ts echo "Contents of useHomePageExtraStats.ts:" cat web/src/hooks/queries/useHomePageExtraStats.ts # Search for averageBlockTimeInSeconds definition echo -e "\nSearching for averageBlockTimeInSeconds definition:" rg "const averageBlockTimeInSeconds" -A 5 # Search for DEFAULT_CHAIN definition echo -e "\nSearching for DEFAULT_CHAIN definition:" rg "const DEFAULT_CHAIN" -A 1Length of output: 1684
web/src/hooks/queries/useHomePageBlockQuery.ts (3)
1-8
: LGTM!The imports and exports are properly organized and follow the necessary conventions.
125-126
: LGTM!The hook returns the computed
courtActivityStats
object, which can be consumed by the components that require this data.
10-33
: Verify the GraphQL query fields align with the schema and requirements.The GraphQL query appears to be well-structured and includes the necessary fields for fetching court data. However, please ensure that the fields being queried, such as
numberDisputes
,feeForJuror
, andstake
, are available in the GraphQL schema and provide the expected data for the desired functionality.Run the following script to verify the GraphQL schema:
Verification successful
To further investigate the 'stake' field, which is present in our GraphQL query but not directly visible in the schema, let's search the codebase for any mentions of 'stake' in relation to the Court type. This will help us determine if it's a valid field or if it needs to be flagged as an issue.
Let's modify our search strategy to look for the 'stake' field in relation to the Court type, focusing on TypeScript files and using a more general search pattern.
The 'stake' field in the GraphQL query is valid and aligns with the schema.
After a thorough investigation of the codebase, we can confirm that the 'stake' field is a valid part of the Court type in the GraphQL schema. It is extensively used throughout the system in various contexts, including queries, calculations, and event definitions. The presence of this field in the HomePageBlock query is correct and consistent with the overall data structure and requirements of the application.
Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify the GraphQL query fields align with the schema. # Test: Search for the GraphQL schema file. Expect: A schema file containing the queried fields. fd -e graphql -x cat {} | rg -e 'type Court' -A 15Length of output: 1332
Script:
#!/bin/bash # Search for 'stake' in relation to the Court type rg -i "court.*stake|stake.*court" --type ts --type graphql -C 3Length of output: 97
Script:
#!/bin/bash # Search for 'stake' in relation to the Court type in TypeScript files rg -i "court.*stake|stake.*court" --type ts -C 3 # Search for 'Court' type definition in TypeScript files rg -i "type Court" --type ts -C 10 # Search for 'stake' field in any GraphQL query or type definition fd -e ts -x cat {} | rg -i "(query|type).*\{" -A 20 | rg -i "stake"Length of output: 82002
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Outside diff range and nitpick comments (2)
web/src/components/StyledSkeleton.tsx (1)
12-14
: Consider adding a prop to customize the margin-bottom value.To make the
StyledCaseCardTitleSkeleton
component more reusable and flexible, consider adding a prop that allows customizing themargin-bottom
value. This way, the component can be used in different contexts where different spacing might be required.Here's an example of how you can modify the component to accept a custom
marginBottom
prop:-export const StyledCaseCardTitleSkeleton = styled(StyledSkeleton)` - margin-bottom: 16px; -`; +export const StyledCaseCardTitleSkeleton = styled(StyledSkeleton)<{ marginBottom?: number }>` + margin-bottom: ${({ marginBottom }) => marginBottom ?? 16}px; +`;With this change, you can use the component like this:
<StyledCaseCardTitleSkeleton marginBottom={24} />web/src/components/DisputeView/DisputeCardView.tsx (1)
Line range hint
1-64
: Consider adding a loading state for the dispute information.The
DisputeInfo
component is not wrapped with a loading state, which may lead to inconsistent loading behavior. Consider adding a loading skeleton for the dispute information to enhance the user experience during loading states.Here's an example of how you can implement the loading state for the
DisputeInfo
component:+import { StyledDisputeInfoSkeleton } from "components/StyledSkeleton"; // ... const DisputeCardView: React.FC<IDisputeCardView> = ({ isLoading, ...props }) => { const navigate = useNavigate(); return ( <StyledCard hover onClick={() => navigate(`/cases/${props?.disputeID?.toString()}`)}> <PeriodBanner id={parseInt(props?.disputeID)} period={props?.period} /> <CardContainer> {isLoading ? <StyledCaseCardTitleSkeleton /> : <TruncatedTitle text={props?.title} maxLength={100} />} - <DisputeInfo {...props} /> + {isLoading ? <StyledDisputeInfoSkeleton /> : <DisputeInfo {...props} />} </CardContainer> </StyledCard> ); };Make sure to create the corresponding
StyledDisputeInfoSkeleton
component in theStyledSkeleton.tsx
file.
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (2)
- web/src/components/DisputeView/DisputeCardView.tsx (2 hunks)
- web/src/components/StyledSkeleton.tsx (1 hunks)
Additional comments not posted (3)
web/src/components/StyledSkeleton.tsx (2)
12-14
: LGTM!The new
StyledCaseCardTitleSkeleton
component extends the existingStyledSkeleton
component and adds a specificmargin-bottom
of 16px. This addition is a valid enhancement to improve the visual spacing and layout of the skeleton loading state for case card titles.
12-14
: Verify the usage ofStyledCaseCardTitleSkeleton
in the codebase.Ensure that the new
StyledCaseCardTitleSkeleton
component is being used appropriately in the relevant parts of the codebase where case card titles are displayed during loading states.Run the following script to verify the component usage:
Verification successful
Verified:
StyledCaseCardTitleSkeleton
is used correctly for loading statesThe
StyledCaseCardTitleSkeleton
component is being used appropriately in the codebase, specifically in the DisputeCardView component. It's correctly implemented to display a skeleton loader for case card titles during loading states.Key findings:
- Imported and used in
web/src/components/DisputeView/DisputeCardView.tsx
- Properly implemented in a conditional rendering based on
isLoading
state- Component definition in
web/src/components/StyledSkeleton.tsx
matches the provided code snippetScripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify the usage of `StyledCaseCardTitleSkeleton` in the codebase. # Test: Search for the component usage. Expect: Occurrences in relevant files. rg --type tsx -A 5 $'StyledCaseCardTitleSkeleton'Length of output: 76
Script:
#!/bin/bash # Description: Verify the usage of `StyledCaseCardTitleSkeleton` in the codebase. # Find all .tsx files and search for StyledCaseCardTitleSkeleton within them fd -e tsx -X rg -A 5 'StyledCaseCardTitleSkeleton'Length of output: 1477
web/src/components/DisputeView/DisputeCardView.tsx (1)
57-57
: LGTM!The component now uses the
StyledCaseCardTitleSkeleton
for the loading state, which aligns with the updated import statement. The conditional rendering logic remains intact and functions as expected.
…, calculation changes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (2)
- web/src/hooks/queries/useHomePageBlockQuery.ts (1 hunks)
- web/src/pages/Home/CourtOverview/ExtraStats.tsx (1 hunks)
Files skipped from review as they are similar to previous changes (1)
- web/src/pages/Home/CourtOverview/ExtraStats.tsx
for (const parent of diffCourts) { | ||
for (const child of diffCourts) { | ||
if (parent.id === child.parent?.id) { | ||
child.treeNumberVotes = String(Number(parent.treeNumberVotes) + Number(child.treeNumberVotes)); | ||
} | ||
} | ||
} | ||
diffCourts.reverse(); | ||
for (const child of diffCourts) { | ||
for (const parent of diffCourts) { | ||
if (parent.id === child.parent?.id) { | ||
parent.stake = String(BigInt(parent.stake) + BigInt(child.stake)); | ||
} | ||
} | ||
} | ||
diffCourts.reverse(); | ||
for (const c of diffCourts) { | ||
c.votesPerPnk = Number(c.numberVotes) / (Number(c.stake) / 1e18); | ||
c.treeVotesPerPnk = c.votesPerPnk; | ||
} | ||
for (const parent of diffCourts) { | ||
for (const child of diffCourts) { | ||
if (parent.id === child.parent?.id) { | ||
child.treeVotesPerPnk += parent.votesPerPnk; | ||
} | ||
} | ||
} | ||
const bestDrawingChancesCourt = diffCourts.sort((a, b) => b.treeVotesPerPnk - a.treeVotesPerPnk)[0]; | ||
// 3. expected reward | ||
// since we isolated the exclusive disputes from the cumulative disputes | ||
// we can calculate the "isolated reward" of every court | ||
// after that's done, then just trickle the rewards down | ||
|
||
for (const c of diffCourts) { | ||
c.expectedRewardPerPnk = c.votesPerPnk * c.feeForJuror; | ||
c.treeExpectedRewardPerPnk = c.expectedRewardPerPnk; | ||
} | ||
for (const parent of diffCourts) { | ||
for (const child of diffCourts) { | ||
if (parent.id === child.parent?.id) { | ||
child.treeExpectedRewardPerPnk = parent.treeExpectedRewardPerPnk + child.treeExpectedRewardPerPnk; | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here we are abusing loops, I would try to optimize them with something like this (pseudo code):
const processed = new Set();
const process = (court) => {
if (!processed.has(court.id) && court.parent) {
court.treeNumberVotes = court.treeNumberVotes + process(court.parent);
}
processed.add(court.id);
return court.treeNumberVotes;
}
for (const court of diffCourts.toReversed()) {
if (!processed.has(court.id))
process(court);
}
I would need to test but with this I think we can do it in linear time, also we might be able to do all the calculations with only one loop.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Outside diff range and nitpick comments (2)
subgraph/core/src/entities/Court.ts (1)
49-52
: LGTM! Consider future refactoring for improved readability.The additions of
numberVotes
andeffectiveStake
initializations are appropriate and align with the PR objectives of enhancing court statistics. These changes provide a solid foundation for tracking votes and effective stakes in the court system.As the
createCourtFromEvent
function continues to grow, consider refactoring it in the future for improved readability. One approach could be to group related initializations into separate functions. For example:function initializeCourtStatistics(court: Court): void { court.numberDisputes = ZERO; court.numberClosedDisputes = ZERO; court.numberVotingDisputes = ZERO; court.numberAppealingDisputes = ZERO; court.numberVotes = ZERO; court.numberStakedJurors = ZERO; } function initializeCourtFinancials(court: Court): void { court.stake = ZERO; court.effectiveStake = ZERO; court.delayedStake = ZERO; court.paidETH = ZERO; court.paidPNK = ZERO; } export function createCourtFromEvent(event: CourtCreated): void { const court = new Court(event.params._courtID.toString()); // ... other initializations ... initializeCourtStatistics(court); initializeCourtFinancials(court); court.save(); }This refactoring is not necessary for the current PR but could be considered for future maintenance.
subgraph/core/schema.graphql (1)
145-149
: LGTM! Consider reordering fields for better grouping.The addition of
numberVotes
andeffectiveStake
fields to theCourt
type is well-implemented and aligns with the PR objectives to provide extra statistics. Both fields use appropriate types and constraints.Consider reordering the fields to group related information together. For example:
type Court @entity { # ... (other fields) numberDisputes: BigInt! numberClosedDisputes: BigInt! numberVotingDisputes: BigInt! numberAppealingDisputes: BigInt! numberVotes: BigInt! numberStakedJurors: BigInt! stake: BigInt! effectiveStake: BigInt! delayedStake: BigInt! # ... (remaining fields) }This grouping improves readability and makes it easier to understand related fields at a glance.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (5)
- subgraph/core/schema.graphql (1 hunks)
- subgraph/core/src/entities/Court.ts (2 hunks)
- subgraph/core/src/entities/JurorTokensPerCourt.ts (2 hunks)
- web/.env.devnet.public (1 hunks)
- web/src/hooks/queries/useHomePageBlockQuery.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- web/.env.devnet.public
- web/src/hooks/queries/useHomePageBlockQuery.ts
🔇 Additional comments (3)
subgraph/core/src/entities/JurorTokensPerCourt.ts (3)
7-7
: LGTM: New import forupdateEffectiveStake
The addition of this import statement is appropriate and necessary for the new functionality being introduced. It aligns with the PR objectives of updating court-related data.
Line range hint
1-63
: Summary: Effective implementation of court data updatesThe changes in this file effectively implement the required updates to court data as part of the larger PR objective. The addition of
updateEffectiveStake
ensures that court statistics are kept current, which is crucial for the new homepage features.Key points:
- The changes are minimal but impactful.
- They align well with the PR objectives.
- The implementation maintains consistency with the existing codebase.
These updates form a solid foundation for the new statistics being added to the homepage. Ensure thorough testing of these changes, particularly focusing on the performance and accuracy of the updated court data.
63-63
: Approve addition ofupdateEffectiveStake
, but consider performance impactThe addition of
updateEffectiveStake(courtID)
at the end ofupdateJurorStake
is logical and aligns with the PR objectives. It ensures that the effective stake is recalculated after all other relevant data has been updated.However, given that
updateJurorStake
might be called frequently, it's worth considering the performance impact of this additional function call.To assess the potential performance impact, let's check the implementation of
updateEffectiveStake
:If
updateEffectiveStake
is a computationally expensive operation, consider if it needs to be called on every stake update or if it can be optimized or called less frequently.✅ Verification successful
Let's further investigate the implementation of
updateEffectiveStake
to assess its performance implications.
To further investigate the implementation of
updateEffectiveStake
, please run the following script to search for its definition across the codebase.
Addition of
updateEffectiveStake
verifiedThe
updateEffectiveStake(courtID)
function is correctly implemented and efficiently handles the update by loading the court and ensuring its existence before proceeding. Its lightweight nature ensures that it should not significantly impact performance when called withinupdateJurorStake
.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Check the implementation of updateEffectiveStake function ast-grep --lang typescript --pattern $'function updateEffectiveStake($_) { $$$ }'Length of output: 84
Script:
#!/bin/bash # Description: Search for updateEffectiveStake as a method within classes ast-grep --lang typescript --pattern $'class $$$ { $$$ updateEffectiveStake($_) { $$$ } $$$ }'Length of output: 107
Script:
#!/bin/bash # Description: Broad search for updateEffectiveStake across the codebase rg 'updateEffectiveStake' --context 2Length of output: 1338
There was a problem hiding this 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 (5)
web/tsconfig.json (1)
61-63
: LGTM! Consider expanding the "lib" array for completeness.The addition of "ESNext.Array" to the "lib" array is a good forward-looking change. It allows the use of the latest ECMAScript Array features, which could be beneficial for implementing the new statistics and components mentioned in the PR objectives.
For completeness and to ensure all necessary features are available, consider expanding the "lib" array to include other commonly used libraries. Here's a suggested modification:
"lib": [ + "DOM", + "DOM.Iterable", + "ESNext", "ESNext.Array" ],This change would provide a more comprehensive set of type definitions, including those for DOM manipulation, which is common in web applications.
web/src/components/ExtraStatsDisplay.tsx (3)
1-41
: LGTM! Consider adding responsive styles.The imports and styled components are well-structured and appropriate for the component's functionality. The use of theme values ensures consistency with the overall design system.
Consider adding responsive styles to the
Container
andTextContainer
components to ensure proper layout on different screen sizes. For example:const Container = styled.div` display: flex; gap: 8px; align-items: center; margin-top: 24px; + @media (max-width: 768px) { + flex-direction: column; + align-items: flex-start; + } `; const TextContainer = styled.div` display: flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: center; + @media (max-width: 768px) { + justify-content: flex-start; + } `;
50-60
: LGTM! Consider adding prop types validation.The
ExtraStatsDisplay
component is well-structured and follows React best practices. The conditional rendering and prop usage are implemented correctly.Consider adding prop types validation using the
prop-types
library for runtime type checking. This can help catch errors early in development. For example:import PropTypes from 'prop-types'; // ... component code ... ExtraStatsDisplay.propTypes = { title: PropTypes.string.isRequired, icon: PropTypes.elementType.isRequired, content: PropTypes.node, text: PropTypes.string };
1-62
: Great implementation of the ExtraStatsDisplay component!This new component aligns well with the PR objectives of enhancing the homepage with additional statistics. It's a reusable and flexible solution that should integrate seamlessly with the existing codebase. The use of styled-components, TypeScript, and React best practices ensures maintainability and consistency with the overall project structure.
To further improve the component's reusability and testability, consider extracting the styled components into a separate file (e.g.,
ExtraStatsDisplay.styles.ts
). This separation of concerns can make it easier to maintain and test the component's logic independently of its styling.web/src/hooks/queries/useHomePageBlockQuery.ts (1)
58-76
: LGTM: Well-implemented custom hook with a minor suggestion.The
useHomePageBlockQuery
hook is well-implemented, following React Query best practices. It correctly uses thegraphqlBatcher
for data fetching and passes the necessary parameters.Consider adding a comment explaining the rationale behind setting
staleTime: Infinity
. This choice might impact data freshness, so it's important to document why this setting is appropriate for this particular use case.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (5)
- web/src/components/ExtraStatsDisplay.tsx (1 hunks)
- web/src/hooks/queries/useHomePageBlockQuery.ts (1 hunks)
- web/src/hooks/queries/useHomePageExtraStats.ts (1 hunks)
- web/src/pages/Home/CourtOverview/ExtraStats.tsx (1 hunks)
- web/tsconfig.json (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- web/src/hooks/queries/useHomePageExtraStats.ts
- web/src/pages/Home/CourtOverview/ExtraStats.tsx
🔇 Additional comments (7)
web/src/components/ExtraStatsDisplay.tsx (2)
43-48
: Well-defined interface!The
IExtraStatsDisplay
interface is clear and provides a good structure for the component's props. The use of optional props (content
andtext
) allows for flexible usage of the component.
62-62
: LGTM!The default export of the
ExtraStatsDisplay
component follows the standard practice for React components.web/src/hooks/queries/useHomePageBlockQuery.ts (5)
1-56
: LGTM: Imports and type definitions are well-structured.The imports and type definitions are appropriate for the functionality of the hook. The
CourtWithTree
type extends theCourt
type with additional properties, which is a good practice for type safety and clarity.
78-122
: LGTM: Optimized court data processing implementation.The
processData
function efficiently processes court data, addressing the previous optimization suggestions. Key improvements include:
- Using a set to track processed courts, preventing redundant processing.
- Implementing a recursive approach to handle parent-child relationships.
- Reverse iteration to ensure parent courts are processed before their children.
These optimizations should result in improved performance, especially for larger datasets.
124-161
: LGTM: Well-implemented court metric calculations.The
addTreeValues
andaddTreeValuesWithDiff
functions are well-implemented:
- Correct calculations for various court metrics, including votes per PNK and expected rewards.
- Proper handling of big numbers using BigInt, which is crucial for financial calculations.
- Pure functions without side effects, promoting maintainability and testability.
The implementation correctly handles both all-time and differential (present vs. past) scenarios.
163-168
: LGTM: Efficient and non-mutating sorting functions.The sorting functions are well-implemented:
- Use of
toSorted
method addresses the previous feedback about avoiding mutation of the original array.- Each function has a clear and appropriate sorting criterion.
- The implementations are concise and easy to understand.
This approach maintains the integrity of the original data while providing the necessary sorted results.
1-168
: Great job on implementing the homepage extra statistics feature!This implementation of
useHomePageBlockQuery
successfully addresses the objectives of providing additional statistics for the homepage. Key strengths of this implementation include:
- Well-structured code with clear separation of concerns.
- Efficient data processing with optimized loops and recursive functions.
- Strong type safety through comprehensive type definitions.
- Non-mutating operations that maintain data integrity.
- Adherence to React and React Query best practices.
The code effectively fetches and processes court-related data, calculating various metrics such as most disputed courts, best drawing chances, and expected rewards. It also handles both all-time and specific time range scenarios.
One minor suggestion would be to add a comment explaining the rationale behind
staleTime: Infinity
in theuseQuery
options.Overall, this is a high-quality implementation that should significantly enhance the homepage's informational value.
Code Climate has analyzed commit 94c4074 and detected 13 issues on this pull request. Here's the issue category breakdown:
View more on Code Climate. |
Quality Gate passedIssues Measures |
(kemuru writing)
closes #683
PR-Codex overview
This PR focuses on enhancing the functionality and structure of the application, particularly in the areas of querying and displaying court statistics, improving component styling, and updating the schema for handling disputes and juror data.
Detailed summary
ESNext.Array
totsconfig.json
.courts
to include new fields.CourtOverview
to includeExtraStats
component.useHomePageExtraStats
for fetching additional statistics.Court
entity withnumberVotes
andeffectiveStake
.updateEffectiveStake
function to calculate total stake.DisputeCardView
to use a new skeleton component for loading states.Summary by CodeRabbit
Summary by CodeRabbit
New Features
ExtraStats
component for displaying additional statistics related to court activity over customizable time frames.ExtraStatsDisplay
component for structured display of additional statistics.Bug Fixes
Documentation
Chores