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: add search room list #54

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open

Conversation

Fakhri1999
Copy link
Member

@Fakhri1999 Fakhri1999 commented Nov 14, 2024

Screenshot/Screen Recording

Before This PR

image

After This PR

2024-11-14.23-23-05.mp4

Summary by CodeRabbit

Release Notes

  • New Features

    • Enhanced image handling with support for remote images from placehold.co.
    • Introduced localized strings for search functionality in English and Indonesian.
    • Added a new RoomCardItem component for displaying room details.
    • Improved the RoomSearchContainer with a responsive design and enhanced internationalization.
  • Bug Fixes

    • Adjusted layout and styling in various components to improve user experience.
  • Chores

    • Updated theme configuration with new color properties.
    • Introduced a new Container component for better layout management.

Copy link
Contributor

coderabbitai bot commented Nov 14, 2024

Walkthrough

The pull request introduces several enhancements across multiple files. It adds a new image handling configuration in next.config.js, enabling remote images from placehold.co. Localization improvements are made by adding a "search" section in English and Indonesian JSON files. Structural changes are implemented in components like LandingPageContainer, RoomSearchContainer, and RoomCardItem, enhancing layout and responsiveness. Additionally, new properties are added to the Room type and ApiRoomSchema, and the searchRoom function's response type is updated to include pagination details.

Changes

File Change Summary
next.config.js Added images property with remotePatterns to allow loading images from placehold.co.
public/locales/en/common.json Introduced a new "search" section with localized strings for search functionality.
public/locales/id/common.json Added a "search" section with localized strings in Indonesian for search functionality.
src/modules/landingPage/LandingPageContainer.tsx Wrapped child components in a new Container component for structural modification.
src/modules/room/RoomCardItem.tsx Introduced a new RoomCardItem component to display room details with tags and descriptions.
src/modules/room/RoomSearchContainer.tsx Replaced layout with Grid components, enhanced mobile responsiveness, and integrated RoomCardItem for displaying rooms.
src/modules/room/roomEntity.ts Added new properties (tags, totalChannel, rate) to ApiRoomSchema and Room type.
src/modules/room/roomService.ts Updated searchRoom function to return a structured response with pagination, introducing SearchRoomResponse type.
src/theme/global.css Modified body styling and added a comment about dark mode; ensured text color is white with !important.
src/theme/index.ts Added a new dark background color property in the theme configuration.
src/uikit/Container.tsx Introduced a new Container functional component utilizing Flex from Chakra UI.
src/uikit/Header.tsx Imported Container from local file; simplified usage in the Header component.
src/uikit/Layout.tsx Added backgroundPosition property to Box and removed px prop from Flex, affecting layout.

Possibly related PRs

Suggested labels

enhancement, good first issue, help wanted

Suggested reviewers

  • Aldiwildan77
  • alamsyaah

Poem

🐇 In the garden where changes bloom,
New images dance, dispelling gloom.
With searches refined in languages two,
Rooms to explore, all waiting for you!
A container to hold, a layout so bright,
Hop along, dear friends, to a delightful sight! 🌼


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
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 (13)
src/uikit/Container.tsx (2)

4-10: Consider adding default props and prop documentation.

The component implementation is clean and follows React best practices. However, to improve maintainability and developer experience, consider adding:

  • JSDoc documentation describing the component's purpose and usage
  • PropTypes or TypeScript interface documentation for better IDE support
+/**
+ * A responsive container component that provides consistent padding and layout.
+ * Wraps content in a flex container with responsive horizontal padding.
+ *
+ * @example
+ * <Container>
+ *   <YourContent />
+ * </Container>
+ */
 export function Container(props: FlexProps) {
   return (
     <Flex px={{ base: 5, lg: 10 }} w='100%' flexDir='column' {...props}>

6-6: Consider extracting responsive values to theme tokens.

The padding values are currently hardcoded. For better maintainability and consistency across the application, consider moving these values to theme tokens.

-    <Flex px={{ base: 5, lg: 10 }} w='100%' flexDir='column' {...props}>
+    <Flex px={{ base: 'containerPaddingBase', lg: 'containerPaddingLg' }} w='100%' flexDir='column' {...props}>

Then define these in your theme:

// theme.ts
export const space = {
  containerPaddingBase: '1.25rem', // 5 in Chakra's default scale
  containerPaddingLg: '2.5rem',    // 10 in Chakra's default scale
}
src/modules/room/roomEntity.ts (2)

11-13: Consider using consistent naming convention

The property total_channel uses snake_case while TypeScript conventionally uses camelCase. Consider renaming it to totalChannel to maintain consistency with TypeScript conventions and match the corresponding property in the Room type.

-      total_channel: z.number().default(0),
+      totalChannel: z.number().default(0),

25-27: LGTM! Consider matching property order with schema

The type definitions are correct and properly aligned with the schema. For better maintainability, consider ordering the properties to match the order in ApiRoomSchema.

 export type Room = {
   serial: string;
   name: string;
   description: string;
+  tags: string[];
   totalChannel: number;
   rate: number;
-  tags: string[];
 };
src/uikit/Layout.tsx (1)

19-21: Background styling looks good, but let's track the TODO.

The background image styling properties are appropriate for responsive design. However, the TODO comment indicates this is a temporary solution pending a home page image fix.

Would you like me to create a GitHub issue to track this TODO and ensure it's not forgotten? This will help prevent technical debt.

src/modules/room/roomService.ts (1)

43-53: Consider adding error handling and type validation.

While the response structure is correct, consider these improvements:

  1. Add error handling for failed responses
  2. Validate required fields before mapping
  3. Use type guards to ensure data safety

Consider applying this enhancement:

 return {
+  // Add type guard to ensure data integrity
+  rooms: Array.isArray(response.data) ? response.data.map((room) => {
+    // Validate required fields
+    if (!room.serial || !room.name) {
+      throw new Error('Invalid room data: missing required fields');
+    }
     return {
       serial: room.serial,
       name: room.name,
       description: room.description,
       tags: room.tags,
       totalChannel: room.total_channel,
       rate: room.rate,
     };
-  })),
+  }) : [],
   pagination: response.metadata?.pagination,
 };
next.config.js (1)

29-32: Consider environment-specific configuration

The hardcoded values for protocol and hostname could be made configurable through environment variables, similar to other configurations in this file.

Example implementation:

 {
-  protocol: 'https',
-  hostname: 'placehold.co',
+  protocol: process.env.IMAGE_PROTOCOL || 'https',
+  hostname: process.env.IMAGE_HOSTNAME || 'placehold.co',
   port: '',
   pathname: '/**',
 }
public/locales/id/common.json (1)

25-25: Consider enhancing the search results message.

The current translation uses "kamar" (room) which is less formal. Consider using "ruangan" instead to maintain consistency with the title translations and provide a more professional tone.

-    "found_rooms": "<b>Ditemukan {{count}}</b> kamar yang cocok dengan filter Anda",
+    "found_rooms": "<b>Ditemukan {{count}}</b> ruangan yang cocok dengan filter Anda",
src/modules/room/RoomCardItem.tsx (3)

18-20: Add JSDoc documentation for the Props type.

Consider adding documentation to improve code maintainability and developer experience.

+/**
+ * Props for the RoomCardItem component
+ * @property {Room} room - The room data to display in the card
+ */
 type Props = {
   room: Room;
 };

22-22: Consider making MAX_TAG_SHOW_COUNT more maintainable.

The constant would benefit from documentation and potentially being configurable via props or environment variables.

+/**
+ * Maximum number of tags to display before showing a "+X more" tooltip
+ * @constant {number}
+ */
-const MAX_TAG_SHOW_COUNT = 2;
+const MAX_TAG_SHOW_COUNT = process.env.NEXT_PUBLIC_MAX_TAG_SHOW_COUNT ?? 2;

54-83: Improve mobile responsiveness for tags section.

The current implementation hides tags on mobile (display={{ base: 'none', md: 'flex' }}). Consider a more mobile-friendly approach.

Instead of hiding tags on mobile, consider:

  1. Showing them in a scrollable horizontal container
  2. Stacking them vertically below the main content
  3. Or showing them in an expandable section
-<HStack spacing={3} display={{ base: 'none', md: 'flex' }}>
+<HStack
+  spacing={3}
+  overflowX={{ base: 'auto', md: 'visible' }}
+  width="100%"
+  sx={{
+    '::-webkit-scrollbar': {
+      display: 'none'
+    }
+  }}>
src/modules/room/RoomSearchContainer.tsx (2)

64-64: Memoize the debounced onChange handler to improve performance.

Currently, the debounced function is recreated on every render, which may lead to unnecessary re-renders. Memoize the debounced handler using useMemo.

Here's how you can implement it:

+  const debouncedSetQuery = useMemo(() => debounce((value) => setQuery(value), 300), []);
+
   // ...

-              onChange={debounce((e) => setQuery(e.target.value), 300)}
+              onChange={(e) => debouncedSetQuery(e.target.value)}

Don't forget to import useMemo from react:

+ import { useState, useMemo } from 'react';

82-85: Address the TODO comment regarding pagination.

The TODO indicates the need to update the room count using pagination data after implementing infinite scroll. This will enhance accuracy in displaying the number of rooms matching the filters.

Would you like assistance in implementing the pagination functionality or creating a GitHub issue to track this task?

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 9e6d1d8 and 0bfdfba.

📒 Files selected for processing (13)
  • next.config.js (1 hunks)
  • public/locales/en/common.json (1 hunks)
  • public/locales/id/common.json (1 hunks)
  • src/modules/landingPage/LandingPageContainer.tsx (2 hunks)
  • src/modules/room/RoomCardItem.tsx (1 hunks)
  • src/modules/room/RoomSearchContainer.tsx (1 hunks)
  • src/modules/room/roomEntity.ts (2 hunks)
  • src/modules/room/roomService.ts (3 hunks)
  • src/theme/global.css (1 hunks)
  • src/theme/index.ts (1 hunks)
  • src/uikit/Container.tsx (1 hunks)
  • src/uikit/Header.tsx (2 hunks)
  • src/uikit/Layout.tsx (1 hunks)
🔇 Additional comments (18)
src/uikit/Container.tsx (2)

1-2: LGTM! Clean and specific imports.

The imports are well-organized, separating types from components.


6-8: Verify prop spreading order for proper override behavior.

The current implementation spreads props after defining default styles. This is correct as it allows consumers to override default styles when needed. However, ensure this behavior is documented and tested.

✅ Verification successful

Based on the search results, I can now generate a final response as we have sufficient information about the Container component's usage across the codebase.

Props spreading order in Container component is correctly implemented

The Container component's implementation with props spreading after default styles is correct and consistent with best practices. The search results show that:

  • The component is used across multiple pages and modules with different prop combinations
  • No instances of style override issues were found in the usage patterns
  • The implementation allows proper customization while maintaining default styles as fallback

The current implementation in src/uikit/Container.tsx follows the correct pattern:

<Flex px={{ base: 5, lg: 10 }} w='100%' flexDir='column' {...props}>

where default styles are defined first and props are spread afterward, allowing proper override behavior.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for any instances where Container's default styles might be causing issues
ast-grep --pattern 'Container $props'

Length of output: 39


Script:

#!/bin/bash
# Search for Container component usage patterns
rg "Container" -A 2 -B 2

# Also check for any test files related to Container
fd "Container.test" -t f

# Look for Container component with spread operator pattern
ast-grep --pattern '<Container {...$_}>'

Length of output: 7161

src/modules/landingPage/LandingPageContainer.tsx (2)

1-1: LGTM! Clean import statement.

The import of the Container component follows React best practices.


13-19: LGTM! Good structural improvement.

The addition of the Container wrapper improves the component hierarchy by:

  • Centralizing layout control
  • Providing consistent padding and responsive behavior
  • Following component composition best practices
src/modules/room/roomEntity.ts (1)

11-13: Verify search implementation handles new properties

Since these new properties are part of the room search feature, let's verify their implementation in the search functionality.

Also applies to: 25-27

✅ Verification successful

Search implementation properly handles new room properties

The search implementation correctly handles the new properties (tags, total_channel, rate):

  • The properties are properly mapped in roomService.ts when transforming API response
  • The search functionality passes these properties through to the room card components
  • The search query implementation in roomHook.ts and RoomSearchContainer.tsx maintains a clean separation of concerns
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check how these new properties are used in search-related components

# Check for search-related files that might use these properties
echo "Searching for files handling room search..."
rg -l "searchRoom|SearchRoom" --type ts --type tsx

# Check how the new properties are used in components
echo "\nChecking usage of new properties in components..."
rg -A 3 "tags|totalChannel|rate" --type tsx

Length of output: 364


Script:

#!/bin/bash
# Let's try a different approach without file type restrictions

# Search for room search related files
echo "Searching for files handling room search..."
rg -l "searchRoom|SearchRoom"

# Check usage of the new properties
echo -e "\nChecking usage of new properties..."
rg -A 3 "(tags|total_channel|rate).*room"

# Look for any search-related components or functions
echo -e "\nChecking for search implementations..."
ast-grep --pattern 'function $FUNC($$$) {
  $$$
  search$$$Room
  $$$
}'

Length of output: 868


Script:

#!/bin/bash
# Let's examine the search implementation details

# Check RoomSearchContainer implementation
echo "Checking RoomSearchContainer implementation..."
cat src/modules/room/RoomSearchContainer.tsx

# Check room service search implementation
echo -e "\nChecking room service search implementation..."
cat src/modules/room/roomService.ts

# Check room hook search implementation
echo -e "\nChecking room hook implementation..."
cat src/modules/room/roomHook.ts

Length of output: 5402

src/uikit/Layout.tsx (1)

19-21: Verify image configuration setup.

The AI summary mentions new image handling configuration in next.config.js for placehold.co. Let's verify this setup is properly configured for the background images used here.

✅ Verification successful

Background image configuration is properly set up

The verification shows that:

  • The next.config.js has proper image configuration for placehold.co
  • The Layout component correctly handles background images via the bgImage prop
  • Background images are properly used in landing page and room search with local SVG files from /assets/images/
  • The TODO comment about changing position to 'right' is a separate styling concern and doesn't affect the image configuration

The current setup is working as expected for both remote images (via next.config.js) and local assets.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify next.config.js image configuration setup

# Check if next.config.js exists and contains image configuration
echo "Checking next.config.js for image configuration..."
rg -A 5 "images.*:" next.config.js

# Look for background image usage patterns
echo "Checking for background image usage patterns..."
rg "backgroundImage.*placehold\.co" src/

Length of output: 416


Script:

#!/bin/bash
# Let's check the Layout.tsx file to understand the background image setup
echo "Checking Layout.tsx for background image configuration..."
cat src/uikit/Layout.tsx

# Let's also check for any other background image usages in the codebase
echo -e "\nChecking for background image related styles..."
rg "background.*:" -A 2 src/

# Check for image-related imports and configurations
echo -e "\nChecking for image-related imports..."
rg "import.*[iI]mage" src/

Length of output: 3083


Script:

#!/bin/bash
# Let's check how the Layout component is being used with bgImage prop
echo "Checking usage of Layout component with bgImage..."
rg -A 3 "Layout.*bgImage" src/

# Let's also check the pages directory to see how images are configured
echo -e "\nChecking pages directory for image configurations..."
rg "background.*image" src/pages/

Length of output: 1165

src/theme/index.ts (1)

38-38: LGTM with a minor suggestion.

The semi-transparent dark background color is appropriate for overlay effects. Consider using rgba(0, 0, 0, 0.4) instead of rgba(1, 1, 1, 0.4) for pure black, though the visual difference would be minimal.

Let's verify how this new theme color is being used:

✅ Verification successful

The dark background color is appropriately used and implemented

The color is being used in RoomCardItem component as a background color for a card layout, which is a suitable use case for a semi-transparent dark overlay. The theme also has a consistent structure with other background colors (like background.coffee), showing this is a well-organized addition.

While using rgba(0, 0, 0, 0.4) would be technically more accurate for pure black, the current implementation with rgba(1, 1, 1, 0.4) will have negligible visual difference and works well for its intended purpose.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check usage of the new dark background color in the codebase
# Expected: Find components using this theme color for overlays or dim effects

# Search for background references in tsx/jsx files
rg -t tsx -t jsx "background.*dark" 

# Search for specific theme path usage
rg "background\.dark"

Length of output: 156


Script:

#!/bin/bash
# Let's check the actual usage context in RoomCardItem.tsx
rg -B 5 -A 5 "background\.dark" src/modules/room/RoomCardItem.tsx

# Also check if there are any other background-related theme colors
cat src/theme/index.ts

Length of output: 1300

src/modules/room/roomService.ts (3)

5-5: LGTM: Clean type import for pagination.

The import is properly scoped using the 'type' keyword, following TypeScript best practices.


17-20: LGTM: Well-structured response type.

The type definition cleanly separates room data from pagination metadata, with proper use of optional properties.


26-26: Verify the impact of the return type change.

The function's return type has changed from Promise<Room[]> to Promise<SearchRoomResponse>, which could affect existing consumers.

✅ Verification successful

Return type change is safe to proceed

The change from Promise<Room[]> to Promise<SearchRoomResponse> is safe because:

  1. The only consumer (roomHook.ts) uses the result through useQuery without any direct array operations
  2. The new SearchRoomResponse type provides additional metadata while keeping the rooms array accessible via .rooms property
  3. No other direct usages or array operations were found in the codebase
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for direct usage of searchRoom function to identify affected code
ast-grep --pattern 'searchRoom($$$)' 

# Search for array operations on searchRoom results that might break
rg -l 'await searchRoom.*\.(map|filter|reduce|forEach|length)'

Length of output: 175


Script:

#!/bin/bash
# Let's check the implementation of roomHook.ts to understand how the result is used
cat src/modules/room/roomHook.ts

# Also check for any type definitions related to SearchRoomResponse
fd SearchRoomResponse --exec cat {}

Length of output: 543


Script:

#!/bin/bash
# Let's check the roomService.ts file to understand the SearchRoomResponse type
cat src/modules/room/roomService.ts

# Also search for any Room[] type usage in the codebase that might be affected
rg "Promise<Room\[\]>" -A 2 -B 2

Length of output: 1306

next.config.js (1)

26-35: Review the image configuration strategy

A few considerations about the current implementation:

  1. Using placehold.co suggests this might be temporary. Consider:

    • Moving to a proper CDN/image hosting service for production
    • Using environment-specific configurations
    • Implementing proper image optimization and caching strategies
  2. The pathname pattern '/**' is very permissive. Consider restricting it to specific paths or sizes that your application actually needs.

Let's verify the actual image usage patterns:

public/locales/en/common.json (2)

22-29: LGTM! Well-structured localization entries.

The new search section is well-organized with clear, user-friendly messages that maintain consistency across desktop and mobile views.


25-25: Verify HTML tag handling in translations.

The translation string contains HTML tags (<b></b>). Please ensure your i18n library properly handles HTML tags in translations to prevent potential XSS vulnerabilities or rendering issues.

✅ Verification successful

Let me gather more information about how HTML tags are specifically handled in the codebase.


HTML tags in translations are safely handled using the Trans component

The codebase correctly handles HTML tags in translations using the Trans component from next-i18next, which safely interpolates HTML elements. Specifically for the found_rooms translation:

  • The <b> tag in the translation string is properly mapped to a <strong> element via the components prop
  • No dangerous HTML rendering methods (dangerouslySetInnerHTML) are used
  • The implementation follows i18next's recommended practices for handling HTML in translations
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check i18n library configuration and usage for HTML tag handling

# Look for i18n configuration files
fd -e js -e ts -e json "i18n.config|next-i18next.config"

# Check how HTML tags are handled in components
rg -A 3 "useTranslation|Trans component" 

Length of output: 2463


Script:

#!/bin/bash
# Check for Trans component usage with HTML tags
rg -A 5 "<Trans" 

# Check the i18next configuration
cat next-i18next.config.js

# Look for dangerouslySetInnerHTML usage which might be related to translation rendering
rg "dangerouslySetInnerHTML"

# Check for specific usage of the found_rooms translation key
rg "found_rooms"

Length of output: 1044

public/locales/id/common.json (1)

22-29: LGTM! Well-structured localization for search feature.

The translations are natural, complete, and properly formatted. The section includes all necessary UI elements with appropriate mobile/desktop variants.

src/modules/room/RoomCardItem.tsx (1)

1-16: LGTM! Well-organized imports with proper component selection.

The imports are logically grouped and all components are utilized effectively. Good choice using Next.js Image component for optimized image loading.

src/uikit/Header.tsx (2)

22-22: Verify custom Container component compatibility

The switch from Chakra UI's Container to a custom implementation might affect the header's layout behavior.

#!/bin/bash
# Check the custom Container implementation
ast-grep --pattern 'export const Container = ({ children }) => {
  $$$
}'

# Check for any Container usages that might be affected
rg -l "from '@chakra-ui/react'" | xargs rg "Container"

147-148: Review layout changes impact

The Container component's simplified props and removal of maxW constraints might affect the header's responsive behavior and maximum width limits. Additionally, the removal of horizontal padding (px) from the Flex component could impact content spacing.

Consider:

  1. Documenting the intended layout behavior
  2. Adding responsive width constraints if needed
  3. Ensuring consistent padding patterns across components
src/modules/room/RoomSearchContainer.tsx (1)

3-13: Imports are well-organized and necessary dependencies are included.

The imported modules are appropriate and improve the component's functionality.

Comment on lines +6 to +8
/* TODO: remove this hardcoded style if we want to activate dark mode */
background-color: black !important;
color: white !important;
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

Avoid hardcoded colors and !important declarations for theme implementation

The current implementation has several concerns:

  1. Hardcoded colors prevent proper theme switching
  2. Using !important makes styles difficult to override and maintain
  3. TODO comment indicates this is a temporary solution

Consider implementing a proper theme system using CSS variables:

body {
-  /* TODO: remove this hardcoded style if we want to activate dark mode */
-  background-color: black !important;
-  color: white !important;
+  background-color: var(--background-color);
+  color: var(--text-color);
}

+:root {
+  /* Light theme (default) */
+  --background-color: #ffffff;
+  --text-color: #000000;
+}
+
+[data-theme='dark'] {
+  --background-color: #000000;
+  --text-color: #ffffff;
+}

This approach:

  • Enables easy theme switching
  • Maintains maintainable code
  • Follows CSS best practices
  • Removes the need for !important declarations

Consider using a CSS-in-JS solution or a dedicated theme management library like @emotion/styled or styled-components for better theme management across your React components.

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

Comment on lines +41 to +43
<Text fontWeight={600} fontSize='20px'>
{room.name}
</Text>
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

Implement localization for text content.

Text content should be localized using your translation system for better internationalization support.

 <Text fontWeight={600} fontSize='20px'>
-  {room.name}
+  {t('room.name', { name: room.name })}
 </Text>
 // ...
-<Text fontWeight={400}>{room.totalChannel} Server Joined</Text>
+<Text fontWeight={400}>{t('room.serversJoined', { count: room.totalChannel })}</Text>
 // ...
-<Text noOfLines={2}>{room.description}</Text>
+<Text noOfLines={2}>{t('room.description', { description: room.description })}</Text>

Also applies to: 51-51, 87-87

Comment on lines +26 to +89
<Flex
flexDir='column'
borderRadius='16px'
p={4}
gap={4}
bgColor='background.dark'>
<Flex flexDir='row' gap={3}>
<Image
src='https://placehold.co/60x60.png'
width={60}
height={60}
alt='server'
style={{ borderRadius: '12px' }}
/>
<Flex flexDir='column' gap={1}>
<Text fontWeight={600} fontSize='20px'>
{room.name}
</Text>
<HStack spacing={3}>
<HStack spacing={1}>
<Icon as={StarIcon} fontSize='16px' />
<Text fontWeight={400}>{room.rate}</Text>
</HStack>
<HStack spacing={1}>
<Icon as={ServerIcon} fontSize='16px' />
<Text fontWeight={400}>{room.totalChannel} Server Joined</Text>
</HStack>
{room.tags.length > 0 && (
<HStack spacing={3} display={{ base: 'none', md: 'flex' }}>
<Divider orientation='vertical' bgColor='white' />
<HStack spacing={2}>
{room.tags.slice(0, MAX_TAG_SHOW_COUNT).map((tag) => (
<Tag
key={tag}
fontSize='14px'
bgColor='rgba(255, 255, 255, 0.25)'
color='white'>
<TagLeftIcon as={HashtagIcon} mr={1} />
<TagLabel>{tag}</TagLabel>
</Tag>
))}
{room.tags.length > MAX_TAG_SHOW_COUNT && (
<Tooltip
label={room.tags.slice(MAX_TAG_SHOW_COUNT).join(', ')}>
<Tag
fontSize='14px'
bgColor='rgba(255, 255, 255, 0.25)'
color='white'
cursor='pointer'>
<TagLabel>
+{room.tags.length - MAX_TAG_SHOW_COUNT}
</TagLabel>
</Tag>
</Tooltip>
)}
</HStack>
</HStack>
)}
</HStack>
</Flex>
</Flex>
<Text noOfLines={2}>{room.description}</Text>
</Flex>
);
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 error boundary and loading states.

The component should handle error cases and loading states gracefully.

Consider wrapping the component with an error boundary and adding loading states:

function RoomCardItemErrorFallback({ error, resetErrorBoundary }) {
  return (
    <Flex
      flexDir='column'
      borderRadius='16px'
      p={4}
      gap={4}
      bgColor='background.dark'>
      <Text>Error loading room: {error.message}</Text>
      <Button onClick={resetErrorBoundary}>Retry</Button>
    </Flex>
  );
}

export function RoomCardItem({ room, isLoading }: Props & { isLoading?: boolean }) {
  if (isLoading) {
    return <RoomCardItemSkeleton />;
  }

  return (
    <ErrorBoundary FallbackComponent={RoomCardItemErrorFallback}>
      {/* existing component content */}
    </ErrorBoundary>
  );
}

Comment on lines +33 to +39
<Image
src='https://placehold.co/60x60.png'
width={60}
height={60}
alt='server'
style={{ borderRadius: '12px' }}
/>
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

Replace hardcoded placeholder image with proper image handling.

The current implementation uses a hardcoded placeholder image URL and lacks proper error handling.

 <Image
-  src='https://placehold.co/60x60.png'
+  src={room.imageUrl ?? '/default-room-image.png'}
   width={60}
   height={60}
-  alt='server'
+  alt={`${room.name} room image`}
+  onError={(e) => {
+    e.currentTarget.src = '/default-room-image.png';
+  }}
   style={{ borderRadius: '12px' }}
 />

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

<Container pt={6} minH='100vh'>
<HStack spacing={2} color='white'>
<Icon as={BackIcon} />
<Text fontSize='14px'>Homepage</Text>
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

Localize the "Homepage" text for consistency.

The text "Homepage" should use the translation function t to support internationalization.

Apply this diff to localize the text:

-          <Text fontSize='14px'>Homepage</Text>
+          <Text fontSize='14px'>{t('common:homepage')}</Text>

Ensure the key common:homepage exists in your localization files.

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

Comment on lines +90 to +93
{searchRoomQuery.data?.rooms.map((room) => (
<RoomCardItem key={room.serial} room={room} />
))}
</Flex>
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

Safely handle potential undefined rooms to prevent runtime errors.

If searchRoomQuery.data or searchRoomQuery.data.rooms is undefined, calling .map on undefined will cause an error. Ensure that rooms is defined before mapping.

Apply this diff to safely handle undefined rooms:

-                  {searchRoomQuery.data?.rooms.map((room) => (
+                  {searchRoomQuery.data?.rooms?.map((room) => (

Alternatively, provide a default empty array:

-                  {searchRoomQuery.data?.rooms.map((room) => (
+                  {(searchRoomQuery.data?.rooms ?? []).map((room) => (
📝 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
{searchRoomQuery.data?.rooms.map((room) => (
<RoomCardItem key={room.serial} room={room} />
))}
</Flex>
{searchRoomQuery.data?.rooms?.map((room) => (
<RoomCardItem key={room.serial} room={room} />
))}
</Flex>
```
Alternative suggestion using the nullish coalescing approach:
```suggestion
{(searchRoomQuery.data?.rooms ?? []).map((room) => (
<RoomCardItem key={room.serial} room={room} />
))}
</Flex>

@Aldiwildan77
Copy link
Member

Please add the alternative text if the room searched is empty so that we might be notified by the text @Fakhri1999

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