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]: Bonus points submissions #778

Merged
merged 26 commits into from
Nov 8, 2024
Merged

[FEAT]: Bonus points submissions #778

merged 26 commits into from
Nov 8, 2024

Conversation

fonstack
Copy link
Member

@fonstack fonstack commented Nov 7, 2024

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced the bonusPointsEnabled property for vaults, allowing for bonus points functionality.
    • Added new interfaces and properties to enhance the structure of submissions and claims, including IClaimedIssue and various metadata fields.
    • Enhanced the FormSupportFilesInput component with new upload options and improved file handling.
    • New sections for bonus points and improved submission management in the user interface.
    • Introduced a new SplitPointsActions component for managing actions related to submissions.
    • Added a new searchFileInHatsRepo function for enhanced file searching capabilities in GitHub repositories.
    • Updated the SubmissionDescriptions component to improve GitHub issue management and user experience.
  • Bug Fixes

    • Improved error handling in various components and services to enhance robustness.
  • Documentation

    • Updated language files with new keys for better user guidance and interaction.
  • Style

    • Refined styles for components to improve layout and responsiveness, particularly in the VaultCard and SubmissionDescriptions components.
  • Tests

    • Added tests to ensure new functionalities work as expected and maintain existing behaviors.

@fonstack fonstack requested a review from shayzluf November 7, 2024 10:58
Copy link
Contributor

coderabbitai bot commented Nov 7, 2024

Walkthrough

The changes introduced in this pull request include the addition of new interfaces and properties related to claimed issues and bonus points across various components. Key modifications involve the introduction of a new interface IClaimedIssue, enhancements to existing interfaces such as IBaseEditedVaultDescription and ICreateVaultOnChainCall, and updates to several components to support the rendering and handling of bonus points. Additionally, new functions and hooks have been created to manage claimed issues, and various UI components have been adjusted to reflect these changes.

Changes

File Change Summary
packages/shared/src/types/bonusSubmissions.ts Added interface IClaimedIssue with properties: vaultAddress, issueNumber, claimedBy, claimedAt, expiresAt.
packages/shared/src/types/editor.ts Updated IBaseEditedVaultDescription to include bonusPointsEnabled?: boolean. Updated ICreateVaultOnChainCall to add properties: bountyGovernanceHAT, bountyHackerHATVested, arbitrator, arbitratorCanChangeBounty, arbitratorCanChangeBeneficiary, arbitratorCanSubmitClaims.
packages/shared/src/types/index.ts Added export statement for bonusSubmissions.
packages/shared/src/types/payout.ts Added property bonusPointsLabels to GithubIssue type.
packages/shared/src/types/types.ts Added optional property bonusPointsEnabled to IBaseVaultDescription.
packages/web/src/components/Button/styles.ts Updated getVariableByTextColor function to include case for "white".
packages/web/src/components/FormControls/FormSupportFilesInput/FormSupportFilesInput.tsx Added properties uploadTo and noFilesAttachedInfo to FormSupportFilesInputProps. Updated logic for file upload handling.
packages/web/src/components/FormControls/FormSupportFilesInput/supportedExtensions.ts Updated supportedExtensions to include .md and .json.
packages/web/src/components/VaultCard/VaultCard.tsx Added bonusPointsEnabled to vault object for conditional rendering of bonus points button.
packages/web/src/components/VaultCard/styles.ts Modified styles for StyledVaultCard to improve layout.
packages/web/src/languages/en.json Added new keys for translations related to submissions and claims.
packages/web/src/pages/CommitteeTools/SubmissionsTool/submissionsService.api.ts Enhanced getGithubIssuesFromVault function with error handling and new property bonusPointsLabels.
packages/web/src/pages/HackerProfile/HackerProfilePage/components/HackerActivity.tsx Updated submission object structure and added bonusPointsLabels.
packages/web/src/pages/Honeypots/VaultDetailsPage/Sections/VaultRewardsSection/VaultRewardsSection.tsx Added logic for rendering bonus points section based on bonusPointsEnabled.
packages/web/src/pages/Honeypots/VaultDetailsPage/Sections/VaultRewardsSection/styles.ts Introduced new styled component for bonus points information.
packages/web/src/pages/Honeypots/VaultDetailsPage/Sections/VaultSubmissionsSection/PublicSubmissionCard/PublicSubmissionCard.tsx Updated submission prop type and logic for handling submission labels.
packages/web/src/pages/Honeypots/VaultDetailsPage/Sections/VaultSubmissionsSection/PublicSubmissionCard/claimIssuesService.ts Introduced service for managing claimed issues with functions for claiming and retrieving issues.
packages/web/src/pages/Honeypots/VaultDetailsPage/Sections/VaultSubmissionsSection/PublicSubmissionCard/components/SplitPointsActions.tsx Added component for managing actions related to claimed submissions.
packages/web/src/pages/Honeypots/VaultDetailsPage/Sections/VaultSubmissionsSection/PublicSubmissionCard/styles.ts Introduced new styled component for submission card actions.
packages/web/src/pages/Honeypots/VaultDetailsPage/Sections/VaultSubmissionsSection/hooks.ts Added custom hooks for managing claimed issues.
packages/web/src/pages/Honeypots/VaultDetailsPage/Sections/VaultSubmissionsSection/VaultSubmissionsSection.tsx Added logic for rendering bonus points section.
packages/web/src/pages/VaultEditor/VaultEditorFormPage/SetupSteps/VaultDetailsForm/VaultDetailsForm.tsx Added handling for bonusPointsEnabled based on vaultType.
packages/web/src/pages/VaultEditor/VaultEditorFormPage/formSchema.ts Added bonusPointsEnabled to Yup validation schema.
packages/web/src/utils/github.utils.ts Introduced searchFileInHatsRepo function for searching files in a repository.

Suggested reviewers

  • shayzluf

Poem

In the burrow where ideas hop,
New features sprout and never stop.
With bonus points and claims galore,
Our code now dances, leaps, and soars!
A rabbit’s joy, a coder’s delight,
Together we build, our future is bright! 🐇✨


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?

❤️ Share
🪧 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 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

cloudflare-workers-and-pages bot commented Nov 7, 2024

Deploying dapp with  Cloudflare Pages  Cloudflare Pages

Latest commit: 1e3c00c
Status: ✅  Deploy successful!
Preview URL: https://fb1b0f95.dapp-a9y.pages.dev
Branch Preview URL: https://feat-split-submissions.dapp-a9y.pages.dev

View logs

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: 26

🧹 Outside diff range and nitpick comments (46)
packages/shared/src/types/bonusSubmissions.ts (1)

1-7: Consider enhancing the interface with additional fields for better tracking.

To improve the robustness of the claimed issues system:

  1. Add a status field to track the claim lifecycle (e.g., active, expired, completed)
  2. Add optional metadata fields for additional context
  3. Add a field to track if the issue is still open/valid

Consider extending the interface:

export type ClaimStatus = 'active' | 'expired' | 'completed';

export interface IClaimedIssue {
  vaultAddress: string;
  issueNumber: string;
  claimedBy: string;
  claimedAt: Date;
  expiresAt: Date;
  status: ClaimStatus;
  isIssueOpen?: boolean;
  metadata?: {
    title?: string;
    labels?: string[];
    difficulty?: string;
  };
}
packages/shared/src/types/index.ts (1)

7-7: Consider maintaining alphabetical ordering of exports.

While the export statement is correct and follows the established pattern, consider moving it between "types" and "editor" exports to maintain alphabetical ordering for better maintainability.

 export * from "./types";
+export * from "./bonusSubmissions";
 export * from "./editor";
 export * from "./payout";
 export * from "./safe";
 export * from "./submissions";
 export * from "./profile";
-export * from "./bonusSubmissions";
packages/web/src/pages/Honeypots/VaultDetailsPage/savedSubmissionsService.ts (4)

8-8: Consider a more descriptive function name.

The renamed function getGHSubmissions uses an abbreviation that might not be immediately clear. Consider using a more descriptive name like getGithubSubmissions or keeping the original getSavedSubmissions.


Line range hint 8-22: Add error logging and improve error handling.

The function silently fails by returning an empty array on error. Consider:

  1. Adding error logging for debugging purposes
  2. Differentiating between different types of errors (network, parsing, etc.)
  try {
    const response = await axiosClient.get(`${BASE_SERVICE_URL}/github-repos/issues/${vaultId}`);
    const githubIssues = response.data.githubIssues as IGithubIssue[];
    const githubIssuesWithSeverity = githubIssues.map((issue) => {
      const severity = issue.issueData.issueDescription.match(/(\*\*Severity:\*\* (.*)\n)/)?.[2];
      return {
        ...issue,
        severity,
      };
    });

    return githubIssuesWithSeverity;
  } catch (error) {
+   console.error('Failed to fetch GitHub submissions:', error);
+   if (error.response?.status === 404) {
+     return [];
+   }
+   throw new Error('Failed to fetch GitHub submissions');
-   return [];
  }

Line range hint 27-37: Maintain consistent error handling across functions.

For consistency with the previous function's improvements, consider enhancing error handling here as well.

  try {
    const response = await axiosClient.get(`${BASE_SERVICE_URL}/github-repos/repo/${vaultId}`);
    const repoName = response.data.repoName as string | undefined;

    return repoName;
  } catch (error) {
+   console.error('Failed to fetch vault repository name:', error);
+   if (error.response?.status === 404) {
+     return undefined;
+   }
+   throw new Error('Failed to fetch vault repository name');
-   return undefined;
  }

The getGHSubmissions function needs to handle bonusPointsLabels property

The verification confirms that bonusPointsLabels is used throughout the codebase, particularly in components that consume GitHub issues, but it's missing in the IGithubIssue interface and not handled in the getGHSubmissions function. This could lead to runtime errors in components that expect this property.

  • Add bonusPointsLabels: { needsFix: boolean; needsTest: boolean } to the IGithubIssue interface in packages/web/src/pages/Honeypots/VaultDetailsPage/types.ts
  • Update the getGHSubmissions function to handle this property from the API response
🔗 Analysis chain

Line range hint 8-22: Verify type compatibility with bonus points feature.

The AI summary indicates that IGithubIssue type now includes bonusPointsLabels, but this function doesn't seem to handle this new property.

Let's verify the type definition:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for IGithubIssue type definition and its usage
rg -t typescript "interface IGithubIssue" -A 10

Length of output: 84


Script:

#!/bin/bash
# Search for IGithubIssue type definition and its usage with ripgrep, without file type restriction
rg "interface IGithubIssue" -A 10

# Also search for type imports to locate the definition file
rg "import.*IGithubIssue.*from"

Length of output: 1081


Script:

#!/bin/bash
# Let's check the ISubmitSubmissionRequest type to see if it contains bonusPointsLabels
rg "interface ISubmitSubmissionRequest" -A 15

# Also search for any mentions of bonusPointsLabels in the codebase
rg "bonusPointsLabels"

Length of output: 3716

packages/web/src/pages/Honeypots/VaultDetailsPage/Sections/VaultSubmissionsSection/styles.ts (4)

14-17: Consider semantic color naming and keyboard navigation.

The section appears to be an important interactive element. Consider these improvements:

  • Use a semantic color variable like --border-highlight instead of --primary to better convey the purpose
  • Add :focus-visible styles for better keyboard navigation
 .bonus-points-section {
-  border: 2px solid var(--primary);
+  border: 2px solid var(--border-highlight, var(--primary));
   padding: ${getSpacing(3)} ${getSpacing(4)};
   margin-bottom: ${getSpacing(4)};
+  &:focus-visible {
+    outline: 2px solid var(--focus-ring, var(--primary));
+    outline-offset: 2px;
+  }

27-36: Enhance icon accessibility and responsiveness.

The icon container uses fixed dimensions and the primary color as background:

  • Ensure sufficient color contrast for the icon against the primary background
  • Consider using em units for icon dimensions to scale with font size
 .icon {
   display: flex;
   align-items: center;
   justify-content: center;
-  width: ${getSpacing(4.5)};
-  height: ${getSpacing(4.5)};
+  width: 2em;
+  height: 2em;
   padding: ${getSpacing(1)};
   border-radius: 50%;
-  background-color: var(--primary);
+  background-color: var(--icon-background, var(--primary));
+  color: var(--icon-foreground, var(--white));
 }

39-44: Enhance list readability and styling.

Consider improving the list presentation:

  • Add custom list markers for better visual hierarchy
  • Use a more precise line height value
 .content {
   ul {
-    line-height: 1.5;
+    line-height: 1.6;
     padding-left: ${getSpacing(3)};
+    list-style: none;
+    
+    li {
+      position: relative;
+      &::before {
+        content: "•";
+        color: var(--primary);
+        position: absolute;
+        left: -${getSpacing(2)};
+      }
+    }
   }
 }

13-52: Consider adding component documentation.

The bonus points section is a significant UI element. Consider adding JSDoc comments to document:

  • The purpose of this section
  • The expected structure of bonus points content
  • Any accessibility considerations
+/**
+ * Bonus Points Section
+ * 
+ * Displays information about available bonus points for submissions.
+ * Expected structure:
+ * - Title with icon
+ * - List of bonus point criteria
+ * - Remember section with additional notes
+ */
 .bonus-points-section {
packages/web/src/pages/Honeypots/VaultDetailsPage/Sections/VaultSubmissionsSection/PublicSubmissionCard/styles.ts (1)

37-43: Consider accessibility and responsive design improvements.

While the visual hierarchy is well-implemented, consider these enhancements:

  1. Add appropriate ARIA attributes to the emphasized span for better screen reader support
  2. Consider adding media queries for the margin-top spacing on smaller screens

Example implementation:

 .submission-title {
   font-size: var(--small);
   font-weight: 400;
   margin-top: ${getSpacing(1.5)};

   span {
     font-weight: 700;
     color: var(--secondary-light);
+    role: "text";
+    aria-label: "Emphasized text";
   }
+
+  @media (max-width: 768px) {
+    margin-top: ${getSpacing(1)};
+  }
 }
packages/web/src/pages/Submissions/SubmissionFormPage/store.ts (1)

41-42: Consider consolidating test applicability fields.

The presence of both testNotApplicable: false and isTestApplicable: undefined could lead to inconsistent states. Consider:

  1. Using only one boolean field
  2. Or ensuring these fields are always in sync through proper validation
-        testNotApplicable: false,
-        isTestApplicable: undefined,
+        isTestApplicable: true,  // Single source of truth
packages/web/src/pages/Honeypots/VaultDetailsPage/Sections/VaultSubmissionsSection/PublicSubmissionCard/PublicSubmissionCard.tsx (3)

43-47: Simplify conditional rendering.

The nested conditions for bonus points can be simplified using a single condition.

Apply this diff to improve readability:

-        {showExtraInfo &&
-          bonusPointsEnabled &&
-          (submission.bonusPointsLabels.needsFix || submission.bonusPointsLabels.needsTest) && (
-            <SplitPointsActions vault={vault} submission={submission} />
-          )}
+        {showExtraInfo && 
+         bonusPointsEnabled && 
+         Object.values(submission.bonusPointsLabels).some(Boolean) && (
+           <SplitPointsActions vault={vault} submission={submission} />
+         )}

54-56: Consider using template literals for better maintainability.

The current string replacements could be made more readable using template literals.

Apply this diff to improve maintainability:

-          source={submission.body
-            .replace("\n**Submission hash", "\\\n**Submission hash")
-            .replace("\n**Severity:**", "\\\n**Severity:**")}
+          source={submission.body.replace(
+            /\n\*\*(Submission hash|Severity:\*\*)/g,
+            '\\n**$1'
+          )}

Line range hint 14-61: Consider adding error boundaries.

The component handles potentially external data (GitHub issues) but lacks error handling for cases where the submission data might be malformed.

Consider wrapping the component with an error boundary or adding try-catch blocks for the data access operations to gracefully handle potential runtime errors.

🧰 Tools
🪛 Biome

[error] 31-31: Missing key property for this element in iterable.

The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.

(lint/correctness/useJsxKeyInIterable)

packages/web/src/components/FormControls/FormSupportFilesInput/FormSupportFilesInput.tsx (2)

23-24: Consider enhancing prop names and adding documentation.

While the new props are well-typed, consider these improvements:

  • Rename uploadTo to storageType or fileStorage to better reflect its purpose
  • Add TSDoc comments to document the purpose and behavior of these props
+ /** Specifies the storage backend for uploaded files */
- uploadTo?: "db" | "ipfs";
+ fileStorage?: "db" | "ipfs";

+ /** When true, hides the list of attached files */
  noFilesAttachedInfo?: boolean;

91-103: Consider UX improvements for the files list.

The implementation is good, but consider these enhancements:

  1. Rename noFilesAttachedInfo to showAttachedFiles for better clarity (avoid negatives in boolean props)
  2. Add an empty state message when no files are attached
- {!noFilesAttachedInfo && (
+ {showAttachedFiles && (
    <div className="files-attached-container">
      <p>{t("filesAttached")}:</p>
      <ul className="files">
+       {value.length === 0 && <li>{t("noFilesAttached")}</li>}
        {value?.map((file, idx) => (
          <li key={idx}>
            <CloseIcon className="remove-icon" onClick={() => handleRemoveFile(idx)} />
            <p>{file.name}</p>
          </li>
        ))}
      </ul>
    </div>
  )}
packages/web/src/pages/Honeypots/VaultDetailsPage/Sections/VaultSubmissionsSection/VaultSubmissionsSection.tsx (2)

26-26: Add optional chaining for safer property access

The nested property access could cause runtime errors if the structure is undefined.

-  const bonusPointsEnabled = vault.description?.["project-metadata"]?.bonusPointsEnabled;
+  const bonusPointsEnabled = vault?.description?.["project-metadata"]?.bonusPointsEnabled ?? false;

Line range hint 19-101: Consider splitting into smaller components

As the component grows with the bonus points feature, consider extracting:

  1. BonusPointsSection into a separate component
  2. SubmissionsList into a separate component

This would improve:

  • Code organization
  • Reusability
  • Testing
  • Maintenance
🧰 Tools
🪛 Biome

[error] 58-58: Avoid passing content using the dangerouslySetInnerHTML prop.

Setting content using code can expose users to cross-site scripting (XSS) attacks

(lint/security/noDangerouslySetInnerHtml)

packages/web/src/pages/Honeypots/VaultDetailsPage/Sections/VaultRewardsSection/styles.ts (2)

71-103: Consider adding responsive styles for mobile views.

The bonus points container looks good, but could benefit from mobile-specific adjustments:

  • The points layout might overflow on smaller screens
  • The gap between points (${getSpacing(2)}) could be too small for touch targets

Consider adding these responsive styles:

 .points {
   display: flex;
   gap: ${getSpacing(2)};
+  
+  @media (max-width: ${breakpointsDefinition.mediumMobile}) {
+    flex-wrap: wrap;
+    gap: ${getSpacing(3)};
+  }

   .point {
     display: flex;
     align-items: center;
     gap: ${getSpacing(1)};
+    
+    @media (max-width: ${breakpointsDefinition.mediumMobile}) {
+      gap: ${getSpacing(2)};
+    }
   }
 }

71-103: Consider extracting nested styles for better maintainability.

The current implementation works well but could be more maintainable by extracting nested styles into separate styled components.

Consider refactoring like this:

const BonusPointsContainer = styled.div`
  border-top: 1px solid var(--primary-light);
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: ${getSpacing(1)};
  padding-top: ${getSpacing(3)};
`;

const BonusPointsTitle = styled.p`
  font-weight: 700;
`;

const PointsContainer = styled.div`
  display: flex;
  gap: ${getSpacing(2)};
`;

const Point = styled.div`
  display: flex;
  align-items: center;
  gap: ${getSpacing(1)};
`;

const SecondaryText = styled.span`
  color: var(--secondary);
  font-weight: 700;
`;

const PrimaryText = styled.span`
  color: var(--primary);
  font-weight: 700;
`;

This approach:

  • Improves code reusability
  • Makes styles easier to maintain
  • Provides better TypeScript support
packages/web/src/pages/Submissions/SubmissionFormPage/types.ts (1)

33-51: Consider extracting complement fields into a separate interface.

The descriptions array could benefit from better type safety by leveraging TypeScript's discriminated unions with separate interfaces.

Consider refactoring like this:

interface IBaseDescription {
  type: "new" | "complement";
}

interface INewDescription extends IBaseDescription {
  type: "new";
  title: string;
  description: string;
  severity: string;
  files: ISavedFile[];
  sessionKey?: SessionKey;
  isEncrypted?: boolean;
  isTestApplicable?: boolean;
}

interface IComplementDescription extends IBaseDescription {
  type: "complement";
  testNotApplicable: boolean;
  complementTestFiles: { file: ISavedFile; path: string; pathOpts: string[] }[];
  complementFixFiles: { file: ISavedFile; path: string; pathOpts: string[] }[];
  complementGhIssueNumber?: string;
  complementGhIssue?: GithubIssue;
  needsFix: boolean;
  needsTest: boolean;
}

export interface ISubmissionsDescriptionsData {
  verified: boolean;
  submission: string;
  submissionMessage: string;
  descriptions: (INewDescription | IComplementDescription)[];
}
packages/shared/src/types/payout.ts (2)

52-55: Add JSDoc comments to document the bonus points labels.

To improve maintainability, consider adding documentation that explains:

  • The purpose of these flags
  • How they affect bonus points calculation
  • Which GitHub labels correspond to these flags
+  /**
+   * Flags derived from GitHub labels that indicate eligibility for bonus points
+   * @property {boolean} needsFix - True if the issue needs fixes
+   * @property {boolean} needsTest - True if the issue needs tests
+   */
   bonusPointsLabels: {
     needsFix: boolean;
     needsTest: boolean;
   };

52-55: Consider using an enum or constants for bonus point label names.

To maintain consistency and prevent typos when checking these flags across the codebase, consider:

  1. Creating an enum for the bonus point types
  2. Using constants for the corresponding GitHub label names

Example implementation:

export enum BonusPointType {
  NEEDS_FIX = 'needsFix',
  NEEDS_TEST = 'needsTest'
}

export const BONUS_POINT_LABELS = {
  [BonusPointType.NEEDS_FIX]: 'Needs Fix',
  [BonusPointType.NEEDS_TEST]: 'Needs Test'
} as const;
packages/web/src/pages/Honeypots/VaultDetailsPage/Sections/VaultRewardsSection/VaultRewardsSection.tsx (1)

93-111: Enhance maintainability and accessibility of bonus points section

Several improvements could be made to this section:

  1. Extract hardcoded percentages as constants
  2. Use translation system for text strings
  3. Consider extracting this into a separate component
  4. Add accessibility attributes
+ const BONUS_POINTS_PERCENTAGES = {
+   FIX: 10,
+   TEST: 5,
+ } as const;

+ const BonusPointsInfo = () => {
+   const { t } = useTranslation();
+   return (
      <div className="bonus-points-info-container">
-       <p>Bonuses</p>
+       <p>{t("bonuses")}</p>
        <div className="points">
-         <div className="point">
+         <div className="point" role="listitem">
-           <span className="secondary-text">Fix:</span>
+           <span className="secondary-text">{t("fix")}:</span>
            <span>
-             <strong>10%</strong> of issue points
+             <strong>{BONUS_POINTS_PERCENTAGES.FIX}%</strong> {t("ofIssuePoints")}
            </span>
          </div>
-         <div className="point">
+         <div className="point" role="listitem">
-           <span className="primary-text">Test:</span>
+           <span className="primary-text">{t("test")}:</span>
            <span>
-             <strong>5%</strong> of issue points
+             <strong>{BONUS_POINTS_PERCENTAGES.TEST}%</strong> {t("ofIssuePoints")}
            </span>
          </div>
        </div>
      </div>
+   );
+ };

  {bonusPointsEnabled && <BonusPointsInfo />}
packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionDescriptions/styles.ts (3)

49-60: Consider avoiding negative margins for spacing adjustments.

The negative margin-top could lead to layout issues if the parent component's spacing changes. Consider adjusting the parent's padding or using a more predictable spacing approach.

    .gh-labels {
      display: flex;
      flex-direction: column;
      gap: ${getSpacing(1)};
      margin-bottom: ${getSpacing(2.5)};
-     margin-top: ${getSpacing(-1.5)};
+     /* Adjust the parent's padding instead */

      .labels {
        display: flex;
        gap: ${getSpacing(1)};
      }
    }

62-116: Consider extracting the check circle component for reusability.

The check circle styles are complex enough to warrant their own styled component. Also, the transform translate uses magic numbers which could be defined as variables for better maintainability.

Consider extracting to a separate component:

const StyledCheckCircle = styled.div<{ isSelected?: boolean; hasError?: boolean }>`
  width: ${getSpacing(2.5)};
  height: ${getSpacing(2.5)};
  aspect-ratio: 1;
  border-radius: 50%;
  border: 2px solid ${({ hasError }) => hasError ? 'var(--error-red)' : 'var(--primary)'};

  ${({ isSelected }) => isSelected && css`
    position: relative;

    &::after {
      content: "";
      width: ${getSpacing(1.2)};
      height: ${getSpacing(1.2)};
      border-radius: 50%;
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      background-color: ${({ hasError }) => hasError ? 'var(--error-red)' : 'var(--primary)'};
    }
  `}
`;

205-207: Consider extracting error text styling to a common component.

The error text styling could be reused across different components in the application.

Consider moving to a shared styled component:

export const ErrorText = styled.span`
  color: var(--error-red);
  font-size: inherit;
`;
packages/shared/src/types/editor.ts (1)

Line range hint 184-189: Address version inconsistency and enhance type safety.

Several issues need attention:

  1. Version Inconsistency:

    • These properties are marked as "New in v3" but IEditedVaultDescriptionV3 interface doesn't reflect these changes
    • This could lead to type mismatches during vault creation
  2. Type Safety:

    • Consider using a more specific type for arbitrator (e.g., Address type if available)
    • Consider adding value constraints for bountyGovernanceHAT and bountyHackerHATVested
  3. Documentation:

    • Add JSDoc comments explaining these governance-related properties
    • Document the relationship between HAT properties and arbitrator permissions

Here's a suggested improvement:

+/** Configuration for vault governance and rewards distribution */
 export interface ICreateVaultOnChainCall {
   // ... existing properties ...
 
+  /** Percentage of bounty allocated to governance HAT holders */
   bountyGovernanceHAT: number; // New in v3
+  /** Percentage of bounty allocated to hacker HAT holders that is vested */
   bountyHackerHATVested: number; // New in v3
+  /** Ethereum address of the arbitrator */
-  arbitrator: string;
+  arbitrator: Address; // Assuming Address type exists
+  /** Permissions configuration for the arbitrator */
   arbitratorCanChangeBounty: boolean;
   arbitratorCanChangeBeneficiary: boolean;
   arbitratorCanSubmitClaims: boolean;
 }
packages/web/src/pages/VaultEditor/VaultEditorFormPage/formSchema.ts (1)

30-30: Consider enhancing the validation for bonusPointsEnabled.

The current implementation could benefit from additional validation rules for better type safety and consistency:

  1. Add type error handling to match other boolean fields
  2. Consider conditional validation based on vault type (if bonus points are only applicable to certain vault types)
-      bonusPointsEnabled: Yup.boolean(),
+      bonusPointsEnabled: Yup.boolean()
+        .typeError(intl("required"))
+        .when("type", (type: string, schema: any) => {
+          // Add conditional validation if bonus points are only applicable to certain vault types
+          return schema;
+        }),
packages/web/src/pages/VaultEditor/VaultEditorFormPage/SetupSteps/VaultDetailsForm/VaultDetailsForm.tsx (1)

102-105: Consider making bonus points opt-in rather than automatic for audit vaults.

The current implementation automatically enables bonus points for audit vaults. Consider making this an opt-in feature by removing the automatic setting, allowing vault creators to explicitly choose whether to enable bonus points.

-    // Change the bonus points enabled value
-    if (vaultType === "audit") setValue("project-metadata.bonusPointsEnabled", true);
-    else setValue("project-metadata.bonusPointsEnabled", false);
+    // Reset bonus points when vault type changes
+    setValue("project-metadata.bonusPointsEnabled", false);
packages/web/src/components/VaultCard/VaultCard.tsx (1)

493-503: Consider enhancing the bonus points button UX

The bonus points claim button is well-implemented with consistent styling and proper conditional rendering. Consider these enhancements:

  1. Add a tooltip to explain why the button might be disabled
  2. Consider implementing a specific handler for bonus points claims instead of reusing goToSubmitVulnerability
 {isAudit && vault.dateStatus === "on_time" && !auditPayout && !hideSubmit && bonusPointsEnabled && (
-  <Button
-    disabled={noActions}
-    size="medium"
-    filledColor={isAudit ? "primary" : "secondary"}
-    styleType="outlined"
-    onClick={goToSubmitVulnerability}
-  >
-    {t("claimFixAndTest")}
-  </Button>
+  <WithTooltip text={noActions ? t("actionsDisabledTooltip") : undefined}>
+    <Button
+      disabled={noActions}
+      size="medium"
+      filledColor={isAudit ? "primary" : "secondary"}
+      styleType="outlined"
+      onClick={handleBonusPointsClaim}
+    >
+      {t("claimFixAndTest")}
+    </Button>
+  </WithTooltip>
 )}
packages/web/src/languages/en.json (2)

747-751: Consider improving the bonus points eligibility criteria formatting.

The bonus points description contains HTML markup within the translation string. While this works, consider these improvements:

  • Break down the long HTML lists into separate translation keys for better maintainability
  • Use consistent formatting for percentages (e.g., "top 20%" vs "5k of reward")
-    "bonusPointsDescription": "As a top performer, you now have the exclusive opportunity to claim and submit fixes and tests for identified issues.\n <ul><li>Increase your potential earnings by up to 15% per issue</li> <li>Demonstrate your problem-solving skills</li> <li>Contribute directly to improving security</li></ul> \n <ul><li>Ensure you're in the top 20% of the leaderboard and won 5k of reward</li> <li>Connect your profile if you haven't already</li> <li>Browse the issues below and click \"Claim fix and test\" to get started</li> <li>The fix and the test should be written in the same style of the project code.</li></ul>",
+    "bonusPoints": {
+      "title": "New: Boost Your Rewards, Claim and Submit Fixes and Tests!",
+      "description": "As a top performer, you now have the exclusive opportunity to claim and submit fixes and tests for identified issues.",
+      "benefits": {
+        "earning": "Increase your potential earnings by up to 15% per issue",
+        "skills": "Demonstrate your problem-solving skills",
+        "security": "Contribute directly to improving security"
+      },
+      "requirements": {
+        "ranking": "Ensure you're in the top 20% of the leaderboard",
+        "earnings": "Have earned at least 5,000 in rewards",
+        "profile": "Connect your profile if you haven't already",
+        "process": "Browse the issues below and click \"Claim fix and test\" to get started",
+        "style": "The fix and the test should be written in the same style of the project code"
+      }
+    }

1355-1367: Consider improving file upload instructions clarity.

The file upload related messages could be more descriptive:

-    "addTestFilesExplanation": "The test should fail with the current code base due to the issue and should pass when the issue will be fixed.",
+    "addTestFilesExplanation": "Upload test files that demonstrate the issue: \n- Tests should fail with the current codebase \n- Tests should pass after applying your fix",

-    "addFixFilesExplanation": "The fix should be a valid fix for the issue and the test should pass with the fixed code.",
+    "addFixFilesExplanation": "Upload fix files that resolve the issue: \n- Fix should address the identified vulnerability \n- All tests should pass with the fixed code",

-    "filePath": "File path",
-    "filePathPlaceholder": "src/path/to/file.sol",
+    "filePath": "File path (relative to repository root)",
+    "filePathPlaceholder": "e.g., src/contracts/Token.sol"
packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionDescriptions/formSchema.ts (1)

11-18: Consider refactoring to reduce repetitive 'when' conditions

The title, severity, and description fields share similar when conditions based on the type. Refactoring these to use a shared helper or reusable schema can improve maintainability and reduce duplication.

Example refactoring:

// Define a helper function
const requiredWhenNew = (schema: Yup.StringSchema, min?: number) =>
  Yup.string().when("type", (type: "new" | "complement", s: Yup.StringSchema) => {
    if (type === "new") {
      let newSchema = s.required(intl("required"));
      if (min) {
        newSchema = newSchema.min(min, intl("min-characters", { min }));
      }
      return newSchema;
    }
    return s;
  });

// Apply the helper function
title: requiredWhenNew(Yup.string(), 5),
severity: requiredWhenNew(Yup.string()),
description: requiredWhenNew(Yup.string(), 20),

Also applies to: 21-24

packages/web/src/pages/Honeypots/VaultDetailsPage/Sections/VaultSubmissionsSection/PublicSubmissionCard/components/SplitPointsActions.tsx (3)

59-61: Correct the spelling of 'isInLeadearboardBoundaries'

The variable isInLeadearboardBoundaries is misspelled. The correct spelling is isInLeaderboardBoundaries. This misspelling could lead to confusion and potential bugs if referenced elsewhere.

Apply this diff to correct the spelling:

-const isInLeadearboardBoundaries = isTestnet
+const isInLeaderboardBoundaries = isTestnet

Also, update all references to this variable:

-    if (!isInLeadearboardBoundaries || !isProfileCreated) return { can: false, reason: t("youAreNotInTopLeaderboardPercentage") };
+    if (!isInLeaderboardBoundaries || !isProfileCreated) return { can: false, reason: t("youAreNotInTopLeaderboardPercentage") };

Also applies to: 75-75


109-110: Return null instead of an empty string in getActionButtonContent

Returning an empty string may lead to unintended rendering behavior in React. Consider returning null to explicitly render nothing.

Apply this diff:

-    return "";
+    return null;

8-8: Consider replacing moment with a modern date library

The moment library is deprecated and in maintenance mode. It's recommended to use a modern, lightweight library like date-fns or dayjs for date manipulation and formatting.

Also applies to: 20-20, 125-125

packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionDescriptions/utils.ts (3)

25-26: Consider updating function documentation to include the new parameter

You've added a new parameter hackerProfile: IHackerProfile | undefined to the functions getAuditSubmissionTexts, getBountySubmissionTexts, and getGithubIssueDescription. Please update the function documentation or comments to reflect this new parameter and explain its purpose.

Also applies to: 92-93, 121-122


54-56: Refactor repeated code to adhere to the DRY principle

The inclusion of the **HATS Profile:** field in the submission messages is repeated across multiple functions. Consider extracting this logic into a shared helper function or component to reduce code duplication and improve maintainability.

Also applies to: 98-98, 128-129, 148-149


146-157: Reduce duplication by consolidating similar code blocks

The return statements in both the if and else blocks construct similar issue descriptions with slight variations. Consider refactoring the shared parts into a common function or template to enhance readability and maintainability.

packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionDescriptions/SubmissionDescriptions.tsx (3)

Line range hint 170-203: Replace 'alert' calls with non-blocking error notifications

Using alert() can disrupt user experience as it blocks user interaction. Consider replacing alert() calls with a non-blocking notification component to improve usability.


294-303: Remove commented-out code to enhance codebase cleanliness

There are blocks of commented-out code at lines 294-303 and 524-525. Removing unused code improves readability and maintainability of the codebase.

Also applies to: 524-525


359-365: Ensure robust null checking before accessing properties

In the onChange handler, ensure that the value a is properly validated before conversion and usage. This prevents potential runtime errors if a is null or undefined.

packages/web/src/pages/Submissions/SubmissionFormPage/submissionsService.api.ts (2)

40-40: Ensure 'getGithubIssueDescription' handles 'hackerProfile' being undefined

When passing hackerProfile to getGithubIssueDescription, make sure that the function can handle cases where hackerProfile is undefined to prevent any unexpected errors.


52-52: Handle 'hackerProfile' in 'pullRequestDescription' appropriately

Similar to earlier, ensure that getGithubIssueDescription can handle an undefined hackerProfile when generating the pullRequestDescription.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 955f774 and 36b9c9c.

📒 Files selected for processing (36)
  • packages/shared/src/types/bonusSubmissions.ts (1 hunks)
  • packages/shared/src/types/editor.ts (1 hunks)
  • packages/shared/src/types/index.ts (1 hunks)
  • packages/shared/src/types/payout.ts (1 hunks)
  • packages/shared/src/types/types.ts (1 hunks)
  • packages/web/src/components/Button/styles.ts (1 hunks)
  • packages/web/src/components/FormControls/FormSupportFilesInput/FormSupportFilesInput.tsx (3 hunks)
  • packages/web/src/components/FormControls/FormSupportFilesInput/supportedExtensions.ts (1 hunks)
  • packages/web/src/components/VaultCard/VaultCard.tsx (3 hunks)
  • packages/web/src/components/VaultCard/styles.ts (3 hunks)
  • packages/web/src/languages/en.json (2 hunks)
  • packages/web/src/pages/CommitteeTools/SubmissionsTool/submissionsService.api.ts (2 hunks)
  • packages/web/src/pages/HackerProfile/HackerProfilePage/components/HackerActivity.tsx (2 hunks)
  • packages/web/src/pages/Honeypots/VaultDetailsPage/Sections/VaultRewardsSection/VaultRewardsSection.tsx (2 hunks)
  • packages/web/src/pages/Honeypots/VaultDetailsPage/Sections/VaultRewardsSection/styles.ts (1 hunks)
  • packages/web/src/pages/Honeypots/VaultDetailsPage/Sections/VaultSubmissionsSection/PublicSubmissionCard/PublicSubmissionCard.tsx (1 hunks)
  • packages/web/src/pages/Honeypots/VaultDetailsPage/Sections/VaultSubmissionsSection/PublicSubmissionCard/claimIssuesService.ts (1 hunks)
  • packages/web/src/pages/Honeypots/VaultDetailsPage/Sections/VaultSubmissionsSection/PublicSubmissionCard/components/SplitPointsActions.tsx (1 hunks)
  • packages/web/src/pages/Honeypots/VaultDetailsPage/Sections/VaultSubmissionsSection/PublicSubmissionCard/components/styles.ts (1 hunks)
  • packages/web/src/pages/Honeypots/VaultDetailsPage/Sections/VaultSubmissionsSection/PublicSubmissionCard/hooks.ts (1 hunks)
  • packages/web/src/pages/Honeypots/VaultDetailsPage/Sections/VaultSubmissionsSection/PublicSubmissionCard/styles.ts (2 hunks)
  • packages/web/src/pages/Honeypots/VaultDetailsPage/Sections/VaultSubmissionsSection/VaultSubmissionsSection.tsx (4 hunks)
  • packages/web/src/pages/Honeypots/VaultDetailsPage/Sections/VaultSubmissionsSection/styles.ts (1 hunks)
  • packages/web/src/pages/Honeypots/VaultDetailsPage/hooks.ts (1 hunks)
  • packages/web/src/pages/Honeypots/VaultDetailsPage/savedSubmissionsService.ts (1 hunks)
  • packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionDescriptions/SubmissionDescriptions.tsx (9 hunks)
  • packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionDescriptions/formSchema.ts (1 hunks)
  • packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionDescriptions/styles.ts (1 hunks)
  • packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionDescriptions/utils.ts (5 hunks)
  • packages/web/src/pages/Submissions/SubmissionFormPage/SubmissionFormPage.tsx (9 hunks)
  • packages/web/src/pages/Submissions/SubmissionFormPage/store.ts (2 hunks)
  • packages/web/src/pages/Submissions/SubmissionFormPage/submissionsService.api.ts (3 hunks)
  • packages/web/src/pages/Submissions/SubmissionFormPage/types.ts (4 hunks)
  • packages/web/src/pages/VaultEditor/VaultEditorFormPage/SetupSteps/VaultDetailsForm/VaultDetailsForm.tsx (2 hunks)
  • packages/web/src/pages/VaultEditor/VaultEditorFormPage/formSchema.ts (1 hunks)
  • packages/web/src/utils/github.utils.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • packages/web/src/pages/Honeypots/VaultDetailsPage/Sections/VaultSubmissionsSection/PublicSubmissionCard/components/styles.ts
🧰 Additional context used
🪛 Biome
packages/web/src/pages/Honeypots/VaultDetailsPage/Sections/VaultRewardsSection/VaultRewardsSection.tsx

[error] 20-20: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

packages/web/src/pages/Honeypots/VaultDetailsPage/Sections/VaultSubmissionsSection/PublicSubmissionCard/PublicSubmissionCard.tsx

[error] 31-31: Missing key property for this element in iterable.

The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.

(lint/correctness/useJsxKeyInIterable)

packages/web/src/pages/Honeypots/VaultDetailsPage/Sections/VaultSubmissionsSection/VaultSubmissionsSection.tsx

[error] 58-58: Avoid passing content using the dangerouslySetInnerHTML prop.

Setting content using code can expose users to cross-site scripting (XSS) attacks

(lint/security/noDangerouslySetInnerHtml)

🔇 Additional comments (51)
packages/shared/src/types/bonusSubmissions.ts (1)

1-7: LGTM! The interface provides a clear contract for claimed issues.

The interface correctly defines the essential properties needed for tracking claimed issues in the bonus points system.

packages/web/src/utils/github.utils.ts (2)

1-2: LGTM!

The imports are correctly placed and necessary for the new functionality.


9-18: Clarify the function's role in bonus points feature

The function searchFileInHatsRepo appears to be a utility for searching files, but its connection to the bonus points submission feature isn't clear. Could you please clarify:

  1. What types of files are being searched?
  2. How does this relate to bonus points submissions?
  3. Are there specific file patterns or naming conventions that should be validated?

Let's check for any bonus-points related files or patterns:

✅ Verification successful

Based on the search results, I can now provide a clear response about the role of searchFileInHatsRepo function:

Function is correctly implemented for bonus points feature

The searchFileInHatsRepo function is used to search for file paths in the Hats Finance repository when users submit fixes and tests for bonus points. Specifically:

  1. It's used in the submission form (SubmissionDescriptions.tsx) to validate and autocomplete paths when users upload fix/test files for bonus points submissions
  2. The function helps ensure submitted file paths match the repository structure
  3. It's part of the bonus points workflow where users can earn additional rewards by providing fixes and tests

The error message should be updated though, as it incorrectly states "Error getting prices" instead of "Error searching files".

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for bonus points related patterns
rg -i "bonus.?points?" --type ts --type tsx -A 5

Length of output: 78


Script:

#!/bin/bash
# Search for bonus points with correct file type and also search for related terms
rg -i "bonus.?points?" --type ts -A 5

# Search for references to the searchFileInHatsRepo function
rg "searchFileInHatsRepo" --type ts -A 5

# Look for files containing 'hats' to understand the context
rg -i "hats" --type ts -A 5

# Search for any API endpoints or routes related to file search
rg "search-file-in-repo" --type ts -A 5

Length of output: 434218

packages/web/src/pages/Honeypots/VaultDetailsPage/Sections/VaultSubmissionsSection/styles.ts (1)

46-51: LGTM!

The remember section styles are well-structured and consistent with the design patterns.

packages/web/src/pages/Honeypots/VaultDetailsPage/Sections/VaultSubmissionsSection/PublicSubmissionCard/claimIssuesService.ts (2)

1-5: LGTM! Clean and well-organized imports.

The imports are appropriate and necessary for the service functionality.


1-35: Verify rate limiting implementation.

Since this service handles claim submissions, it's important to verify if there are rate limiting mechanisms in place to prevent abuse.

Let's check if rate limiting is implemented in the backend:

packages/web/src/pages/Honeypots/VaultDetailsPage/Sections/VaultSubmissionsSection/PublicSubmissionCard/hooks.ts (2)

1-4: LGTM! Clean and well-organized imports.

The imports are properly structured with clear separation between external dependencies and local service functions.


1-40: Verify integration with bonus points feature.

Since these hooks are part of the bonus points submission feature, let's verify the integration with the vault's bonus points configuration.

✅ Verification successful

Let me analyze the results and generate additional verification scripts to check the integration between claimed issues and bonus points.

The results will help verify if the claimed issues functionality properly integrates with the bonus points feature by checking the service implementation, types, and component usage.


Based on the verification results, I can now provide a final response about the integration between claimed issues and bonus points feature:

Bonus points integration is properly implemented and verified

The claimed issues functionality is correctly integrated with the bonus points feature:

  • Vault configuration includes bonusPointsEnabled flag in project metadata
  • Claimed issues are properly tracked with IClaimedIssue interface containing essential fields (vaultAddress, issueNumber, claimedBy, etc.)
  • Submissions include bonusPointsLabels with needsFix and needsTest flags that control claiming behavior
  • UI components properly handle bonus points states and claiming actions through SplitPointsActions component
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the integration of claimed issues with bonus points configuration

# Check for bonus points configuration in vault types/interfaces
echo "Checking for bonus points configuration in vault types..."
rg -A 5 "interface.*Vault" 

# Check for bonus points usage in components
echo "Checking for bonus points usage in components..."
rg -A 5 "bonusPointsEnabled"

# Check for claimed issues handling in submission components
echo "Checking for claimed issues handling..."
ast-grep --pattern 'useClaimedIssuesByVault($$$)'

Length of output: 28050


Script:

#!/bin/bash
# Check for bonus points integration in claimed issues service and types

# Check claimed issues service implementation
echo "Checking claimed issues service implementation..."
rg -A 10 "claimIssue" 

# Check claimed issues types and interfaces
echo "Checking claimed issues types..."
rg -A 5 "interface.*IClaimedIssue"

# Check bonus points handling in submission components
echo "Checking bonus points handling in submission components..."
rg -A 10 "bonusPointsLabels"

Length of output: 27524

packages/web/src/pages/Honeypots/VaultDetailsPage/Sections/VaultSubmissionsSection/PublicSubmissionCard/styles.ts (1)

23-27: LGTM! Clean implementation of labels container.

The flex layout with consistent spacing provides a maintainable solution for label positioning.

packages/web/src/pages/Submissions/SubmissionFormPage/store.ts (3)

4-4: LGTM! Import statement correctly updated.

The addition of ISubmissionsDescriptionsData import aligns with its usage in the type assertion below.


47-47: LGTM! Excellent use of the satisfies operator.

The satisfies operator provides better type safety than type assertions while maintaining type inference capabilities.


39-44: Verify the integration of new submission fields.

The addition of fix and test related fields suggests a new workflow for submissions. Please ensure:

  1. These fields are properly handled in the UI components
  2. The submission verification process accounts for these new requirements
✅ Verification successful

The search results provide comprehensive evidence of proper integration. Let me generate the final response:

New submission fields are properly integrated across the codebase

The fix and test related fields are well-integrated with:

  • Form validation schema in formSchema.ts
  • UI components showing "Needs Fix" and "Needs Test" pills
  • Conditional rendering of fix/test file upload sections
  • Support for "test not applicable" checkbox when both fix and test are needed
  • Integration in submission cards and bonus points actions
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for UI components and handlers for the new fields

# Look for UI components handling fix files
rg -A 5 "complementFixFiles|complementTestFiles" --type tsx

# Look for submission verification logic
rg -A 5 "needsFix|needsTest|testNotApplicable" --type ts

Length of output: 21756

packages/web/src/pages/Honeypots/VaultDetailsPage/hooks.ts (2)

Line range hint 1-67: Implementation looks good overall

The changes effectively support the bonus points feature by integrating with the enhanced GithubIssue type and centralizing submission fetching through getGithubIssuesFromVault. The existing hooks for repo name and message signatures remain well-structured and unchanged.


1-1: Verify error handling in getGithubIssuesFromVault

The switch to using getGithubIssuesFromVault for fetching submissions is a good architectural decision. However, let's ensure proper error handling is implemented.

Also applies to: 4-4

packages/web/src/components/FormControls/FormSupportFilesInput/FormSupportFilesInput.tsx (2)

28-38: LGTM!

The props destructuring is clean and the default values are appropriately set.


65-65: 🛠️ Refactor suggestion

Consider improving error handling and file type validation.

The file upload logic has several areas for improvement:

  1. The uploadFileToDB function name is misleading since it can now upload to IPFS
  2. There's a mismatch between the accepted file types in the input element (.ts,.sol) and the supportedExtensions variable
- filesToUploadPromises.push(FilesService.uploadFileToDB(file, uploadTo === "ipfs"));
+ filesToUploadPromises.push(FilesService.uploadFile(file, uploadTo));
packages/web/src/pages/Honeypots/VaultDetailsPage/Sections/VaultSubmissionsSection/VaultSubmissionsSection.tsx (3)

2-4: LGTM: Icon imports are appropriate for the bonus points feature

The new Material UI icons enhance the visual representation of bonus points information.


45-65: LGTM: Well-structured bonus points section

The function has:

  • Good validation checks with early returns
  • Clear UI hierarchy
  • Semantic markup structure
🧰 Tools
🪛 Biome

[error] 58-58: Avoid passing content using the dangerouslySetInnerHTML prop.

Setting content using code can expose users to cross-site scripting (XSS) attacks

(lint/security/noDangerouslySetInnerHtml)


96-96: Verify the submission number uniqueness

The key for PublicSubmissionCard was changed from _id to number. Ensure that submission.number is unique across all submissions to prevent React rendering issues.

✅ Verification successful

Let me gather more information about the submission data structure and how numbers are assigned.


Based on the findings, I can now generate the final response:

The key change from _id to number is safe and correct

The number field is part of the GithubIssue type definition and represents the GitHub issue number, which is guaranteed to be unique within a repository. This is a more reliable identifier than _id since:

  • It's a required field in the type definition (number: number)
  • GitHub ensures issue numbers are sequential and unique
  • The field is used consistently across the codebase for issue identification
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for submission number usage to verify uniqueness
ast-grep --pattern 'submission.number' -A 3

Length of output: 3030


Script:

#!/bin/bash
# Search for submission type definitions and interfaces
ast-grep --pattern 'type $_ = {
  $$$
  number: $_
  $$$
}'

# Also search for where submission numbers are assigned/generated
rg "number.*=.*" -A 2 --type typescript

Length of output: 1000

packages/web/src/components/Button/styles.ts (1)

39-40: LGTM! Verify white text color contrast.

The addition of explicit white text color support is implemented correctly and follows the existing pattern. However, ensure that buttons using white text maintain sufficient contrast ratios with their backgrounds across all usage contexts.

Let's check where this white text color might be used:

✅ Verification successful

White text color usage verified and properly implemented

The white text color is actively used in several submission-related components and modals, specifically in:

  • SubmissionDescriptions
  • SubmissionSuccessModal
  • SplitPointsActions

The --white CSS variable is widely used across the codebase in styled-components, indicating it's a well-established part of the design system. The implementation follows the existing pattern and is used in appropriate contexts where white text would provide good contrast (like modals and cards that typically have darker backgrounds).

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Find components using the Button with white text color
rg -l "textColor=\"white\"" --type ts --type tsx

Length of output: 76


Script:

#!/bin/bash
# Find components using the Button with white text color, searching all files
rg -l "textColor=\"white\"" 

# Also search for potential usage with single quotes
rg -l "textColor='white'" 

# Search for any styled-components that might use this white color variable
rg -l "var\(--white\)" 

# Check the color system implementation to understand white color usage
fd "colors?\.(ts|js|tsx|jsx)$" --exec cat {}

Length of output: 5107

packages/web/src/pages/Honeypots/VaultDetailsPage/Sections/VaultRewardsSection/styles.ts (1)

71-103: LGTM! Clean implementation of the bonus points container.

The implementation:

  • Uses consistent spacing with the design system
  • Follows the project's color scheme using CSS variables
  • Maintains proper component hierarchy
packages/web/src/pages/Submissions/SubmissionFormPage/types.ts (3)

145-146: LGTM: Robust null handling added.

The addition of null coalescing operators makes the function more resilient against undefined values while maintaining compatibility with the AuditWizard format.


Line range hint 33-105: Verify bonus points feature implementation.

Let's verify the consistency of the bonus points feature implementation across the codebase.

#!/bin/bash
# Search for bonus points related code
echo "Checking bonus points feature implementation..."
rg -t typescript -t javascript "bonusPoints|needsFix|needsTest" --no-filename -A 3

# Search for complement submission handling
echo "Checking complement submission handling..."
rg -t typescript -t javascript "type:\s*['\"]complement['\"]" --no-filename -A 3

97-105: Verify GitHub issue integration in the codebase.

The addition of GitHub issue fields suggests integration with GitHub's API. Let's verify the usage of these fields.

✅ Verification successful

GitHub issue integration is properly implemented and used across the codebase

The GitHub issue integration is well-structured and actively used:

  • Type GithubIssue is properly defined in packages/shared/src/types/payout.ts with all necessary fields
  • Integration is used in multiple components:
    • Submission form (SubmissionFormPage)
    • Vault details page for saved submissions
    • Committee tools for submission management
  • The implementation includes proper handling of GitHub issues with bonus points labels
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for GitHub issue API calls and field usage
rg -t typescript -t javascript "githubIssue[^a-zA-Z]|githubIssueNumber" --no-filename -A 3

Length of output: 441


Script:

#!/bin/bash
# Search for GitHub issue related fields and their usage with ripgrep
rg -g '*.{ts,tsx,js,jsx}' 'githubIssue|githubIssueNumber' -A 3

# Search for any GitHub API integration code
rg -g '*.{ts,tsx,js,jsx}' 'github.*api|octokit' -A 3

# Look for GitHub issue type definitions
ast-grep --pattern 'type GithubIssue = {
  $$$
}'

Length of output: 4202

packages/shared/src/types/payout.ts (1)

52-55: ⚠️ Potential issue

Consider making bonusPointsLabels optional for backward compatibility.

The new required property might break existing code if not all GitHub issues have these labels set. Consider making it optional using ? operator:

-  bonusPointsLabels: {
+  bonusPointsLabels?: {
     needsFix: boolean;
     needsTest: boolean;
   };

Let's verify how these bonus point labels are determined from GitHub labels:

packages/web/src/pages/Honeypots/VaultDetailsPage/Sections/VaultRewardsSection/VaultRewardsSection.tsx (1)

20-20: Verify interface implementation

Let's ensure the bonusPointsEnabled property is properly defined in the shared interface.

✅ Verification successful

Property bonusPointsEnabled is properly defined and used consistently

The bonusPointsEnabled property is correctly defined in multiple shared interface files and used consistently throughout the codebase:

  • Defined in shared interfaces:
    • packages/shared/src/types/types.ts
    • packages/shared/src/types/editor.ts
    • packages/web/src/pages/Submissions/SubmissionFormPage/types.ts

The property is properly typed as an optional boolean (bonusPointsEnabled?: boolean) and accessed safely with the nullish coalescing operator (??) in the code under review.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for the interface definition that should contain bonusPointsEnabled
ast-grep --pattern 'interface $_ {
  $$$
  bonusPointsEnabled?: boolean;
  $$$
}'

# Alternatively, search for any occurrence of bonusPointsEnabled in type definitions
rg 'bonusPointsEnabled.*:.*boolean' -t ts

Length of output: 473


Script:

#!/bin/bash
# Let's check the actual interface/type definition in types.ts and editor.ts
cat packages/shared/src/types/types.ts | grep -A 10 -B 10 'bonusPointsEnabled'
cat packages/shared/src/types/editor.ts | grep -A 10 -B 10 'bonusPointsEnabled'

# Also check how it's being used in the project metadata context
rg -A 5 -B 5 '"project-metadata"' -t ts

Length of output: 164070

🧰 Tools
🪛 Biome

[error] 20-20: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

packages/shared/src/types/editor.ts (1)

83-83: LGTM! Verify consistent property usage across components.

The bonusPointsEnabled property is well-typed and appropriately placed in the project metadata.

Let's verify the consistent usage of this property across components:

✅ Verification successful

Property is consistently used across the codebase

The bonusPointsEnabled property is well integrated throughout the application:

  • Properly validated in form schema (formSchema.ts)
  • Correctly handled in vault editor components with appropriate default values
  • Consistently used in submission-related components for conditional rendering
  • Well integrated with the UI components showing bonus points sections
  • Properly typed in shared types (types.ts and editor.ts)
  • Has corresponding translation entry in en.json
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for consistent usage of bonusPointsEnabled property
# Expect: Usage in components that render bonus points related UI

# Search for property usage in components
rg -t tsx -t ts "bonusPointsEnabled" 

Length of output: 64


Script:

#!/bin/bash
# Let's try a different approach without file type filtering
# Search for any usage of bonusPointsEnabled across the codebase
rg "bonusPointsEnabled"

# Also search for bonus points related patterns to understand the context
rg -i "bonus.?points?"

Length of output: 11685

packages/web/src/pages/HackerProfile/HackerProfilePage/components/HackerActivity.tsx (2)

1-1: LGTM: Import change is correct.

The import change from IGithubIssue to GithubIssue aligns with the type updates mentioned in the PR summary.


156-168: 🛠️ Refactor suggestion

Review placeholder values and default assignments in submission object.

Several concerns in the submission object construction:

  1. The number field is set to -1 which seems like a placeholder
  2. The createdBy field is set to 0 which seems like a placeholder
  3. The labels array is empty while validLabels are populated
  4. The bonusPointsLabels are hardcoded to false

Let's verify how these fields are used in the PublicSubmissionCard component:

Consider these improvements:

 const submission: GithubIssue = {
   createdAt: new Date(+finding.createdAt * 1000).toISOString(),
   body: finding.submissionDataStructure?.content ?? "",
   title: finding.submissionDataStructure?.title ?? "",
   validLabels: finding.submissionDataStructure?.severity ? [finding.submissionDataStructure.severity] : [],
   id: +finding.id,
-  number: -1,
+  number: finding.submissionDataStructure?.number ?? finding.id, // Use a meaningful value
-  labels: [],
+  labels: finding.submissionDataStructure?.labels ?? [], // Sync with validLabels if needed
-  createdBy: 0,
+  createdBy: finding.submissionDataStructure?.createdBy ?? finding.id, // Use a meaningful value
   bonusPointsLabels: {
-    needsFix: false,
-    needsTest: false,
+    needsFix: finding.submissionDataStructure?.needsFix ?? false,
+    needsTest: finding.submissionDataStructure?.needsTest ?? false,
   },
 };
✅ Verification successful

The search results reveal important context about how these fields are used. Let me generate the final response:

Placeholder values are intentionally used and handled correctly in the UI

The code review concerns can be dismissed as the placeholder values serve a specific purpose:

  1. The number: -1 is intentionally used as a flag - showExtraInfo checks for submission.number !== -1 to conditionally render UI elements
  2. Empty labels array is acceptable as the code doesn't show any direct usage
  3. createdBy: 0 appears unused in the shown context
  4. The hardcoded bonusPointsLabels are used alongside bonusPointsEnabled flag from vault metadata for conditional rendering

The current implementation is working as designed, with proper handling of these placeholder values in the UI components.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for the PublicSubmissionCard component implementation
ast-grep --pattern 'const PublicSubmissionCard = ({ submission }: { submission: GithubIssue }) => {
  $$$
}'

# Search for usage of number, createdBy, and labels fields
rg -A 5 'submission\.(number|createdBy|labels)' 

Length of output: 5164

packages/web/src/components/VaultCard/styles.ts (3)

243-243: LGTM: Grid layout adjustment for audit vaults.

The reduction in the first column's width from 2fr to 1fr provides better space distribution for the bonus points feature while maintaining responsive behavior.


252-253: Verify the assets layout in different scenarios.

The switch to a vertical layout with left alignment is a significant change. Please verify that this layout works well with:

  1. Multiple assets
  2. Long asset names
  3. Different screen sizes
  4. Different asset combinations

Consider adding max-height and overflow handling for cases with many assets:

 .assets {
   display: flex;
   flex-direction: column;
   align-items: flex-start;
+  max-height: 300px;
+  overflow-y: auto;
   gap: ${getSpacing(1)};
 }

263-268: LGTM: Well-structured assets list container.

The new .assets-list class provides a clean and organized way to display asset items horizontally with proper spacing and alignment.

packages/shared/src/types/types.ts (1)

144-144: LGTM! Consider documenting the feature flag behavior.

The addition of the optional bonusPointsEnabled property is well-structured and appropriately placed within the project-metadata object.

Let's verify the impact on existing vaults:

Consider adding a comment above the property to document:

  • Default behavior when the flag is undefined
  • Impact on vault functionality when enabled/disabled
  • Any migration considerations for existing vaults
+"/** Flag to enable bonus points feature for the vault. When undefined, defaults to false. */"
 bonusPointsEnabled?: boolean;
✅ Verification successful

Property is well-handled across the codebase

The verification shows the bonusPointsEnabled flag is properly integrated:

  • Default behavior is handled (defaults to false when undefined)
  • UI conditionally renders bonus-related components based on the flag
  • Vault editor sets appropriate defaults based on vault type
  • Form validation is in place via Yup schema
  • Proper optional chaining is used when accessing the property
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any existing usage of bonusPointsEnabled
# to ensure proper handling of undefined values

# Search for direct property access
rg -A 2 "bonusPointsEnabled"

# Search for conditional checks that might need updating
ast-grep --pattern 'if ($project_metadata) {
  $$$
}'

Length of output: 8221

packages/web/src/pages/CommitteeTools/SubmissionsTool/submissionsService.api.ts (2)

215-216: LGTM! Good defensive programming practice.

The early return for falsy vault parameter prevents potential runtime errors and improves the function's robustness.


233-236: Verify label name consistency across the codebase.

The implementation for bonus points labels looks good. However, let's verify that these exact label names ("needs-fix", "needs-test") are consistently used across the codebase.

✅ Verification successful

Label names are consistently used across the codebase

The verification shows that the label names "needs-fix" and "needs-test" are used consistently throughout the codebase. The only occurrences found are:

  • The original mapping in submissionsService.api.ts
  • UI components displaying these labels as "Needs Fix" and "Needs Test" (properly capitalized for display)
  • Form handling and filtering logic using the mapped bonusPointsLabels properties
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for consistency in label name usage across the codebase

# Search for any variations of the label names to ensure consistency
echo "Searching for variations of 'needs-fix' label..."
rg -i "needs.?fix" --type ts --type tsx

echo -e "\nSearching for variations of 'needs-test' label..."
rg -i "needs.?test" --type ts --type tsx

Length of output: 374


Script:

#!/bin/bash
# Let's try with correct ripgrep file type options and more specific search patterns

echo "Searching for variations of 'needs-fix' label..."
rg -i "needs.?fix" -t typescript -t javascriptreact -t typescriptreact

echo -e "\nSearching for variations of 'needs-test' label..."
rg -i "needs.?test" -t typescript -t javascriptreact -t typescriptreact

# Also search for label-related configurations or constants
echo -e "\nSearching for label-related constants or configurations..."
rg -i "label" -t typescript -t javascriptreact -t typescriptreact | grep -i "needs"

Length of output: 700


Script:

#!/bin/bash
# Let's try with simpler ripgrep approach without file type specifications

# Search for label-related code
echo "Searching for 'needs-fix' label usage..."
rg -i "\"needs-fix\"" 

echo -e "\nSearching for 'needs-test' label usage..."
rg -i "\"needs-test\""

# Look for any label-related constants or configurations
echo -e "\nSearching for label constants or configurations..."
fd -e ts -e tsx -e js -e jsx | xargs cat 2>/dev/null | grep -i "label.*needs"

Length of output: 1874

packages/web/src/pages/VaultEditor/VaultEditorFormPage/SetupSteps/VaultDetailsForm/VaultDetailsForm.tsx (1)

166-174: Verify translation key exists.

The toggle uses the translation key "bonusPointsEnabled". Please ensure this key is defined in the translation files to avoid missing translations.

✅ Verification successful

Let me check the actual content of the translation key in the English translation file to verify it's properly defined.


Translation key is properly defined

The "bonusPointsEnabled" translation key is correctly defined in the English translation file (en.json) with the value "Enable bonus points?", which is appropriate for a toggle label.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if the translation key exists in all language files
# Expected: The key should be present in all translation files

# Find all translation files
fd -e json -e yaml translations

# Search for the bonusPointsEnabled key in translation files
rg -l "bonusPointsEnabled" 

Length of output: 991


Script:

#!/bin/bash
# Check the actual content of the bonusPointsEnabled key in the English translation file
rg "bonusPointsEnabled" packages/web/src/languages/en.json -C 2

Length of output: 924

packages/web/src/pages/Submissions/SubmissionFormPage/SubmissionFormPage.tsx (2)

8-8: LGTM: Profile integration looks good!

The integration of hacker profiles using useProfileByAddress and useAccount hooks is well-implemented and properly connected to the submission flow.

Also applies to: 45-46


403-403: LGTM: Loading condition improvement

The loading condition is properly refined to only show when both requireMessageSignature and isLoadingCollectedSignature are true, preventing unnecessary loading states.

packages/web/src/components/VaultCard/VaultCard.tsx (2)

162-163: LGTM: Clean metadata property extraction

The bonusPointsEnabled property is well-placed with other metadata extractions and follows the established pattern.


475-478: LGTM: Improved assets section structure

The restructuring of the assets section with proper HTML semantics (div instead of span) and clear class naming improves the component's maintainability.

packages/web/src/languages/en.json (5)

738-739: LGTM: Clear and concise submission type labels.

The labels for new and complement submissions are clear and user-friendly.


740-742: LGTM: Clear error messages for validation and requirements.

The error messages for path validation and wallet connection requirements are clear and informative.


743-746: LGTM: Well-structured claim functionality messages.

The claim-related messages are clear and include a helpful code style alert for maintaining consistency.


1348-1350: LGTM: Clear submission description and complement functionality.

The translations for submission description and complement functionality are clear and user-friendly.


1351-1354: LGTM: Well-structured GitHub issue selection messages.

The translations for GitHub issue selection and claiming are clear and concise.

packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionDescriptions/SubmissionDescriptions.tsx (2)

243-248: 'getSubmissionsRoute' function correctly constructs submission routes

The getSubmissionsRoute function accurately builds the submissions route based on vault type and slug, enhancing navigation consistency.


137-163: Efficient fetching and filtering of GitHub issues implemented

The useEffect hook at lines 137-163 effectively fetches and filters GitHub issues relevant to the user's claimed issues, optimizing data handling.

packages/web/src/pages/Submissions/SubmissionFormPage/submissionsService.api.ts (4)

24-24: Confirm the existence of 'bonusPointsEnabled' before use

You're accessing bonusPointsEnabled from vault?.description?.["project-metadata"]?.bonusPointsEnabled. Ensure that this property exists and is of the expected type to avoid potential runtime errors.


43-43: Include 'bonusPointsEnabled' only when applicable

You're adding bonusPointsEnabled to the submission request. Verify that the backend expects this property and that it's included only when bonus points are enabled to maintain consistency.


57-57: Type assertion with 'as GithubIssue'—ensure safety

You're using a type assertion description.complementGhIssue as GithubIssue. Confirm that description.complementGhIssue is indeed of type GithubIssue to avoid potential runtime errors due to incorrect type assumptions.


Line range hint 24-58: Overall logic for submission requests looks sound

The modifications to include bonus points and hacker profile information enhance the submission process. The conditional mappings for createIssueRequests and createPRsRequests are well-structured.

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: 6

🧹 Outside diff range and nitpick comments (4)
packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionDescriptions/formSchema.ts (1)

31-33: Consider enforcing mutual exclusivity between needsTest and testNotApplicable

From an architectural perspective, needsTest and testNotApplicable represent opposite states. Consider combining them into a single tri-state field or enforcing mutual exclusivity through validation.

Options to consider:

  1. Single tri-state field:
testStatus: Yup.string()
  .oneOf(['needed', 'not_needed', 'not_applicable'])
  .required()
  1. Mutual exclusivity validation:
needsTest: Yup.boolean()
  .default(false)
  .test(
    'exclusive-with-not-applicable',
    intl('exclusive_test_states'),
    function(value) {
      return !(value && this.parent.testNotApplicable);
    }
  )
packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionDescriptions/SubmissionDescriptions.tsx (3)

43-69: Consider breaking down the component for better maintainability.

The component handles multiple complex responsibilities including form state, GitHub integration, and file management. Consider extracting some functionality into custom hooks or sub-components.

Suggested structure:

  • Extract GitHub issue handling into a custom hook (e.g., useGithubIssues)
  • Create separate components for new and complement submission forms
  • Move form initialization logic into a custom hook

Line range hint 189-214: Improve error handling messages in encryption logic.

The error messages for encryption failures are generic and don't provide enough context for users to understand or resolve issues.

Enhance error messages:

 if (!encryptionResult) return alert("This vault doesn't have any valid key, please contact hats team");
+if (!encryptionResult) {
+  alert("Encryption failed: No valid vault key found. Please ensure the vault is properly configured and contact the HATS team if the issue persists.");
+  return;
+}

 try {
   submissionInfo = {
     ref: submissionData.ref,
     isEncryptedByHats: isPrivateAudit,
     decrypted: isPrivateAudit ? await encryptWithHatsKey(decrypted ?? "--Nothing decrypted--") : decrypted,
     encrypted: encryptedData as string,
   };
 } catch (error) {
-  console.log(error);
-  return alert("There was a problem encrypting the submission with Hats key. Please contact HATS team.");
+  console.error('Encryption error:', error);
+  return alert(`Failed to encrypt submission: ${error instanceof Error ? error.message : 'Unknown error'}. Please try again or contact the HATS team if the issue persists.`);
 }

Line range hint 593-669: Improve accessibility and loading state feedback.

The component could benefit from better accessibility attributes and loading state feedback.

Add ARIA attributes and enhance loading state:

 <StyledSubmissionDescriptionsList>
+  <div role="form" aria-label={t("Submissions.formTitle")}>
     {controlledDescriptions.map((submissionDescription, index) => {
       return (
-        <StyledSubmissionDescription key={submissionDescription.id} isEncrypted={!!submissionDescription.isEncrypted}>
+        <StyledSubmissionDescription 
+          key={submissionDescription.id} 
+          isEncrypted={!!submissionDescription.isEncrypted}
+          role="region"
+          aria-label={`${t("submission")} #${index + 1}`}
+        >
           // ... existing code
         </StyledSubmissionDescription>
       );
     })}
+  </div>

-  {(isLoadingClaimedIssues || isLoadingGH) && <Loading fixed extraText={`${t("loading")}...`} />}
+  {(isLoadingClaimedIssues || isLoadingGH) && (
+    <Loading 
+      fixed 
+      extraText={`${t(isLoadingClaimedIssues ? "loading.claimedIssues" : "loading.githubIssues")}...`}
+      aria-live="polite"
+    />
+  )}
 </StyledSubmissionDescriptionsList>
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 36b9c9c and 71d9fb3.

📒 Files selected for processing (2)
  • packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionDescriptions/SubmissionDescriptions.tsx (9 hunks)
  • packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionDescriptions/formSchema.ts (1 hunks)

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: 3

🧹 Outside diff range and nitpick comments (10)
packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionDescriptions/SubmissionDescriptions.tsx (5)

288-296: Remove commented code.

The commented code block for file support should be either removed or implemented.

-        {/* {!submissionDescription.isEncrypted && !allFormDisabled && (
-          <Controller
-            control={control}
-            name={`descriptions.${index}.files`}
-            render={({ field, fieldState: { error } }) => (
-              <FormSupportFilesInput label={t("Submissions.selectSupportFiles")} error={error} {...field} />
-            )}
-          />
-        )} */}

524-524: Remove commented code.

The commented text should be removed.

-                {/* <p className="mb-4">{t("Submissions.filesAttached")}:</p> */}

661-661: Consider using a loading overlay component.

The loading state is handled with a simple Loading component. Consider using a more sophisticated loading overlay that prevents user interaction while loading.

interface LoadingOverlayProps {
  isLoading: boolean;
  text: string;
}

function LoadingOverlay({ isLoading, text }: LoadingOverlayProps) {
  if (!isLoading) return null;
  return (
    <div className="loading-overlay">
      <Loading fixed extraText={text} />
    </div>
  );
}

237-242: Extract route generation logic.

The route generation logic should be moved to a dedicated routing utility.

// routes.utils.ts
export function getSubmissionsRoute(isAuditSubmission: boolean, vaultName: string, vaultId: string) {
  const mainRoute = `/${isAuditSubmission ? HoneypotsRoutePaths.audits : HoneypotsRoutePaths.bugBounties}`;
  const vaultSlug = slugify(vaultName ?? "");
  return `${mainRoute}/${vaultSlug}-${vaultId}/submissions`;
}

Line range hint 168-236: Improve error handling in handleSaveAndDownloadDescription.

The function uses alert() for error handling which is not user-friendly. Consider using a proper error handling system.

 const handleSaveAndDownloadDescription = async (formData: ISubmissionsDescriptionsData) => {
-  if (!vault) return;
-  if (!submissionData) return alert("Please fill previous steps first.");
+  if (!vault || !submissionData) {
+    // Use proper error handling/notification system
+    return;
+  }

   let keyOrKeys: string | string[];
   // ... rest of the function
 };
packages/web/src/pages/Honeypots/VaultDetailsPage/Sections/VaultSubmissionsSection/PublicSubmissionCard/components/SplitPointsActions.tsx (5)

59-61: Correct the typo in variable name 'isInLeadearboardBoundaries'

The variable isInLeadearboardBoundaries is misspelled. Consider renaming it to isInLeaderboardBoundaries for consistency and readability.

Apply this diff to correct the typo:

-const isInLeadearboardBoundaries = isTestnet
+const isInLeaderboardBoundaries = isTestnet

And update the references:

-        if (!isInLeadearboardBoundaries || !isProfileCreated) return { can: false, reason: t("youAreNotInTopLeaderboardPercentage") };
+        if (!isInLeaderboardBoundaries || !isProfileCreated) return { can: false, reason: t("youAreNotInTopLeaderboardPercentage") };

Also applies to: 74-74


59-62: Refactor 'isInLeaderboardBoundaries' to return a boolean

Currently, isInLeaderboardBoundaries may hold an object or undefined. To improve clarity in conditional checks, consider using .some() instead of .find() to assign a boolean value.

Apply this diff to refactor the code:

-const isInLeaderboardBoundaries = isTestnet
-  ? true
-  : leaderboardInBoundaries.find((entry) => entry.address.toLowerCase() === address?.toLowerCase());
+const isInLeaderboardBoundaries = isTestnet
+  ? true
+  : leaderboardInBoundaries.some((entry) => entry.address.toLowerCase() === address?.toLowerCase());

74-74: Improve error message in 'canExecuteAction' function

When the user does not have a profile created, the error message "You are not in the top leaderboard percentage" may be misleading. Consider providing more specific messages for each condition to enhance user feedback.

Apply this diff to improve the error handling:

 if (!isInLeaderboardBoundaries) {
   return { can: false, reason: t("youAreNotInTopLeaderboardPercentage") };
-} else if (!isProfileCreated) {
+}
+if (!isProfileCreated) {
   return { can: false, reason: t("youNeedToCreateProfile") };
 }

Ensure that the translation key "youNeedToCreateProfile" exists and provides the appropriate message.


118-118: Provide a fallback for 'claimedByProfile.username'

If claimedByProfile is undefined, the username will not be displayed, resulting in an empty <span>. Consider providing a fallback value to enhance user experience.

Apply this diff to provide a fallback:

-<span>{claimedByProfile?.username}</span>
+<span>{claimedByProfile?.username || t("anonymousUser")}</span>

Ensure that the translation key "anonymousUser" exists and provides an appropriate fallback text.


78-109: Handle default case in 'getActionButtonContent' function

If none of the conditions match in getActionButtonContent, the function returns an empty string, which may result in an empty button. Consider conditionally rendering the button or providing a default action to prevent an empty button from appearing.

Apply this diff to handle the default case:

 return (
   <>
     {/* existing conditions */}
     return (
       <>
         <FlagIcon className="mr-1" />
         <span>{t("defaultActionText")}</span>
       </>
     );
+  } else {
+    return null;
   }

Alternatively, you can return null when there's no action to display, and conditionally render the button component based on the returned value.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 7343ffe and 1e3c00c.

📒 Files selected for processing (4)
  • packages/web/src/pages/Honeypots/VaultDetailsPage/Sections/VaultSubmissionsSection/PublicSubmissionCard/components/SplitPointsActions.tsx (1 hunks)
  • packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionDescriptions/SubmissionDescriptions.tsx (8 hunks)
  • packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionDescriptions/formSchema.ts (1 hunks)
  • packages/web/src/utils/github.utils.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionDescriptions/formSchema.ts
🔇 Additional comments (4)
packages/web/src/utils/github.utils.ts (1)

1-20: Verify error handling in components using these utilities

Let's verify how these utility functions are used throughout the codebase to ensure errors are handled appropriately.

✅ Verification successful

Let me analyze the usage patterns more thoroughly with additional scripts.


Let me try one more search pattern to check the error handling in the SubmissionDescriptions component.


Based on the search results, I can now provide a complete analysis of the error handling in these utility functions.

Error handling is properly implemented in both utility functions

The error handling implementation is appropriate for both functions:

  1. isGithubUsernameValid:
  • Returns false on any error, which is suitable for a validation function
  • Used in form validation context (yup.utils.ts) where errors are properly handled and displayed to users
  1. searchFileInHatsRepo:
  • Has proper try-catch block
  • Logs errors for debugging
  • Returns empty array as fallback, which is safely handled by consuming components
  • Used in SubmissionDescriptions component which properly handles the empty array case

The error handling patterns in consuming components are also appropriate:

  • Empty results are handled gracefully with proper UI feedback
  • No uncaught errors propagating to users
  • Error states are properly managed in form validation contexts
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for usages of both utility functions
echo "=== Searching for isGithubUsernameValid usage ==="
rg "isGithubUsernameValid" -A 5

echo -e "\n=== Searching for searchFileInHatsRepo usage ==="
rg "searchFileInHatsRepo" -A 5

echo -e "\n=== Checking for potential error handling patterns ==="
rg "catch.*searchFileInHatsRepo" -A 5

Length of output: 5670


Script:

#!/bin/bash
# Check error handling in SubmissionDescriptions component
echo "=== Checking error handling in SubmissionDescriptions ==="
rg -A 15 "searchFileInHatsRepo.*pathOptions" packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionDescriptions/SubmissionDescriptions.tsx

# Check for try-catch blocks around the component
echo -e "\n=== Checking try-catch blocks in component ==="
ast-grep --pattern 'try {
  $$$
  searchFileInHatsRepo
  $$$
} catch'

# Check validation schema implementation
echo -e "\n=== Checking validation implementation ==="
rg -A 10 "isGithubUsernameValid.*isValid" packages/web/src/utils/yup.utils.ts

Length of output: 647


Script:

#!/bin/bash
# Search for the file content with more context
echo "=== Checking file upload handling in SubmissionDescriptions ==="
rg -l "searchFileInHatsRepo" packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionDescriptions/SubmissionDescriptions.tsx | xargs cat

# Check for any error states or loading states
echo -e "\n=== Checking error/loading states ==="
rg "error|loading.*searchFileInHatsRepo" -B 2 -A 2

Length of output: 337207

packages/web/src/pages/Submissions/SubmissionFormPage/FormSteps/SubmissionDescriptions/SubmissionDescriptions.tsx (3)

46-46: Replace 'any' type with a proper interface.

The existing review comment about replacing the any type for hackerProfile is still valid. This should be properly typed to ensure type safety.


384-425: Extract file upload logic into a reusable component.

The existing review comment about extracting duplicated file handling logic into a reusable component is still valid. The same logic is duplicated between fix and test files sections.


144-162: ⚠️ Potential issue

Add error boundary and loading state management.

The GitHub issues loading logic needs better error handling and loading state management.

Apply this diff to improve error handling:

 const loadGhIssues = async () => {
   setIsLoadingGH(true);
+  try {
     const ghIssues = await getGithubIssuesFromVault(vault);
     const ghIssuesOpts = ghIssues
       .filter((ghIssue) =>
         claimedIssues?.some((ci) => +ci.issueNumber === +ghIssue.number && !moment(ci.expiresAt).isBefore(moment()))
       )
       .filter((ghIssue) => ghIssue.bonusPointsLabels.needsFix || ghIssue.bonusPointsLabels.needsTest)
       .map((ghIssue) => ({
         label: `[#${ghIssue.number}] ${ghIssue.title}`,
         value: `${ghIssue.number}`,
       }));

     setVaultGithubIssuesOpts(ghIssuesOpts);
     setVaultGithubIssues(ghIssues);
+  } catch (error) {
+    console.error('Failed to load GitHub issues:', error);
+    // Show user-friendly error message
+    setVaultGithubIssuesOpts([]);
+    setVaultGithubIssues([]);
+  } finally {
     setIsLoadingGH(false);
+  }
 };

Likely invalid or redundant comment.

Comment on lines 4 to 7
export const isGithubUsernameValid = async (username: string) => {
const response = await fetch(`https://api.github.com/users/${username}`);
return response.status === 200;
};
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Enhance security and error handling in GitHub username validation

The existing function needs improvements for security and reliability:

  1. Add URL encoding for the username parameter
  2. Consider GitHub's rate limiting
  3. Add proper error handling for network issues
 export const isGithubUsernameValid = async (username: string) => {
+  if (!username?.trim()) return false;
+
   try {
-    const response = await fetch(`https://api.github.com/users/${username}`);
+    const response = await fetch(`https://api.github.com/users/${encodeURIComponent(username.trim())}`);
     return response.status === 200;
+  } catch (error) {
+    console.error('Error validating GitHub username:', error);
+    return false;
+  }
 };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const isGithubUsernameValid = async (username: string) => {
const response = await fetch(`https://api.github.com/users/${username}`);
return response.status === 200;
};
export const isGithubUsernameValid = async (username: string) => {
if (!username?.trim()) return false;
try {
const response = await fetch(`https://api.github.com/users/${encodeURIComponent(username.trim())}`);
return response.status === 200;
} catch (error) {
console.error('Error validating GitHub username:', error);
return false;
}
};

Comment on lines +9 to +20
export const searchFileInHatsRepo = async (repoName: string, fileName: string): Promise<string[]> => {
if (!repoName || !fileName) return [];

try {
const res = await axiosClient.get(`${BASE_SERVICE_URL}/utils/search-file-in-repo?repoName=${repoName}&fileName=${fileName}`);

return res.data.files ?? [];
} catch (err) {
console.error(err);
return [];
}
};
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add type safety and URL encoding

While the error handling approach (returning empty array) is good, there are still some improvements needed:

+ interface SearchFileResponse {
+   files: string[];
+ }
+
 export const searchFileInHatsRepo = async (repoName: string, fileName: string): Promise<string[]> => {
   if (!repoName || !fileName) return [];

   try {
-    const res = await axiosClient.get(`${BASE_SERVICE_URL}/utils/search-file-in-repo?repoName=${repoName}&fileName=${fileName}`);
+    const res = await axiosClient.get<SearchFileResponse>(
+      `${BASE_SERVICE_URL}/utils/search-file-in-repo?` +
+      `repoName=${encodeURIComponent(repoName.trim())}&` +
+      `fileName=${encodeURIComponent(fileName.trim())}`
+    );

     return res.data.files ?? [];
   } catch (err) {
     console.error(err);
+    console.error(`Failed to search for file '${fileName}' in repo '${repoName}'`);
     return [];
   }
 };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const searchFileInHatsRepo = async (repoName: string, fileName: string): Promise<string[]> => {
if (!repoName || !fileName) return [];
try {
const res = await axiosClient.get(`${BASE_SERVICE_URL}/utils/search-file-in-repo?repoName=${repoName}&fileName=${fileName}`);
return res.data.files ?? [];
} catch (err) {
console.error(err);
return [];
}
};
interface SearchFileResponse {
files: string[];
}
export const searchFileInHatsRepo = async (repoName: string, fileName: string): Promise<string[]> => {
if (!repoName || !fileName) return [];
try {
const res = await axiosClient.get<SearchFileResponse>(
`${BASE_SERVICE_URL}/utils/search-file-in-repo?` +
`repoName=${encodeURIComponent(repoName.trim())}&` +
`fileName=${encodeURIComponent(fileName.trim())}`
);
return res.data.files ?? [];
} catch (err) {
console.error(err);
console.error(`Failed to search for file '${fileName}' in repo '${repoName}'`);
return [];
}
};

Comment on lines +396 to +424
onChange={async (a) => {
if (!a?.length) return;
for (const file of a) {
const fixFiles = getValues(`descriptions.${index}.complementFixFiles`);
if (fixFiles.some((f) => f.file.ipfsHash === file.ipfsHash)) continue;
const newFile = { file, path: "", pathOpts: [] };

const repoName = await getVaultRepoName(vault?.id);
if (!repoName) {
setValue(`descriptions.${index}.complementFixFiles`, [...fixFiles, newFile]);
return;
}

const pathOptions = await searchFileInHatsRepo(repoName, file.name);
if (pathOptions.length === 0) {
setValue(`descriptions.${index}.complementFixFiles`, [...fixFiles, newFile]);
} else if (pathOptions.length === 1) {
setValue(`descriptions.${index}.complementFixFiles`, [
...fixFiles,
{ ...newFile, path: pathOptions[0], pathOpts: [] },
]);
} else {
setValue(`descriptions.${index}.complementFixFiles`, [
...fixFiles,
{ ...newFile, path: "", pathOpts: pathOptions },
]);
}
}
}}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add error handling for file operations.

The file upload logic lacks proper error handling for API calls.

Apply this diff to improve error handling:

 onChange={async (a) => {
   if (!a?.length) return;
+  try {
     for (const file of a) {
       const fixFiles = getValues(`descriptions.${index}.complementFixFiles`);
       if (fixFiles.some((f) => f.file.ipfsHash === file.ipfsHash)) continue;
       const newFile = { file, path: "", pathOpts: [] };

       const repoName = await getVaultRepoName(vault?.id);
       if (!repoName) {
         setValue(`descriptions.${index}.complementFixFiles`, [...fixFiles, newFile]);
         return;
       }

       const pathOptions = await searchFileInHatsRepo(repoName, file.name);
       if (pathOptions.length === 0) {
         setValue(`descriptions.${index}.complementFixFiles`, [...fixFiles, newFile]);
       } else if (pathOptions.length === 1) {
         setValue(`descriptions.${index}.complementFixFiles`, [
           ...fixFiles,
           { ...newFile, path: pathOptions[0], pathOpts: [] },
         ]);
       } else {
         setValue(`descriptions.${index}.complementFixFiles`, [
           ...fixFiles,
           { ...newFile, path: "", pathOpts: pathOptions },
         ]);
       }
     }
+  } catch (error) {
+    console.error('Failed to process file:', error);
+    // Show user-friendly error message
+  }
 }}

Committable suggestion skipped: line range outside the PR's diff.

@shayzluf shayzluf merged commit ccd6d14 into develop Nov 8, 2024
4 checks passed
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