Skip to content

Boards page#275

Merged
okhaimie-dev merged 4 commits intodevelopfrom
boards-page
Feb 21, 2025
Merged

Boards page#275
okhaimie-dev merged 4 commits intodevelopfrom
boards-page

Conversation

@supreme2580
Copy link
Copy Markdown
Collaborator

@supreme2580 supreme2580 commented Feb 20, 2025

Closes: #274

Summary by CodeRabbit

  • New Features

    • Added a new page showcasing Mancala boards with interactive visual displays and actions.
  • Chores

    • Updated dependency versions and configuration settings, including smart contract language upgrades.
  • Refactor

    • Renamed game components and queries to a unified naming convention, ensuring consistent data handling.
    • Enhanced module and function visibility across both client and contract layers for improved integration.

@vercel
Copy link
Copy Markdown

vercel bot commented Feb 20, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
mancala-pkco ✅ Ready (Inspect) Visit Preview 💬 Add feedback Feb 20, 2025 9:47pm

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Feb 20, 2025

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

This pull request updates client and contract code across the board. On the client side, dependency versions in the package manifest are bumped and naming is refactored from “mancalaAlpha” to “mancalaSalt” while introducing new UI components and routes (notably a new Boards page). On the contracts side, version and dependency upgrades are applied along with comprehensive configuration and namespace changes. In addition, many source files have been updated to change module, struct, enum, and function visibility from private to public, and auto-generated binding/schema files are removed.

Changes

File(s) Change Summary
client/package.json Updated dependency versions for @cartridge/connector (^0.5.5 → ^0.6.0) and @cartridge/controller (^0.5.8 → ^0.6.0).
client/src/App.tsx, client/src/pages/Boards.tsx, client/src/components/boards/board-block.tsx New imports, route /boards, and components (Boards, BoardBlock) added; updated options object and connector instantiation; naming refactored from mancalaAlpha to mancalaSalt.
client/src/components/gameplay/*, client/src/components/profile/user-section.tsx, client/src/components/tutorial/*, client/src/lib/config.ts, client/src/lib/constants.ts Updated data queries and references, replacing “mancalaAlpha” with “mancalaSalt” and applying formatting improvements for clarity.
contracts/.tool-versions, contracts/Scarb.toml Upgraded dependency versions (e.g., dojo v1.0.9 → v1.1.2, cairo v2.8.4 → v2.9.2) and bumped package version.
contracts/bindings/typescript/contracts.gen.ts, contracts/bindings/typescript/models.gen.ts Removed auto-generated contract binding and TypeScript type definition files.
contracts/dojo_dev.toml, contracts/dojo_sepolia.toml, contracts/dojo_slot.toml, contracts/manifest_dev.json, contracts/manifest_sepolia.json, contracts/torii_dev.toml Changed namespace from “mancala_alpha” to “mancala_salt”, updated contract addresses, class hashes, tags, selectors, and event mappings.
Multiple contracts source files (e.g., components, events, lib, models, store, systems, tests, tasks, types, utils) Modified module, struct, enum, function, and implementation visibility from private to public; updated import/export statements and refactored trait implementations (e.g., using core::traits::Into); removed deprecated printing functionality.

Sequence Diagram(s)

sequenceDiagram
  participant U as User
  participant R as Router
  participant A as App Component
  participant B as Boards Page
  participant BB as BoardBlock Component

  U->>R: Navigate to /boards
  R->>A: Render App with "/boards" route
  A->>B: Display Boards component
  B->>BB: Render each BoardBlock for board items
Loading

Possibly related PRs

  • Controller patch fix #170: Updates to the client/package.json file aligning dependency updates with similar modifications in that PR.

Suggested reviewers

  • okhaimie-dev

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 generate docstrings to generate docstrings for this PR. (Beta)
  • @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.

@supreme2580 supreme2580 changed the base branch from main to develop February 20, 2025 20:29
Copy link
Copy Markdown

@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.

Caution

Inline review comments failed to post. This is likely due to GitHub's limits when posting large numbers of comments.

Actionable comments posted: 3

🔭 Outside diff range comments (1)
contracts/src/tests/utils.cairo (1)

7-39: 🛠️ Refactor suggestion

Add input validation and error handling.

The function handles complex state mutations but lacks input validation and error handling.

Consider adding:

  1. Validation for player.len_pits to ensure it's within valid range
  2. Checks for arithmetic overflow in seed count calculations
  3. Error handling for invalid pit or seed access
 pub fn move_player_seeds_to_store(world: WorldStorage, player: @Player) {
+    // Validate input
+    assert(*player.len_pits > 0 && *player.len_pits <= 6, 'Invalid number of pits');
+
     let mut store: Store = StoreTrait::new(world);
     let mut player_store = store.get_pit(*player.game_id, *player.address, 7);
     let store_start_count = player_store.seed_count;
     let mut total_moved_seeds = 0;

     let mut idx = 1;
     loop {
         if idx > *player.len_pits {
             break;
         }
         let mut pit = store.get_pit(*player.game_id, *player.address, idx);
         let pit_seed_count = pit.seed_count;
+        // Check for arithmetic overflow
+        assert(
+            store_start_count + total_moved_seeds + pit_seed_count <= u32::max(),
+            'Seed count overflow'
+        );
         let mut seeds_idx = 1;
         loop {
             if seeds_idx > pit_seed_count {
                 break;
             }
             let mut seed = store.get_seed(*player.game_id, *player.address, idx, seeds_idx);
             seed.pit_number = 7;
             seed.seed_number = store_start_count + total_moved_seeds + seeds_idx;
             store.set_seed(seed);
             seeds_idx += 1;
         };
         total_moved_seeds += pit_seed_count;
         pit.seed_count = 0;
         store.set_pit(pit);
         idx += 1;
     };
     // Update store pit count once at the end
     player_store.seed_count += total_moved_seeds;
     store.set_pit(player_store);
 }
🧹 Nitpick comments (28)
contracts/src/events/move.cairo (1)

8-39: LGTM! Good visibility changes for trait implementations.

Making the trait implementations public allows other modules to properly construct events. The constructor functions are well-structured.

Consider adding trailing commas to all constructor parameters for consistency with EndTurn::new():

-    fn new(game_id: u128, pit_number: u8, seed_number: u8) -> PlayerMove {
+    fn new(game_id: u128, pit_number: u8, seed_number: u8,) -> PlayerMove {

-    fn new(game_id: u128, player: ContractAddress) -> PlayerExtraTurn {
+    fn new(game_id: u128, player: ContractAddress,) -> PlayerExtraTurn {

-    fn new(game_id: u128, player: ContractAddress, pit_number: u8, seed_count: u8) -> Capture {
+    fn new(game_id: u128, player: ContractAddress, pit_number: u8, seed_count: u8,) -> Capture {
contracts/src/elements/tasks/mastering.cairo (1)

11-11: Consider improving the description text.

The current text "Get {} games win streak" could be more polished. Consider using "Achieve a {} game winning streak" for better readability.

-        format!("Get {} games win streak", count)
+        format!("Achieve a {} game winning streak", count)
contracts/src/elements/tasks/collecting.cairo (1)

11-11: Fix grammatical error in description text.

The current text has a grammatical error: "seed" should be "seeds" when referring to multiple items.

-        format!("Collect {} seed in game lifetime history", count)
+        format!("Collect {} seeds in game lifetime history", count)
client/src/components/boards/board-block.tsx (1)

15-25: Extract hardcoded colors to theme constants.

The component uses hardcoded color values which could be moved to theme constants for better maintainability.

Consider creating a theme file with color constants:

// theme.ts
export const colors = {
  boardBackground: '#0F111680',
  textPrimary: '#FFFFFF',
  textSecondary: '#C7CAD4',
  buttonDefault: '#171922',
  buttonAccent: '#F58229'
} as const;

Then update the component to use these constants:

-<div className="w-[630px] h-[400px] bg-[#0F111680] rounded-xl">
+<div className="w-[630px] h-[400px] rounded-xl" style={{ backgroundColor: colors.boardBackground }}>
  <div className="w-full h-full p-4 space-y-1">
    {/* ... */}
-   <h3 className="text-white text-2xl font-semibold">{name}</h3>
-   <p className="text-[#C7CAD4] text-lg">{description}</p>
+   <h3 className="text-2xl font-semibold" style={{ color: colors.textPrimary }}>{name}</h3>
+   <p className="text-lg" style={{ color: colors.textSecondary }}>{description}</p>
    {
-     owned ? <Button className="p-5 rounded-3xl bg-[#171922]">Owned</Button> : 
-     <Button className="p-5 rounded-3xl bg-[#F58229]">Buy Board</Button>
+     owned ? <Button className="p-5 rounded-3xl" style={{ backgroundColor: colors.buttonDefault }}>Owned</Button> : 
+     <Button className="p-5 rounded-3xl" style={{ backgroundColor: colors.buttonAccent }}>Buy Board</Button>
    }
  </div>
</div>
contracts/src/lib.cairo (1)

1-63:

Details

❓ Verification inconclusive

Verify the architectural decision to make all modules public.

Making all modules public increases accessibility but could impact encapsulation. Please confirm that this aligns with the project's architectural goals and that all modules are intended to be part of the public API.

Consider:

  1. Are all these modules meant to be part of the public API?
  2. Would some modules benefit from remaining internal to maintain better encapsulation?
  3. Is there documentation that needs to be updated to reflect these public APIs?

Run this script to check for potential unintended usage of these newly public modules:


🏁 Script executed:

#!/bin/bash
# Description: Check for usage of these modules outside their intended scope

# Search for imports of these modules
rg -l "use mancala::(constants|store|models|events|components|elements|systems|types|utils|tests)" --type cairo

Length of output: 143


Below is an updated verification script that avoids using the unrecognized file type by instead searching through all files matching the "*.cairo" pattern. Please execute this script and manually verify the usage of the public modules to ensure they are indeed part of the intended public API.

Next Steps:

  • Run the above script and confirm that there are no unintended external usages of these modules.
  • Verify that the architectural decision to make all modules public aligns with the project's design and documentation.

🏁 Script executed:

[run_scripts]
#!/bin/bash
# Updated: Check for imports of public modules across all Cairo files.
rg -l "use mancala::(constants|store|models|events|components|elements|systems|types|utils|tests)" -g "*.cairo"

Length of output: 1410


Architectural Review: Public API Modules

The search results confirm that many modules (e.g., components, elements, events, tests, etc.) are actively imported within various Cairo files across the codebase. This internal usage indicates that, at least within the repository, these modules are intended to be public. However, before finalizing this decision, please verify the following:

  • Confirm that exposing all these modules publicly aligns with the intended external API boundaries.
  • Review if any modules would benefit from internal-only visibility to improve encapsulation.
  • Update the project documentation to clearly differentiate the intended public APIs from internal implementation details if necessary.

Based on the current evidence, the decision to make all modules public appears consistent with internal usage, but these points should be manually verified.

contracts/src/components/initializable.cairo (1)

29-43: Add events and enhance error handling.

The initialize function could benefit from emitting events and more descriptive error messages.

Consider adding:

  1. Event emission for successful initialization
  2. More descriptive error messages
  3. Additional validation checks
 fn initialize(self: @ComponentState<TState>, world: WorldStorage) {
     // [Effect] Initialize component
     let mut store = StoreTrait::new(world);
     let current_game_counter = store.get_game_counter(1);

-    assert(current_game_counter.count == 0, 'Counter already initialized');
+    assert(
+        current_game_counter.count == 0,
+        'Game counter has already been initialized'
+    );

     // [Effect] Create GameCounter
     let mut game_counter = GameCounterTrait::new();

     // [Effect] GameCounter increment
     game_counter.increment();

     store.set_game_counter(game_counter);
+    
+    // Emit initialization event
+    self.emit(Event::Initialized(game_counter.count));
 }
contracts/src/systems/profile.cairo (1)

12-14: Clean up commented imports.

These commented imports should either be removed if no longer needed or uncommented if they will be used in the future.

-    //use starknet::ContractAddress;
-    //use mancala::models::profile::Profile;
client/src/components/message-area.tsx (1)

35-35: Remove or enhance console.log statement.

Consider removing this console.log or enhancing it with more meaningful debug information for development purposes.

-    console.log("clicked: ");
+    // Remove for production or enhance with meaningful debug info
contracts/src/components/profile.cairo (1)

3-3: Clean up commented debug import.

Remove the commented debug import if it's no longer needed.

-    //use core::debug::PrintTrait;
client/src/App.tsx (1)

56-56: Consider removing unnecessary type assertions.

The double type assertion (as never as Connector) seems redundant and could be simplified.

-  const connectors = [new ControllerConnector(options as never) as never as Connector];
+  const connectors = [new ControllerConnector(options) as Connector];
contracts/src/tests/setup.cairo (1)

1-2: Consider keeping debug trait for development.

While removing debug prints in production code is good practice, consider keeping them in test files to aid in debugging test failures.

-    //use core::debug::PrintTrait;
+    #[cfg(test)]
+    use core::debug::PrintTrait;
client/src/pages/Boards.tsx (2)

6-21: Consider moving hardcoded board data to a separate configuration file.

The boards array contains hardcoded data that would be better maintained in a separate configuration file. This would improve maintainability and make it easier to update board information.

+// boards.config.ts
+export const MANCALA_BOARDS = [
+  {
+    id: 1,
+    image_path: './assets/default_board_sample.png',
+    name: 'Default Board',
+    description: 'Story about it that you can make mention of to have like a description',
+    owned: true
+  },
+  {
+    id: 2,
+    image_path: './assets/starknet_board_sample.png',
+    name: 'Starknet Board',
+    description: 'Story about it that you can make mention of to have like a description',
+    owned: false
+  }
+];

58-61: Consider adding pagination for board grid.

The grid uses a fixed height with overflow scroll. As more boards are added, consider implementing proper pagination for better user experience.

contracts/src/store.cairo (2)

23-25: Verify the impact of making Store struct public.

Making the Store struct public increases its visibility. Ensure this aligns with the security model and doesn't expose sensitive functionality.


30-30: Consider documenting the public implementation.

Since StoreImpl is now public, consider adding documentation to explain its intended usage and any security considerations.

client/src/components/tutorial/tutorial-game-navigation.tsx (1)

21-33: Consider adding proper TypeScript types for props.

The component uses any type for multiple props. Consider defining proper interfaces/types for better type safety.

+interface TutorialGameNavigationProps {
+  game_players: GamePlayers;
+  player_names: PlayerNames;
+  game_node: GameNode;
+  account: Account;
+  gameId: string;
+  timeRemaining: number;
+  setTimeRemaining: (time: number) => void;
+  message: string;
+  setMessage: (message: string) => void;
+  action: { action: string; message: string };
+  setAction: (action: { action: string; message: string }) => void;
+  moveMessage: string;
+}
client/src/pages/games/Gameplay.tsx (2)

37-42: Simplify the boolean expression.

The ternary operator returning boolean literals can be simplified.

-const involved =
-  game_players?.mancalaSaltPlayerModels.edges.filter(
-    (item: any) => item?.node.address === account.address,
-  ).length > 0
-    ? true
-    : false;
+const involved = game_players?.mancalaSaltPlayerModels.edges.filter(
+  (item: any) => item?.node.address === account.address,
+).length > 0;
🧰 Tools
🪛 Biome (1.9.4)

[error] 38-42: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


52-53: Consider adjusting polling interval.

The polling interval of 100ms might be too aggressive. Consider increasing it to reduce server load unless this frequency is specifically required.

client/src/lib/utils.ts (1)

247-349: Consider refactoring for better maintainability.

The calculateMancalaMove function is complex with multiple responsibilities. Consider breaking it down into smaller, focused functions:

  • Seed movement logic
  • Capture logic
  • Pit transition logic

Example refactor:

+function moveSeed(currentPit: number, currentPlayer: string): { newPit: number, newPlayer: string } {
+  if (currentPlayer === player && currentPit > 7) {
+    return { newPit: 1, newPlayer: opponent };
+  } else if (currentPlayer === opponent && currentPit > 6) {
+    return { newPit: 1, newPlayer: player };
+  }
+  return { newPit: currentPit, newPlayer: currentPlayer };
+}

+function handleCapture(
+  seeds: any[],
+  lastSeedPosition: { pit: number, player: string },
+  player: string,
+  opponent: string
+): any[] {
+  if (lastSeedPosition.player === player && lastSeedPosition.pit !== 7) {
+    // Capture logic here
+  }
+  return seeds;
+}

 export function calculateMancalaMove(seeds: any[], selectedPit: number | 0, player: string, opponent: string) {
   // Get seeds to move
   const seedsToMove = seeds.filter(/*...*/).sort(/*...*/);
   if (seedsToMove.length === 0) return seeds;

   // Keep unchanged seeds
   const unchangedSeeds = seeds.filter(/*...*/);

   // Move seeds
   let currentPit = selectedPit;
   let currentPlayer = player;
   let lastSeedPosition = { pit: 0, player };
   
   const movedSeeds = seedsToMove.map((seed, index) => {
     currentPit++;
     
-    // Handle pit transitions
-    if (currentPlayer === player && currentPit > 7) {
-      currentPit = 1;
-      currentPlayer = opponent;
-    } else if (currentPlayer === opponent && currentPit > 6) {
-      currentPit = 1;
-      currentPlayer = player;
-    }
+    // Handle pit transitions
+    const { newPit, newPlayer } = moveSeed(currentPit, currentPlayer);
+    currentPit = newPit;
+    currentPlayer = newPlayer;

     // Update last seed position
     if (index === seedsToMove.length - 1) {
       lastSeedPosition = { pit: currentPit, player: currentPlayer };
     }

     // Return moved seed
     return { /*...*/ };
   });

-  // Handle capture
-  if (lastSeedPosition.player === player && lastSeedPosition.pit !== 7) {
-    // Capture logic
-  }
+  // Handle capture
+  return handleCapture([...unchangedSeeds, ...movedSeeds], lastSeedPosition, player, opponent);

-  return [...unchangedSeeds, ...movedSeeds];
 }
contracts/src/utils/board.cairo (1)

9-9: Verify the impact of making these functions public.

The change in visibility from private to public for these functions expands their accessibility. Ensure this aligns with the module's design and doesn't expose sensitive operations.

Consider:

  1. Document the intended usage of these public functions
  2. Add input validation if these functions can now be called from untrusted contexts
  3. Consider using an interface trait to expose only necessary functions

Also applies to: 28-28, 45-45, 135-135, 178-178, 199-199, 214-214, 246-246, 280-280, 335-335

contracts/src/components/playable.cairo (1)

2-2: Verify the architectural impact of making the module public.

The change in visibility from private to public for the module and error constants expands their accessibility. This aligns with component-based architecture but requires careful consideration.

Consider:

  1. Document the public interface and its intended usage
  2. Ensure error messages are appropriate for public exposure
  3. Add integration tests to verify the component's public interface

Also applies to: 21-25

client/src/components/header.tsx (3)

92-103: Consider memoizing the profile lookup.

The profile lookup is performed in a useEffect hook that runs on every change to account or playerData. Consider memoizing the profile lookup to avoid unnecessary recalculations.

+const profile = useMemo(() => {
+  return playerData?.mancalaSaltProfileModels?.edges.find(
+    (player: any) => player.node.address === account?.address,
+  );
+}, [account?.address, playerData?.mancalaSaltProfileModels?.edges]);

-const profile: any = playerData?.mancalaSaltProfileModels?.edges.find(
-  (player: any) => player.node.address === account?.address,
-);

246-248: Optimize user existence check.

The current implementation iterates through all profiles to check if a user exists. Consider using a more efficient lookup method, such as maintaining a Set of addresses.

+const userAddresses = new Set(
+  profiles.mancalaSaltProfileModels.edges.map(
+    (profile: any) => profile.node.address
+  )
+);
+const userExists = userAddresses.has(account?.address);

-const userExists = profiles.mancalaSaltProfileModels.edges.some(
-  (profile: any) => profile.node.address === account?.address,
-);

298-306: Simplify condition checks.

The condition checks can be simplified for better readability.

-if (
-  account?.address &&
-  playerData?.mancalaSaltProfileModels?.edges &&
-  !profile
-) {
+const hasAccount = Boolean(account?.address);
+const hasProfiles = Boolean(playerData?.mancalaSaltProfileModels?.edges);
+if (hasAccount && hasProfiles && !profile) {
client/src/pages/Lobby.tsx (4)

93-94: Optimize game filtering.

Consider memoizing the filtered games to avoid unnecessary recalculations on every render.

+const filteredGames = useMemo(() => {
+  return data?.mancalaSaltMancalaBoardModels?.edges
+    ?.filter(/* ... */)
+    .sort(/* ... */)
+    .map(/* ... */);
+}, [data?.mancalaSaltMancalaBoardModels?.edges, account.account?.address, playerData]);

-const filteredGames = data?.mancalaSaltMancalaBoardModels?.edges
-  ?.filter(/* ... */)
-  .sort(/* ... */)
-  .map(/* ... */);

119-128: Optimize multiple profile lookups.

Consider creating a map of addresses to profiles to avoid multiple iterations through the profiles array.

+const profileMap = useMemo(() => {
+  return new Map(
+    playerData?.mancalaSaltProfileModels?.edges?.map(
+      (profile: any) => [profile.node.address, profile]
+    )
+  );
+}, [playerData?.mancalaSaltProfileModels?.edges]);

+const player1Profile = profileMap.get(game.node.player_one);
+const player2Profile = profileMap.get(game.node.player_two);
+const winner = profileMap.get(game.node.winner);

-const player1Profile = playerData?.mancalaSaltProfileModels?.edges?.find(
-  (profile: any) => profile.node.address === game.node.player_one,
-);
-const player2Profile = playerData?.mancalaSaltProfileModels?.edges?.find(
-  (profile: any) => profile.node.address === game.node.player_two,
-);
-const winner = playerData?.mancalaSaltProfileModels?.edges?.find(
-  (profile: any) => profile.node.address === game.node.winner,
-);

144-145: Optimize transaction filtering.

Consider using filter and map instead of reduce for better readability and maintainability.

+const filteredTransactions = data?.mancalaSaltMancalaBoardModels?.edges
+  ?.filter((game: any) => 
+    game?.node?.player_one === account.account?.address ||
+    game?.node?.player_two === account.account?.address ||
+    (game?.node?.entity.executedAt && game?.node?.player_two === "0x0")
+  )
+  ?.map((game: any) => ({
+    ...game.node,
+    executedAt: game?.node?.entity.executedAt,
+  })) || [];

-const filteredTransactions = data?.mancalaSaltMancalaBoardModels?.edges?.reduce(
-  (acc: any[], game: any) => {
-    if (
-      game?.node?.player_one === account.account?.address ||
-      game?.node?.player_two === account.account?.address ||
-      (game?.node?.entity.executedAt && game?.node?.player_two === "0x0")
-    ) {
-      acc.push({
-        ...game.node,
-        executedAt: game?.node?.entity.executedAt,
-      });
-    }
-    return acc;
-  },
-  [],
-) || [];

218-229: Simplify address extraction.

The address extraction can be simplified using Set to automatically deduplicate addresses.

+const allAddresses = new Set(
+  data?.mancalaSaltMancalaBoardModels?.edges?.flatMap((game: any) => [
+    game.node.player_one,
+    game.node.player_two,
+    game.node.winner
+  ].filter(Boolean))
+);

-const allAddresses = data?.mancalaSaltMancalaBoardModels?.edges
-  .flatMap((game: any) => [
-    game.node.player_one,
-    game.node.player_two,
-    game.node.winner,
-  ])
-  .filter(Boolean);
🛑 Comments failed to post (3)
client/src/components/boards/board-block.tsx (1)

17-17: 🛠️ Refactor suggestion

Improve image handling and accessibility.

The dynamic background image URL construction could be unsafe and lacks error handling. Additionally, the image needs proper accessibility attributes.

Consider these improvements:

-<div className={`w-full h-64 bg-contain bg-center bg-no-repeat bg-[url('${image_path}')]`} />
+<div 
+  className="w-full h-64 bg-contain bg-center bg-no-repeat" 
+  style={{ backgroundImage: `url(${image_path})` }}
+  role="img"
+  aria-label={`${name} board image`}
+>
+  {/* Add a fallback for image loading errors */}
+  <div className="hidden">
+    <img src={image_path} alt="" onError={(e) => {
+      e.currentTarget.parentElement?.parentElement?.classList.add('bg-gray-200');
+    }} />
+  </div>
+</div>
📝 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.

                <div 
                  className="w-full h-64 bg-contain bg-center bg-no-repeat" 
                  style={{ backgroundImage: `url(${image_path})` }}
                  role="img"
                  aria-label={`${name} board image`}
                >
                  {/* Add a fallback for image loading errors */}
                  <div className="hidden">
                    <img src={image_path} alt="" onError={(e) => {
                      e.currentTarget.parentElement?.parentElement?.classList.add('bg-gray-200');
                    }} />
                  </div>
                </div>
client/src/components/header.tsx (1)

160-162: 🛠️ Refactor suggestion

Remove duplicate profile lookup.

This profile lookup is duplicated from the previous useEffect hook. Consider reusing the memoized profile to maintain consistency and improve maintainability.

contracts/torii_dev.toml (1)

5-5: 💡 Verification agent

🧩 Analysis chain

Verify the new world address deployment.

Please ensure that the new world address 0x8fb1bf2a0525b8c79ecfac766fa62933e26725effd8741a007f50896ea97d1 is correctly deployed and accessible.


🏁 Script executed:

#!/bin/bash
# Description: Verify world address deployment and accessibility
curl -X POST \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"starknet_getClassAt","params":["0x8fb1bf2a0525b8c79ecfac766fa62933e26725effd8741a007f50896ea97d1"],"id":1}' \
  https://api.cartridge.gg/x/starknet/sepolia

Length of output: 663


World address verification update needed

The verification script currently returns an "Invalid block id" error because the JSON-RPC method requires a block identifier parameter (e.g., "latest") alongside the world address. Please update the verification command accordingly to confirm that the new world address is deployed and accessible. For example, modify the JSON payload to:

{
  "jsonrpc": "2.0",
  "method": "starknet_getClassAt",
  "params": [
    "0x8fb1bf2a0525b8c79ecfac766fa62933e26725effd8741a007f50896ea97d1",
    "latest"
  ],
  "id": 1
}
  • Location: contracts/torii_dev.toml (verify/update associated deployment/verification scripts if needed)

@okhaimie-dev okhaimie-dev merged commit fe5092b into develop Feb 21, 2025
3 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Feb 22, 2025
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.

Implement Boards Page According To Figma design

2 participants